react/scripts/rollup/wrappers.js
Mark Erikson 909c6dacfd
Update Rollup to 3.x (#26442)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

This PR:

- Updates Rollup from 2.x to latest 3.x, and updates associated plugins
- Updates deprecated / altered config settings in the Rollup plugin
pipeline
- Fixes some file extension and import issues related to use of ESM in
`react-dom-webpack-server`
- Removes a now-obsolete `strip-unused-imports` Rollup plugin
- <s>Fixes an _existing_ bug with the Rollup 2.x plugin pipeline on
`main` that was causing parts of `DOMProperty.js` to get left out of the
`react-dom-webpack-server` JS bundles, by adding a new plugin to tell
Rollup to treat that file as if it as side effects</s>

This PR should be functionally identical to the other existing "Rollup 3
upgrade" PR at #26078 . I'm filing this as a near-duplicate because I'm
ready to push this change through ASAP so that I can follow it up with a
PR that adds sourcemap support, that PR's artifact diffing seems like
it's possibly stuck and I want to compare the build results, and I've
got this set up against latest `main`.

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

This gets React's build setup updated to the latest Rollup version,
which is generally a good practice, but also ensures that any further
Rollup config tweaks can be done using the current Rollup docs as a
reference.

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->

- Made builds from the latest `main`
- Updated Rollup package versions and cross-compared the changes I
needed to make locally to get successful builds vs #26078
- Diffed the output folders between `main` and this PR, and confirmed
that the bundle contents are identical (with the exception of version
strings and the `react-dom-webpack-server` bundle fix re-adding missing
`DOMProperty.js` content)
2023-03-24 18:08:41 +00:00

464 lines
9.1 KiB
JavaScript

'use strict';
const {resolve} = require('path');
const {readFileSync} = require('fs');
const {bundleTypes, moduleTypes} = require('./bundles');
const {
NODE_ES2015,
ESM_DEV,
ESM_PROD,
UMD_DEV,
UMD_PROD,
UMD_PROFILING,
NODE_DEV,
NODE_PROD,
NODE_PROFILING,
BUN_DEV,
BUN_PROD,
FB_WWW_DEV,
FB_WWW_PROD,
FB_WWW_PROFILING,
RN_OSS_DEV,
RN_OSS_PROD,
RN_OSS_PROFILING,
RN_FB_DEV,
RN_FB_PROD,
RN_FB_PROFILING,
BROWSER_SCRIPT,
} = bundleTypes;
const {RECONCILER} = moduleTypes;
const USE_STRICT_HEADER_REGEX = /'use strict';\n+/;
function registerInternalModuleStart(globalName) {
const path = resolve(__dirname, 'wrappers', 'registerInternalModuleBegin.js');
const file = readFileSync(path);
return String(file).trim();
}
function registerInternalModuleStop(globalName) {
const path = resolve(__dirname, 'wrappers', 'registerInternalModuleEnd.js');
const file = readFileSync(path);
// Remove the 'use strict' directive from the footer.
// This directive is only meaningful when it is the first statement in a file or function.
return String(file).replace(USE_STRICT_HEADER_REGEX, '').trim();
}
const license = ` * Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.`;
const wrappers = {
/***************** NODE_ES2015 *****************/
[NODE_ES2015](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
'use strict';
${source}`;
},
/***************** ESM_DEV *****************/
[ESM_DEV](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
${source}`;
},
/***************** ESM_PROD *****************/
[ESM_PROD](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
${source}`;
},
/***************** BUN_DEV *****************/
[BUN_DEV](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
${source}`;
},
/***************** BUN_PROD *****************/
[BUN_PROD](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
${source}`;
},
/***************** UMD_DEV *****************/
[UMD_DEV](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
${source}`;
},
/***************** UMD_PROD *****************/
[UMD_PROD](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
(function(){${source}})();`;
},
/***************** UMD_PROFILING *****************/
[UMD_PROFILING](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
(function(){${source}})();`;
},
/***************** NODE_DEV *****************/
[NODE_DEV](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
'use strict';
if (process.env.NODE_ENV !== "production") {
(function() {
${source}
})();
}`;
},
/***************** NODE_PROD *****************/
[NODE_PROD](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
${source}`;
},
/***************** NODE_PROFILING *****************/
[NODE_PROFILING](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
${source}`;
},
/****************** FB_WWW_DEV ******************/
[FB_WWW_DEV](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @preventMunge
* @preserve-invariant-messages
*/
'use strict';
if (__DEV__) {
(function() {
${source}
})();
}`;
},
/****************** FB_WWW_PROD ******************/
[FB_WWW_PROD](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @preventMunge
* @preserve-invariant-messages
*/
${source}`;
},
/****************** FB_WWW_PROFILING ******************/
[FB_WWW_PROFILING](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @preventMunge
* @preserve-invariant-messages
*/
${source}`;
},
/****************** RN_OSS_DEV ******************/
[RN_OSS_DEV](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @providesModule ${globalName}-dev
* @preventMunge
* ${'@gen' + 'erated'}
*/
'use strict';
if (__DEV__) {
(function() {
${source}
})();
}`;
},
/****************** RN_OSS_PROD ******************/
[RN_OSS_PROD](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @providesModule ${globalName}-prod
* @preventMunge
* ${'@gen' + 'erated'}
*/
${source}`;
},
/****************** RN_OSS_PROFILING ******************/
[RN_OSS_PROFILING](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @providesModule ${globalName}-profiling
* @preventMunge
* ${'@gen' + 'erated'}
*/
${source}`;
},
/****************** RN_FB_DEV ******************/
[RN_FB_DEV](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @preventMunge
* ${'@gen' + 'erated'}
*/
'use strict';
if (__DEV__) {
(function() {
${source}
})();
}`;
},
/****************** RN_FB_PROD ******************/
[RN_FB_PROD](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @preventMunge
* ${'@gen' + 'erated'}
*/
${source}`;
},
/****************** RN_FB_PROFILING ******************/
[RN_FB_PROFILING](source, globalName, filename, moduleType) {
return `/**
${license}
*
* @noflow
* @nolint
* @preventMunge
* ${'@gen' + 'erated'}
*/
${source}`;
},
};
const reconcilerWrappers = {
/***************** NODE_DEV (reconciler only) *****************/
[NODE_DEV](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
'use strict';
if (process.env.NODE_ENV !== "production") {
module.exports = function $$$reconciler($$$hostConfig) {
var exports = {};
${source}
return exports;
};
module.exports.default = module.exports;
Object.defineProperty(module.exports, "__esModule", { value: true });
}
`;
},
/***************** NODE_PROD (reconciler only) *****************/
[NODE_PROD](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
module.exports = function $$$reconciler($$$hostConfig) {
var exports = {};
${source}
return exports;
};
module.exports.default = module.exports;
Object.defineProperty(module.exports, "__esModule", { value: true });
`;
},
/***************** NODE_PROFILING (reconciler only) *****************/
[NODE_PROFILING](source, globalName, filename, moduleType) {
return `/**
* @license React
* ${filename}
*
${license}
*/
module.exports = function $$$reconciler($$$hostConfig) {
var exports = {};
${source}
return exports;
};
module.exports.default = module.exports;
Object.defineProperty(module.exports, "__esModule", { value: true });
`;
},
};
function wrapBundle(
source,
bundleType,
globalName,
filename,
moduleType,
wrapWithModuleBoundaries
) {
if (wrapWithModuleBoundaries) {
switch (bundleType) {
case NODE_DEV:
case NODE_PROFILING:
case FB_WWW_DEV:
case FB_WWW_PROFILING:
case RN_OSS_DEV:
case RN_OSS_PROFILING:
case RN_FB_DEV:
case RN_FB_PROFILING:
// Remove the 'use strict' directive from source.
// The module start wrapper will add its own.
// This directive is only meaningful when it is the first statement in a file or function.
source = source.replace(USE_STRICT_HEADER_REGEX, '');
// Certain DEV and Profiling bundles should self-register their own module boundaries with DevTools.
// This allows the Timeline to de-emphasize (dim) internal stack frames.
source = `
${registerInternalModuleStart(globalName)}
${source}
${registerInternalModuleStop(globalName)}
`;
break;
}
}
if (bundleType === BROWSER_SCRIPT) {
// Bundles of type BROWSER_SCRIPT get sent straight to the browser without
// additional processing. So we should exclude any extra wrapper comments.
return source;
}
if (moduleType === RECONCILER) {
// Standalone reconciler is only used by third-party renderers.
// It is handled separately.
const wrapper = reconcilerWrappers[bundleType];
if (typeof wrapper !== 'function') {
throw new Error(
`Unsupported build type for the reconciler package: ${bundleType}.`
);
}
return wrapper(source, globalName, filename, moduleType);
}
// All the other packages.
const wrapper = wrappers[bundleType];
if (typeof wrapper !== 'function') {
throw new Error(`Unsupported build type: ${bundleType}.`);
}
return wrapper(source, globalName, filename, moduleType);
}
module.exports = {
wrapBundle,
};