From 197d45307b6db7f600f63a5b411c128decc626ee Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 8 Feb 2022 19:03:02 -0500 Subject: [PATCH] Remove path resolution from internal forks plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alternative to #23254 Our build script has a custom plugin to resolve internal module forks. Currently, it uses require.resolve to resolve the path to a real file on disk. Instead, I've updated all the forked module paths to match their location on disk, relative to the project root, to remove the need to resolve them in the build script's runtime. The main motivation is because require.resolve doesn't work with ESM modules, but aside from that, hardcoding the relative paths is more predictable — the Node module resolution algorithm is complicated, and we don't really need its features for this purpose. --- scripts/rollup/forks.js | 157 ++++++++++++--------- scripts/rollup/plugins/use-forks-plugin.js | 8 +- 2 files changed, 100 insertions(+), 65 deletions(-) diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index 9cab6e5be390..d4a392770bbf 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -30,10 +30,22 @@ const __EXPERIMENTAL__ = // If you need to replace a file with another file for a specific environment, // add it to this list with the logic for choosing the right replacement. + +// Fork paths are relative to the project root. They must include the full path, +// including the extension. We intentionally don't use Node's module resolution +// algorithm because 1) require.resolve doesn't work with ESM modules, and 2) +// the behavior is easier to predict. const forks = Object.freeze({ // Optimization: for UMDs, use a version that we can inline into the React bundle. // Use that from all other bundles. - 'object-assign': (bundleType, entry, dependencies) => { + + // NOTE: This is hard-coded to the main entry point of the (third-party) + // object-assign package. + './node_modules/object-assign/index.js': ( + bundleType, + entry, + dependencies + ) => { if ( bundleType !== UMD_DEV && bundleType !== UMD_PROD && @@ -45,7 +57,7 @@ const forks = Object.freeze({ } if (entry === 'react' || entry === 'react/unstable-shared-subset') { // Use the forked version that uses ES modules instead of CommonJS. - return 'shared/forks/object-assign.inline-umd.js'; + return './packages/shared/forks/object-assign.inline-umd.js'; } if (dependencies.indexOf('react') === -1) { // We can only apply the optimizations to bundle that depend on React @@ -53,19 +65,25 @@ const forks = Object.freeze({ return null; } // We can use the fork that reads the secret export! - return 'shared/forks/object-assign.umd.js'; + return './packages/shared/forks/object-assign.umd.js'; }, - 'react-shallow-renderer': () => { + // NOTE: This is hard-coded to the main entry point of the (third-party) + // react-shallow-renderer package. + './node_modules/react-shallow-renderer/index.js': () => { // Use ESM build of `react-shallow-renderer`. - return 'react-shallow-renderer/esm/index.js'; + return './node_modules/react-shallow-renderer/esm/index.js'; }, // Without this fork, importing `shared/ReactSharedInternals` inside // the `react` package itself would not work due to a cyclical dependency. - 'shared/ReactSharedInternals': (bundleType, entry, dependencies) => { + './packages/shared/ReactSharedInternals.js': ( + bundleType, + entry, + dependencies + ) => { if (entry === 'react' || entry === 'react/unstable-shared-subset') { - return 'react/src/ReactSharedInternals.js'; + return './packages/react/src/ReactSharedInternals.js'; } if (!entry.startsWith('react/') && dependencies.indexOf('react') === -1) { // React internals are unavailable if we can't reference the package. @@ -82,18 +100,18 @@ const forks = Object.freeze({ }, // We have a few forks for different environments. - 'shared/ReactFeatureFlags': (bundleType, entry) => { + './packages/shared/ReactFeatureFlags.js': (bundleType, entry) => { switch (entry) { case 'react-native-renderer': switch (bundleType) { case RN_FB_DEV: case RN_FB_PROD: case RN_FB_PROFILING: - return 'shared/forks/ReactFeatureFlags.native-fb.js'; + return './packages/shared/forks/ReactFeatureFlags.native-fb.js'; case RN_OSS_DEV: case RN_OSS_PROD: case RN_OSS_PROFILING: - return 'shared/forks/ReactFeatureFlags.native-oss.js'; + return './packages/shared/forks/ReactFeatureFlags.native-oss.js'; default: throw Error( `Unexpected entry (${entry}) and bundleType (${bundleType})` @@ -104,11 +122,11 @@ const forks = Object.freeze({ case RN_FB_DEV: case RN_FB_PROD: case RN_FB_PROFILING: - return 'shared/forks/ReactFeatureFlags.native-fb.js'; + return './packages/shared/forks/ReactFeatureFlags.native-fb.js'; case RN_OSS_DEV: case RN_OSS_PROD: case RN_OSS_PROFILING: - return 'shared/forks/ReactFeatureFlags.native-oss.js'; + return './packages/shared/forks/ReactFeatureFlags.native-oss.js'; default: throw Error( `Unexpected entry (${entry}) and bundleType (${bundleType})` @@ -122,37 +140,37 @@ const forks = Object.freeze({ case RN_OSS_DEV: case RN_OSS_PROD: case RN_OSS_PROFILING: - return 'shared/forks/ReactFeatureFlags.test-renderer.native.js'; + return './packages/shared/forks/ReactFeatureFlags.test-renderer.native.js'; case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: - return 'shared/forks/ReactFeatureFlags.test-renderer.www.js'; + return './packages/shared/forks/ReactFeatureFlags.test-renderer.www.js'; } - return 'shared/forks/ReactFeatureFlags.test-renderer.js'; + return './packages/shared/forks/ReactFeatureFlags.test-renderer.js'; case 'react-dom/unstable_testing': switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: - return 'shared/forks/ReactFeatureFlags.testing.www.js'; + return './packages/shared/forks/ReactFeatureFlags.testing.www.js'; } - return 'shared/forks/ReactFeatureFlags.testing.js'; + return './packages/shared/forks/ReactFeatureFlags.testing.js'; default: switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: - return 'shared/forks/ReactFeatureFlags.www.js'; + return './packages/shared/forks/ReactFeatureFlags.www.js'; case RN_FB_DEV: case RN_FB_PROD: case RN_FB_PROFILING: - return 'shared/forks/ReactFeatureFlags.native-fb.js'; + return './packages/shared/forks/ReactFeatureFlags.native-fb.js'; } } return null; }, - scheduler: (bundleType, entry, dependencies) => { + './packages/scheduler/index.js': (bundleType, entry, dependencies) => { switch (bundleType) { case UMD_DEV: case UMD_PROD: @@ -164,28 +182,32 @@ const forks = Object.freeze({ } // Optimization: for UMDs, use the API that is already a part of the React // package instead of requiring it to be loaded via a separate