react
react copied to clipboard
Upgrade to modern version of Rollup and related plugins
The inspiration for this came from @jasonwilliams 's PR for attempting to add sourcemap output support to React's builds:
- https://github.com/facebook/react/issues/20186
- https://github.com/facebook/react/pull/21946
But I figured that it would be useful to minimise the scope of changes in that PR, and to modernise the build tooling along the way.
There have been quite a few version releases for Rollup and the plugins that are currently used, as well as a number of the official Rollup plugins changing package name to use the @rollup/* package prefix.
Looking at package.json we can see all of the current Rollup packages:
// ..snip..
"rollup": "^1.19.4",
"rollup-plugin-babel": "^4.0.1",
"rollup-plugin-commonjs": "^9.3.4",
"rollup-plugin-node-resolve": "^2.1.1",
"rollup-plugin-prettier": "^0.6.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-strip-banner": "^0.2.0",
// ..snip..
And using grep, we can see some additional usages under packages/:
⇒ grep -r 'rollup' package.json packages/*/package.json
package.json: "rollup": "^1.19.4",
package.json: "rollup-plugin-babel": "^4.0.1",
package.json: "rollup-plugin-commonjs": "^9.3.4",
package.json: "rollup-plugin-node-resolve": "^2.1.1",
package.json: "rollup-plugin-prettier": "^0.6.0",
package.json: "rollup-plugin-replace": "^2.2.0",
package.json: "rollup-plugin-strip-banner": "^0.2.0",
package.json: "build": "node ./scripts/rollup/build.js",
package.json: "build-combined": "node ./scripts/rollup/build-all-release-channels.js",
package.json: "lint-build": "node ./scripts/rollup/validate/index.js",
packages/react-devtools-extensions/package.json: "rollup": "^1.19.4",
packages/react-devtools-extensions/package.json: "rollup-plugin-babel": "^4.0.1",
packages/react-devtools-extensions/package.json: "rollup-plugin-commonjs": "^9.3.4",
packages/react-devtools-extensions/package.json: "rollup-plugin-node-resolve": "^2.1.1",
The following is an attempt to capture all of the relevant information about package name changes, new versions, breaking changes, etc for these packages:
- https://github.com/rollup/rollup
- https://www.npmjs.com/package/rollup
- Lockfile currently resolves to
version "1.31.1"- https://github.com/rollup/rollup/blob/master/CHANGELOG.md#1311
- The latest version is
2.76.0, but there are a number of other breaking changes leading up to that version- https://github.com/rollup/rollup/blob/master/CHANGELOG.md#200
-
Breaking Changes
-
- https://github.com/rollup/rollup/blob/master/CHANGELOG.md#200
- Lockfile currently resolves to
- https://www.npmjs.com/package/rollup
- https://github.com/rollup/plugins#plugins-found-here
- https://github.com/rollup/plugins/tree/master/packages/babel
- https://www.npmjs.com/package/@rollup/plugin-babel
- Lockfile currently resolves to
version "4.3.3" - Oldest version for
@rollup/plugin-babelpackage name is5.0.0- https://github.com/rollup/plugins/blob/master/packages/babel/CHANGELOG.md#500
-
Breaking Changes
-
Minimum compatible Rollup version is 1.2.0
-
Minimum supported Node version is 10.0.0
-
.customfactory is now available as separatecreateBabelInputPluginFactoryexport -
Removed
externalHelpers&runtimeHelpersoptions. There is now a singlebabelHelpersoption which can take one of'bundled','inline','runtime'and'external'as a value. The default is'bundled'which matches4.xbehavior, but it is recommended to configure this option explicitly.
-
-
- There don't seem to be any other breaking changes up till the latest version which is
5.3.1
- https://github.com/rollup/plugins/blob/master/packages/babel/CHANGELOG.md#500
- Lockfile currently resolves to
- https://www.npmjs.com/package/@rollup/plugin-babel
- https://github.com/rollup/plugins/tree/master/packages/commonjs
- https://www.npmjs.com/package/@rollup/plugin-commonjs
- Lockfile currently resolves to
version "9.3.4" - Oldest version for
@rollup/plugin-commonjspackage name is11.0.0- https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md#1100
-
Breaking: Minimum compatible Rollup version is 1.20.0
-
Breaking: Minimum supported Node version is 8.0.0
-
- The latest version is
22.0.1, but there are a number of other breaking changes leading up to that version
- https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md#1100
- Based on some comments in the source, I believe this dependency is only used for
react-art, so presumably if that still works properly with the newest version of this lib, we could update to that.
- https://github.com/rollup/plugins/tree/master/packages/node-resolve
- https://www.npmjs.com/package/@rollup/plugin-node-resolve
- Lockfile currently resolves to
version "2.1.1" - Oldest version for
@rollup/plugin-node-resolvepackage name is6.0.0- https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md#600
-
Breaking: Minimum compatible Rollup version is 1.20.0
-
Breaking: Minimum supported Node version is 8.0.0
-
- https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md#500-2019-05-15
-
Breaking Changes
-
Requires at least [email protected] to work (v1.12.0 for module side-effects to be respected)
-
If used with rollup-plugin-commonjs, it should be at least v10.0.0
-
-
- https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md#300
-
[BREAKING] Remove
options.skip
-
- The latest version is
13.3.0, but there are a number of other breaking changes leading up to that version
- https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md#600
- Lockfile currently resolves to
- https://www.npmjs.com/package/@rollup/plugin-node-resolve
- https://github.com/rollup/plugins/tree/master/packages/replace
- https://www.npmjs.com/package/@rollup/plugin-replace
- Lockfile currently resolves to
version "2.2.0" - Oldest version for
@rollup/plugin-replacepackage name is2.2.0- https://github.com/rollup/plugins/blob/master/packages/replace/CHANGELOG.md#220
- The latest version is
4.0.0, but there are a number of other breaking changes leading up to that version
- Lockfile currently resolves to
- https://www.npmjs.com/package/@rollup/plugin-replace
- https://github.com/rollup/plugins/tree/master/packages/babel
- https://github.com/mjeanroy/rollup-plugin-strip-banner
- https://www.npmjs.com/package/rollup-plugin-strip-banner
- Lockfile currently resolves to
version "0.2.0"- https://github.com/mjeanroy/rollup-plugin-strip-banner/blob/master/CHANGELOG.md#020-2017-05-10
- The latest version is
2.0.0. The changelog doesn't explicitly mention any breaking changes, but I didn't look into it too deeply - Edit: Seems there is a secondary changelog in the README, though it still doesn't mention any breaking changes: https://github.com/mjeanroy/rollup-plugin-strip-banner#changelogs
- Lockfile currently resolves to
- https://www.npmjs.com/package/rollup-plugin-strip-banner
- https://github.com/mjeanroy/rollup-plugin-prettier
- https://www.npmjs.com/package/rollup-plugin-prettier
- Lockfile currently resolves to
version "0.6.0"- https://github.com/mjeanroy/rollup-plugin-prettier/blob/master/CHANGELOG.md#060-2019-01-16
- The latest version is
2.2.2. The changelog doesn't explicitly mention any breaking changes, but I didn't look into it too deeply - Edit: Seems there is a secondary changelog in the README that mentions a breaking change: https://github.com/mjeanroy/rollup-plugin-prettier#changelogs
-
Breaking Change: prettier dependency is now a peer dependency instead of a "direct" dependency: user of the plugin can choose to use prettier 1.x.x or prettier 2.x.x (note that this plugin should be compatible with all versions of prettier).
-
If any of these updates rely on a node version later than 10.x, then the following PR may have to land first, otherwise things might break on AppVeyor:
- https://github.com/facebook/react/issues/24891
- https://github.com/facebook/react/pull/24892
My plan/intent is to work through all of this and create a PR updating Rollup and the related plugins; but I wanted to create this issue in the meantime to capture what I have done so far, and also check whether there would be any issues/concerns with a PR like this being made.
Edit: PR opened in:
- https://github.com/facebook/react/pull/24916
It seems yarn 1.x's remove doesn't update the yarn.lock file particularly well.. is there a best practice way for doing this, or is it just a manual sort of thing to clean up?
- https://github.com/yarnpkg/yarn/issues/2581
eg. yarn remove --force --ignore-workspace-root-check rollup-plugin-babel only updated package.json, not yarn.lock
Edit: I wonder if this is because it's used in other packages as well?
⇒ grep -r 'rollup-plugin-babel' packages
packages/react-devtools-timeline/node_modules/json5/package.json: "rollup-plugin-babel": "^3.0.3",
packages/react-devtools-extensions/package.json: "rollup-plugin-babel": "^4.0.1",
packages/react-devtools-shared/src/node_modules/react-window/package.json: "rollup-plugin-babel": "^4.3.2",
packages/react-devtools-shared/src/hooks/__tests__/updateMockSourceMaps.js:const babel = require('rollup-plugin-babel');
⇒ yarn add --force --dev --ignore-workspace-root-check @rollup/plugin-babel
yarn add v1.22.19
[1/4] 🔍 Resolving packages...
warning workspace-aggregator-06b1766b-e8f5-406b-87e7-0089d7a59d18 > react-devtools-extensions > [email protected]: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-babel.
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
...snip: a whole bunch of peer dependency warnings...
[4/4] 🔨 Rebuilding all packages...
success Saved lockfile.
success Saved 3 new dependencies.
info Direct dependencies
├─ @rollup/[email protected]
└─ [email protected]
info All dependencies
├─ @rollup/[email protected]
├─ [email protected]
└─ [email protected]
Edit 2: I tried using yarn's workspace command to manipulate the other packages:
- https://classic.yarnpkg.com/en/docs/cli/workspace
- https://classic.yarnpkg.com/lang/en/docs/cli/add/
But then I ran into an error about "Failed to install dependencies in workspace: expected workspace package to exist". After some googling, that lead me to the following issues, and the various proposed solutions within:
- https://github.com/yarnpkg/yarn/issues/7807
-
Failed to install dependencies in workspace: expected workspace package to exist
- https://github.com/yarnpkg/yarn/issues/7807#issuecomment-588632848
-
yarn policies set-version 1.18.0
-
- https://github.com/yarnpkg/yarn/issues/7807#issuecomment-1097198463
-
npx yarn-deduplicate && yarn install
-
- https://github.com/yarnpkg/yarn/issues/7807#issuecomment-1104082997
-
Re: deduping, this package actually dedupes: https://medium.com/@bnaya/yarn-deduplicate-the-hero-we-need-f4497a362128
-
-
- https://github.com/yarnpkg/yarn/issues/7734
- https://github.com/yarnpkg/yarn/issues/7734#issuecomment-578534560
-
For those looking for a solution that doesn't involve changing the version of
yarnyou're using, editingpackage.jsonto include the version of the package you want and then running theyarncommand again works just fine.
-
- https://github.com/yarnpkg/yarn/issues/7734#issuecomment-588282680
-
For me, the problem is a regression
1.19.1->1.19.2(as reported here). Downgrading to1.19.1helped.
-
- https://github.com/yarnpkg/yarn/issues/7734#issuecomment-671729912
-
An alternative is to issue the command
yarn policies set-version 1.19.1from inside your project.
-
- https://github.com/yarnpkg/yarn/issues/7734#issuecomment-671866619
-
You could also use lerna to add a package without downgrading the yarn version
-
npx lerna add <package>[@version] --scope=<workspace> -
The command above will add the package to the specified workspace
package.jsonand updateyarn.lock
-
- https://github.com/yarnpkg/yarn/issues/7734#issuecomment-578534560
Playing around with things, this seems to be a working set of upgraded rollup version/plugins that still seems to produce the same build output for build/node_modules/react/umd/react.development.js.
Note that:
- It is using the last
1.xversion of Rollup before Rollup2.x - It is using a version of
@rollup/plugin-node-resolvebelow v13.0.0 as that requires Rollup2.x- https://github.com/rollup/plugins/issues/1222#issuecomment-1182795892
- The version of
@rollup/plugin-node-resolvebeing used was determined by manually testing each version below13.0.0and trying to buildyarn build react/index,react-dom/index --type=UMD. For versions11.0.0through to11.2.1, the following error (presumably a bug in the resolver) was produced:-
Error: Could not load /Users/devalias/dev/facebook/react/node_modules/react-dom/src/client/ReactDOMHostConfig (imported by /Users/devalias/dev/facebook/react/packages/react-reconciler/src/forks/ReactFiberHostConfig.dom.js): ENOENT: no such file or directory, open '/Users/devalias/dev/facebook/react/node_modules/react-dom/src/client/ReactDOMHostConfig'
-
diff --git a/package.json b/package.json
index 2e8445521..51e284ff6 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,10 @@
"@babel/preset-flow": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"@babel/traverse": "^7.11.0",
+ "@rollup/plugin-babel": "^5.3.1",
+ "@rollup/plugin-commonjs": "^22.0.1",
+ "@rollup/plugin-node-resolve": "^10.0.0",
+ "@rollup/plugin-replace": "^4.0.0",
"abort-controller": "^3.0.0",
"art": "0.10.1",
"babel-eslint": "^10.0.3",
@@ -83,13 +87,9 @@
"random-seed": "^0.3.0",
"react-lifecycles-compat": "^3.0.4",
"rimraf": "^3.0.0",
- "rollup": "^1.19.4",
- "rollup-plugin-babel": "^4.0.1",
- "rollup-plugin-commonjs": "^9.3.4",
- "rollup-plugin-node-resolve": "^2.1.1",
- "rollup-plugin-prettier": "^0.6.0",
- "rollup-plugin-replace": "^2.2.0",
- "rollup-plugin-strip-banner": "^0.2.0",
+ "rollup": "^1.32.1",
+ "rollup-plugin-prettier": "^2.2.2",
+ "rollup-plugin-strip-banner": "^2.0.0",
"semver": "^7.1.1",
"targz": "^1.0.1",
"through2": "^3.0.1",
Moving to a 2.x version of Rollup seems to change the output of build/node_modules/react/umd/react.development.js. While it may be insignificant, I figured it was worth calling out the differences here for posterity (partial diff included below):
Details
diff --git a/build-currentMain/node_modules/react/umd/react.development.js b/build/node_modules/react/umd/react.development.js
index 74fb8652e..50a773692 100644
--- a/build-currentMain/node_modules/react/umd/react.development.js
+++ b/build/node_modules/react/umd/react.development.js
@@ -10,8 +10,8 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (global = global || self, factory(global.React = {}));
-}(this, (function (exports) { 'use strict';
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.React = {}));
+})(this, (function (exports) { 'use strict';
// TODO: this is special because it gets imported during build.
//
@@ -40,9 +40,12 @@
var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
var REACT_MEMO_TYPE = Symbol.for('react.memo');
var REACT_LAZY_TYPE = Symbol.for('react.lazy');
+ var REACT_SCOPE_TYPE = Symbol.for('react.scope');
var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
+ var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
var REACT_CACHE_TYPE = Symbol.for('react.cache');
+ var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value');
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator';
@@ -63,13 +66,14 @@
/**
* Keeps track of the current dispatcher.
*/
- var ReactCurrentDispatcher = {
+ var ReactCurrentDispatcher$1 = {
/**
* @internal
* @type {ReactComponent}
*/
current: null
};
+ var ReactCurrentDispatcher$2 = ReactCurrentDispatcher$1;
/**
* Keeps track of the current batch's configuration such as how long an update
@@ -78,6 +82,7 @@
var ReactCurrentBatchConfig = {
transition: null
};
+ var ReactCurrentBatchConfig$1 = ReactCurrentBatchConfig;
var ReactCurrentActQueue = {
current: null,
@@ -85,6 +90,7 @@
isBatchingLegacy: false,
didScheduleLegacyUpdate: false
};
+ var ReactCurrentActQueue$1 = ReactCurrentActQueue;
/**
* Keeps track of the current owner.
@@ -99,8 +105,9 @@
*/
current: null
};
+ var ReactCurrentOwner$1 = ReactCurrentOwner;
- var ReactDebugCurrentFrame = {};
+ var ReactDebugCurrentFrame$1 = {};
var currentExtraStackFrame = null;
function setExtraStackFrame(stack) {
{
@@ -109,16 +116,16 @@
}
{
- ReactDebugCurrentFrame.setExtraStackFrame = function (stack) {
+ ReactDebugCurrentFrame$1.setExtraStackFrame = function (stack) {
{
currentExtraStackFrame = stack;
}
}; // Stack implementation injected by the current renderer.
- ReactDebugCurrentFrame.getCurrentStack = null;
+ ReactDebugCurrentFrame$1.getCurrentStack = null;
- ReactDebugCurrentFrame.getStackAddendum = function () {
+ ReactDebugCurrentFrame$1.getStackAddendum = function () {
var stack = ''; // Add an extra top frame while an element is being validated
if (currentExtraStackFrame) {
@@ -126,7 +133,7 @@
} // Delegate to the injected renderer-specific implementation
- var impl = ReactDebugCurrentFrame.getCurrentStack;
+ var impl = ReactDebugCurrentFrame$1.getCurrentStack;
if (impl) {
stack += impl() || '';
@@ -136,9 +143,12 @@
};
}
+ var ReactDebugCurrentFrame$2 = ReactDebugCurrentFrame$1;
+
// -----------------------------------------------------------------------------
var enableScopeAPI = false; // Experimental Create Event Handle API.
+ var enableCacheElement = true;
var enableTransitionTracing = false; // No known bugs, but needs performance testing
var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
@@ -146,24 +156,28 @@
// issues in DEV builds.
var enableDebugTracing = false; // Track which Fiber(s) schedule render work.
+ var enableServerContext = true; // Internal only.
- var ContextRegistry = {};
+ var ContextRegistry$1 = {};
- var ReactSharedInternals = {
- ReactCurrentDispatcher: ReactCurrentDispatcher,
- ReactCurrentBatchConfig: ReactCurrentBatchConfig,
- ReactCurrentOwner: ReactCurrentOwner
+ var ReactSharedInternals$2 = {
+ ReactCurrentDispatcher: ReactCurrentDispatcher$2,
+ ReactCurrentBatchConfig: ReactCurrentBatchConfig$1,
+ ReactCurrentOwner: ReactCurrentOwner$1
};
{
- ReactSharedInternals.ReactDebugCurrentFrame = ReactDebugCurrentFrame;
- ReactSharedInternals.ReactCurrentActQueue = ReactCurrentActQueue;
+ ReactSharedInternals$2.ReactDebugCurrentFrame = ReactDebugCurrentFrame$2;
+ ReactSharedInternals$2.ReactCurrentActQueue = ReactCurrentActQueue$1;
}
{
- ReactSharedInternals.ContextRegistry = ContextRegistry;
+ ReactSharedInternals$2.ContextRegistry = ContextRegistry$1;
}
+ var ReactSharedInternals$3 = ReactSharedInternals$2;
+
+ var suppressWarning = false;
//..snip..
I'm not currently sure if these changes are significant/change the semantics of the output, or are just a different way of the bundler working, but I did notice that it increases the output file sizes a bit (most dramatically in react.development.js):
⇒ yarn build react/index,react-dom/index --type=UMD
yarn run v1.22.19
$ node ./scripts/rollup/build.js react/index,react-dom/index --type=UMD
//..snip..
┌─────────────────────────────────────────────┬───────────┬──────────────┬───────┬───────────┬──────────────┬───────┐
│ Bundle │ Prev Size │ Current Size │ Diff │ Prev Gzip │ Current Gzip │ Diff │
├─────────────────────────────────────────────┼───────────┼──────────────┼───────┼───────────┼──────────────┼───────┤
│ react.development.js (UMD_DEV) │ 111.96 KB │ 117.59 KB │ +5.0% │ 28.82 KB │ 30.35 KB │ +5.3% │
├─────────────────────────────────────────────┼───────────┼──────────────┼───────┼───────────┼──────────────┼───────┤
│ react.production.min.js (UMD_PROD) │ 11.45 KB │ 11.51 KB │ +0.5% │ 4.42 KB │ 4.43 KB │ +0.4% │
├─────────────────────────────────────────────┼───────────┼──────────────┼───────┼───────────┼──────────────┼───────┤
│ react.profiling.min.js (UMD_PROFILING) │ 11.45 KB │ 11.51 KB │ +0.5% │ 4.42 KB │ 4.44 KB │ +0.4% │
├─────────────────────────────────────────────┼───────────┼──────────────┼───────┼───────────┼──────────────┼───────┤
│ react-dom.development.js (UMD_DEV) │ 1.07 MB │ 1.07 MB │ +0.1% │ 236.54 KB │ 236.89 KB │ +0.1% │
├─────────────────────────────────────────────┼───────────┼──────────────┼───────┼───────────┼──────────────┼───────┤
│ react-dom.production.min.js (UMD_PROD) │ 135.13 KB │ 135.91 KB │ +0.6% │ 43.93 KB │ 44.21 KB │ +0.6% │
├─────────────────────────────────────────────┼───────────┼──────────────┼───────┼───────────┼──────────────┼───────┤
│ react-dom.profiling.min.js (UMD_PROFILING) │ 143.66 KB │ 144.44 KB │ +0.5% │ 46.14 KB │ 46.41 KB │ +0.6% │
└─────────────────────────────────────────────┴───────────┴──────────────┴───────┴───────────┴──────────────┴───────┘
✨ Done in 36.89s.
This was using the following versions for Rollup and related plugins, which I believe are the latest versions of all of them:
diff --git a/package.json b/package.json
index 2e8445521..eb68a8d60 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,10 @@
"@babel/preset-flow": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"@babel/traverse": "^7.11.0",
+ "@rollup/plugin-babel": "^5.3.1",
+ "@rollup/plugin-commonjs": "^22.0.1",
+ "@rollup/plugin-node-resolve": "^13.3.0",
+ "@rollup/plugin-replace": "^4.0.0",
"abort-controller": "^3.0.0",
"art": "0.10.1",
"babel-eslint": "^10.0.3",
@@ -83,13 +87,9 @@
"random-seed": "^0.3.0",
"react-lifecycles-compat": "^3.0.4",
"rimraf": "^3.0.0",
- "rollup": "^1.19.4",
- "rollup-plugin-babel": "^4.0.1",
- "rollup-plugin-commonjs": "^9.3.4",
- "rollup-plugin-node-resolve": "^2.1.1",
- "rollup-plugin-prettier": "^0.6.0",
- "rollup-plugin-replace": "^2.2.0",
- "rollup-plugin-strip-banner": "^0.2.0",
+ "rollup": "^2.76.0",
+ "rollup-plugin-prettier": "^2.2.2",
+ "rollup-plugin-strip-banner": "^2.0.0",
"semver": "^7.1.1",
"targz": "^1.0.1",
"through2": "^3.0.1",