Delete Entries without Build Output from package.json and the build directory (#19029)

* Gate test

* Delete entrypoints without Build Outputs from package.json and build output

If an entry point exists in bundles.js but doesn't have any bundleTypes,
I delete that entry point file from the build directory. I also remove it
from the files field in package.json if it exists.

This allows us to remove bundles from being built in the stable release
channel.
This commit is contained in:
Sebastian Markbåge
2020-05-27 19:43:08 -07:00
committed by GitHub
parent e668f1b54f
commit 43e59f29d6
7 changed files with 95 additions and 14 deletions

View File

@@ -20,7 +20,9 @@ describe('ReactDOMFizzServer', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactDOMFizzServer = require('react-dom/unstable-fizz.browser');
if (__EXPERIMENTAL__) {
ReactDOMFizzServer = require('react-dom/unstable-fizz.browser');
}
});
async function readResult(stream) {
@@ -35,6 +37,7 @@ describe('ReactDOMFizzServer', () => {
}
}
// @gate experimental
it('should call renderToReadableStream', async () => {
const stream = ReactDOMFizzServer.renderToReadableStream(
<div>hello world</div>,

View File

@@ -18,7 +18,9 @@ describe('ReactDOMFizzServer', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
ReactDOMFizzServer = require('react-dom/unstable-fizz');
if (__EXPERIMENTAL__) {
ReactDOMFizzServer = require('react-dom/unstable-fizz');
}
Stream = require('stream');
});
@@ -30,6 +32,7 @@ describe('ReactDOMFizzServer', () => {
return writable;
}
// @gate experimental
it('should call pipeToNodeWritable', () => {
const writable = getTestWritable();
ReactDOMFizzServer.pipeToNodeWritable(<div>hello world</div>, writable);

View File

@@ -13,10 +13,13 @@ describe('ReactFetchBrowser', () => {
let ReactFetchBrowser;
beforeEach(() => {
ReactFetchBrowser = require('react-fetch');
if (__EXPERIMENTAL__) {
ReactFetchBrowser = require('react-fetch');
}
});
// TODO: test something useful.
// @gate experimental
it('exports something', () => {
expect(ReactFetchBrowser.fetch).not.toBe(undefined);
});

View File

@@ -20,19 +20,20 @@ describe('ReactFetchNode', () => {
beforeEach(done => {
jest.resetModules();
ReactCache = require('react/unstable-cache');
ReactFetchNode = require('react-fetch');
if (__EXPERIMENTAL__) {
ReactCache = require('react/unstable-cache');
// TODO: A way to pass load context.
ReactCache.CacheProvider._context._currentValue = ReactCache.createCache();
ReactFetchNode = require('react-fetch');
fetch = ReactFetchNode.fetch;
}
http = require('http');
fetch = ReactFetchNode.fetch;
server = http.createServer((req, res) => {
serverImpl(req, res);
});
server.listen(done);
serverEndpoint = `http://localhost:${server.address().port}/`;
// TODO: A way to pass load context.
ReactCache.CacheProvider._context._currentValue = ReactCache.createCache();
});
afterEach(done => {
@@ -54,6 +55,7 @@ describe('ReactFetchNode', () => {
}
}
// @gate experimental
it('can read text', async () => {
serverImpl = (req, res) => {
res.write('ok');
@@ -70,6 +72,7 @@ describe('ReactFetchNode', () => {
});
});
// @gate experimental
it('can read json', async () => {
serverImpl = (req, res) => {
res.write(JSON.stringify({name: 'Sema'}));

View File

@@ -13,10 +13,13 @@ describe('ReactCache', () => {
let ReactCache;
beforeEach(() => {
ReactCache = require('react/unstable-cache');
if (__EXPERIMENTAL__) {
ReactCache = require('react/unstable-cache');
}
});
// TODO: test something useful.
// @gate experimental
it('exports something', () => {
expect(ReactCache.readCache).not.toBe(undefined);
});

View File

@@ -1,5 +1,12 @@
'use strict';
const RELEASE_CHANNEL = process.env.RELEASE_CHANNEL;
const __EXPERIMENTAL__ =
typeof RELEASE_CHANNEL === 'string'
? RELEASE_CHANNEL === 'experimental'
: true;
const bundleTypes = {
UMD_DEV: 'UMD_DEV',
UMD_PROD: 'UMD_PROD',
@@ -108,7 +115,7 @@ const bundles = [
/******* React Cache (experimental, new) *******/
{
bundleTypes: [NODE_DEV, NODE_PROD, NODE_PROFILING],
bundleTypes: __EXPERIMENTAL__ ? [NODE_DEV, NODE_PROD, NODE_PROFILING] : [],
moduleType: ISOMORPHIC,
entry: 'react/unstable-cache',
global: 'ReactCache',
@@ -223,14 +230,16 @@ const bundles = [
/******* React DOM Fizz Server *******/
{
bundleTypes: [NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD],
bundleTypes: __EXPERIMENTAL__
? [NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD]
: [],
moduleType: RENDERER,
entry: 'react-dom/unstable-fizz.browser',
global: 'ReactDOMFizzServer',
externals: ['react', 'react-dom/server'],
},
{
bundleTypes: [NODE_DEV, NODE_PROD],
bundleTypes: __EXPERIMENTAL__ ? [NODE_DEV, NODE_PROD] : [],
moduleType: RENDERER,
entry: 'react-dom/unstable-fizz.node',
global: 'ReactDOMFizzServer',

View File

@@ -1,6 +1,12 @@
'use strict';
const {existsSync, readdirSync, unlinkSync} = require('fs');
const {
existsSync,
readdirSync,
unlinkSync,
readFileSync,
writeFileSync,
} = require('fs');
const Bundles = require('./bundles');
const {
asyncCopyTo,
@@ -115,6 +121,56 @@ function getTarOptions(tgzName, packageName) {
};
}
let entryPointsToHasBundle = new Map();
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const bundle of Bundles.bundles) {
let hasBundle = entryPointsToHasBundle.get(bundle.entry);
if (!hasBundle) {
entryPointsToHasBundle.set(bundle.entry, bundle.bundleTypes.length > 0);
}
}
function filterOutEntrypoints(name) {
// Remove entry point files that are not built in this configuration.
let jsonPath = `build/node_modules/${name}/package.json`;
let packageJSON = JSON.parse(readFileSync(jsonPath));
let files = packageJSON.files;
if (!Array.isArray(files)) {
throw new Error('expected all package.json files to contain a files field');
}
let changed = false;
for (let i = 0; i < files.length; i++) {
let filename = files[i];
let entry =
filename === 'index.js'
? name
: name + '/' + filename.replace(/\.js$/, '');
let hasBundle = entryPointsToHasBundle.get(entry);
if (hasBundle === undefined) {
// This entry doesn't exist in the bundles. Check if something similar exists.
hasBundle =
entryPointsToHasBundle.get(entry + '.node') ||
entryPointsToHasBundle.get(entry + '.browser');
}
if (hasBundle === undefined) {
// This doesn't exist in the bundles. It's an extra file.
} else if (hasBundle === true) {
// This is built in this release channel.
} else {
// This doesn't have any bundleTypes in this release channel.
// Let's remove it.
files.splice(i, 1);
i--;
unlinkSync(`build/node_modules/${name}/${filename}`);
changed = true;
}
}
if (changed) {
let newJSON = JSON.stringify(packageJSON, null, ' ');
writeFileSync(jsonPath, newJSON);
}
}
async function prepareNpmPackage(name) {
await Promise.all([
asyncCopyTo('LICENSE', `build/node_modules/${name}/LICENSE`),
@@ -128,6 +184,7 @@ async function prepareNpmPackage(name) {
),
asyncCopyTo(`packages/${name}/npm`, `build/node_modules/${name}`),
]);
filterOutEntrypoints(name);
const tgzName = (
await asyncExecuteCommand(`npm pack build/node_modules/${name}`)
).trim();