From 43e59f29d6edbd5b968a895e1a8bef8af1479a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Wed, 27 May 2020 19:43:08 -0700 Subject: [PATCH] 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. --- .../ReactDOMFizzServerBrowser-test.js | 5 +- .../__tests__/ReactDOMFizzServerNode-test.js | 5 +- .../src/__tests__/ReactFetchBrowser-test.js | 5 +- .../src/__tests__/ReactFetchNode-test.js | 15 +++-- .../react/src/__tests__/ReactCache-test.js | 5 +- scripts/rollup/bundles.js | 15 ++++- scripts/rollup/packaging.js | 59 ++++++++++++++++++- 7 files changed, 95 insertions(+), 14 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js index 040f723192..b100f1b5a6 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js @@ -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(
hello world
, diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js index 41bbded094..ff09f64540 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js @@ -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(
hello world
, writable); diff --git a/packages/react-fetch/src/__tests__/ReactFetchBrowser-test.js b/packages/react-fetch/src/__tests__/ReactFetchBrowser-test.js index 8ae38d54d6..5410f4b470 100644 --- a/packages/react-fetch/src/__tests__/ReactFetchBrowser-test.js +++ b/packages/react-fetch/src/__tests__/ReactFetchBrowser-test.js @@ -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); }); diff --git a/packages/react-fetch/src/__tests__/ReactFetchNode-test.js b/packages/react-fetch/src/__tests__/ReactFetchNode-test.js index 4acc271dcf..1588554972 100644 --- a/packages/react-fetch/src/__tests__/ReactFetchNode-test.js +++ b/packages/react-fetch/src/__tests__/ReactFetchNode-test.js @@ -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'})); diff --git a/packages/react/src/__tests__/ReactCache-test.js b/packages/react/src/__tests__/ReactCache-test.js index 543fd7055a..3839d1a6b2 100644 --- a/packages/react/src/__tests__/ReactCache-test.js +++ b/packages/react/src/__tests__/ReactCache-test.js @@ -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); }); diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index 6eb1ef6450..f9c32cd51c 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -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', diff --git a/scripts/rollup/packaging.js b/scripts/rollup/packaging.js index b08df58aef..d62561bca2 100644 --- a/scripts/rollup/packaging.js +++ b/scripts/rollup/packaging.js @@ -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();