scripts/rollup/forks.js (430 lines of code) (raw):

'use strict'; const {bundleTypes, moduleTypes} = require('./bundles'); const inlinedHostConfigs = require('../shared/inlinedHostConfigs'); const { UMD_DEV, UMD_PROD, UMD_PROFILING, 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, } = bundleTypes; const {RENDERER, RECONCILER} = moduleTypes; const RELEASE_CHANNEL = process.env.RELEASE_CHANNEL; // Default to building in experimental mode. If the release channel is set via // an environment variable, then check if it's "experimental". const __EXPERIMENTAL__ = typeof RELEASE_CHANNEL === 'string' ? RELEASE_CHANNEL === 'experimental' : true; // 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({ // 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 './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. './packages/shared/ReactSharedInternals.js': ( bundleType, entry, dependencies ) => { if (entry === 'react' || entry === 'react/src/ReactSharedSubset.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. // We return an error because we only want to throw if this module gets used. return new Error( 'Cannot use a module that depends on ReactSharedInternals ' + 'from "' + entry + '" because it does not declare "react" in the package ' + 'dependencies or peerDependencies.' ); } return null; }, // We have a few forks for different environments. './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 './packages/shared/forks/ReactFeatureFlags.native-fb.js'; case RN_OSS_DEV: case RN_OSS_PROD: case RN_OSS_PROFILING: return './packages/shared/forks/ReactFeatureFlags.native-oss.js'; default: throw Error( `Unexpected entry (${entry}) and bundleType (${bundleType})` ); } case 'react-native-renderer/fabric': switch (bundleType) { case RN_FB_DEV: case RN_FB_PROD: case RN_FB_PROFILING: return './packages/shared/forks/ReactFeatureFlags.native-fb.js'; case RN_OSS_DEV: case RN_OSS_PROD: case RN_OSS_PROFILING: return './packages/shared/forks/ReactFeatureFlags.native-oss.js'; default: throw Error( `Unexpected entry (${entry}) and bundleType (${bundleType})` ); } case 'react-test-renderer': switch (bundleType) { case RN_FB_DEV: case RN_FB_PROD: case RN_FB_PROFILING: case RN_OSS_DEV: case RN_OSS_PROD: case RN_OSS_PROFILING: return './packages/shared/forks/ReactFeatureFlags.test-renderer.native.js'; case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: return './packages/shared/forks/ReactFeatureFlags.test-renderer.www.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 './packages/shared/forks/ReactFeatureFlags.testing.www.js'; } return './packages/shared/forks/ReactFeatureFlags.testing.js'; default: switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: return './packages/shared/forks/ReactFeatureFlags.www.js'; case RN_FB_DEV: case RN_FB_PROD: case RN_FB_PROFILING: return './packages/shared/forks/ReactFeatureFlags.native-fb.js'; } } return null; }, './packages/scheduler/index.js': (bundleType, entry, dependencies) => { switch (bundleType) { case UMD_DEV: case UMD_PROD: case UMD_PROFILING: if (dependencies.indexOf('react') === -1) { // It's only safe to use this fork for modules that depend on React, // because they read the re-exported API from the SECRET_INTERNALS object. return null; } // 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 <script> tag return './packages/shared/forks/Scheduler.umd.js'; default: // For other bundles, use the shared NPM package. return null; } }, './packages/scheduler/src/SchedulerFeatureFlags.js': ( bundleType, entry, dependencies ) => { if ( bundleType === FB_WWW_DEV || bundleType === FB_WWW_PROD || bundleType === FB_WWW_PROFILING ) { return './packages/scheduler/src/forks/SchedulerFeatureFlags.www.js'; } return './packages/scheduler/src/SchedulerFeatureFlags.js'; }, './packages/shared/consoleWithStackDev.js': (bundleType, entry) => { switch (bundleType) { case FB_WWW_DEV: return './packages/shared/forks/consoleWithStackDev.www.js'; default: return null; } }, // In FB bundles, we preserve an inline require to ReactCurrentOwner. // See the explanation in FB version of ReactCurrentOwner in www: './packages/react/src/ReactCurrentOwner.js': (bundleType, entry) => { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: return './packages/react/src/forks/ReactCurrentOwner.www.js'; default: return null; } }, // Similarly, we preserve an inline require to ReactCurrentDispatcher. // See the explanation in FB version of ReactCurrentDispatcher in www: './packages/react/src/ReactCurrentDispatcher.js': (bundleType, entry) => { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: return './packages/react/src/forks/ReactCurrentDispatcher.www.js'; default: return null; } }, './packages/react/src/ReactSharedInternals.js': (bundleType, entry) => { switch (bundleType) { case UMD_DEV: case UMD_PROD: case UMD_PROFILING: return './packages/react/src/forks/ReactSharedInternals.umd.js'; default: return null; } }, // Different wrapping/reporting for caught errors. './packages/shared/invokeGuardedCallbackImpl.js': (bundleType, entry) => { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: return './packages/shared/forks/invokeGuardedCallbackImpl.www.js'; default: return null; } }, './packages/react-reconciler/src/ReactFiberReconciler.js': ( bundleType, entry, dependencies, moduleType, bundle ) => { if (bundle.enableNewReconciler) { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: // Use the forked version of the reconciler return './packages/react-reconciler/src/ReactFiberReconciler.new.js'; } } // Otherwise, use the non-forked version. return './packages/react-reconciler/src/ReactFiberReconciler.old.js'; }, './packages/react-reconciler/src/ReactEventPriorities.js': ( bundleType, entry, dependencies, moduleType, bundle ) => { if (bundle.enableNewReconciler) { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: // Use the forked version of the reconciler return './packages/react-reconciler/src/ReactEventPriorities.new.js'; } } // Otherwise, use the non-forked version. return './packages/react-reconciler/src/ReactEventPriorities.old.js'; }, './packages/react-reconciler/src/ReactFiberHotReloading.js': ( bundleType, entry, dependencies, moduleType, bundle ) => { if (bundle.enableNewReconciler) { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: // Use the forked version of the reconciler return './packages/react-reconciler/src/ReactFiberHotReloading.new.js'; } } // Otherwise, use the non-forked version. return './packages/react-reconciler/src/ReactFiberHotReloading.old.js'; }, // Different dialogs for caught errors. './packages/react-reconciler/src/ReactFiberErrorDialog.js': ( bundleType, entry ) => { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: // Use the www fork which shows an error dialog. return './packages/react-reconciler/src/forks/ReactFiberErrorDialog.www.js'; case RN_OSS_DEV: case RN_OSS_PROD: case RN_OSS_PROFILING: case RN_FB_DEV: case RN_FB_PROD: case RN_FB_PROFILING: switch (entry) { case 'react-native-renderer': case 'react-native-renderer/fabric': // Use the RN fork which plays well with redbox. return './packages/react-reconciler/src/forks/ReactFiberErrorDialog.native.js'; default: return null; } default: return null; } }, './packages/react-reconciler/src/ReactFiberHostConfig.js': ( bundleType, entry, dependencies, moduleType ) => { if (dependencies.indexOf('react-reconciler') !== -1) { return null; } if (moduleType !== RENDERER && moduleType !== RECONCILER) { return null; } // eslint-disable-next-line no-for-of-loops/no-for-of-loops for (let rendererInfo of inlinedHostConfigs) { if (rendererInfo.entryPoints.indexOf(entry) !== -1) { return `./packages/react-reconciler/src/forks/ReactFiberHostConfig.${rendererInfo.shortName}.js`; } } throw new Error( 'Expected ReactFiberHostConfig to always be replaced with a shim, but ' + `found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` + 'Did you mean to add it there to associate it with a specific renderer?' ); }, './packages/react-server/src/ReactServerStreamConfig.js': ( bundleType, entry, dependencies, moduleType ) => { if (dependencies.indexOf('react-server') !== -1) { return null; } if (moduleType !== RENDERER && moduleType !== RECONCILER) { return null; } // eslint-disable-next-line no-for-of-loops/no-for-of-loops for (let rendererInfo of inlinedHostConfigs) { if (rendererInfo.entryPoints.indexOf(entry) !== -1) { if (!rendererInfo.isServerSupported) { return null; } return `./packages/react-server/src/forks/ReactServerStreamConfig.${rendererInfo.shortName}.js`; } } throw new Error( 'Expected ReactServerStreamConfig to always be replaced with a shim, but ' + `found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` + 'Did you mean to add it there to associate it with a specific renderer?' ); }, './packages/react-server/src/ReactServerFormatConfig.js': ( bundleType, entry, dependencies, moduleType ) => { if (dependencies.indexOf('react-server') !== -1) { return null; } if (moduleType !== RENDERER && moduleType !== RECONCILER) { return null; } // eslint-disable-next-line no-for-of-loops/no-for-of-loops for (let rendererInfo of inlinedHostConfigs) { if (rendererInfo.entryPoints.indexOf(entry) !== -1) { if (!rendererInfo.isServerSupported) { return null; } return `./packages/react-server/src/forks/ReactServerFormatConfig.${rendererInfo.shortName}.js`; } } throw new Error( 'Expected ReactServerFormatConfig to always be replaced with a shim, but ' + `found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` + 'Did you mean to add it there to associate it with a specific renderer?' ); }, './packages/react-server/src/ReactFlightServerConfig.js': ( bundleType, entry, dependencies, moduleType ) => { if (dependencies.indexOf('react-server') !== -1) { return null; } if (moduleType !== RENDERER && moduleType !== RECONCILER) { return null; } // eslint-disable-next-line no-for-of-loops/no-for-of-loops for (let rendererInfo of inlinedHostConfigs) { if (rendererInfo.entryPoints.indexOf(entry) !== -1) { if (!rendererInfo.isServerSupported) { return null; } return `./packages/react-server/src/forks/ReactFlightServerConfig.${rendererInfo.shortName}.js`; } } throw new Error( 'Expected ReactFlightServerConfig to always be replaced with a shim, but ' + `found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` + 'Did you mean to add it there to associate it with a specific renderer?' ); }, './packages/react-client/src/ReactFlightClientHostConfig.js': ( bundleType, entry, dependencies, moduleType ) => { if (dependencies.indexOf('react-client') !== -1) { return null; } if (moduleType !== RENDERER && moduleType !== RECONCILER) { return null; } // eslint-disable-next-line no-for-of-loops/no-for-of-loops for (let rendererInfo of inlinedHostConfigs) { if (rendererInfo.entryPoints.indexOf(entry) !== -1) { if (!rendererInfo.isServerSupported) { return null; } return `./packages/react-client/src/forks/ReactFlightClientHostConfig.${rendererInfo.shortName}.js`; } } throw new Error( 'Expected ReactFlightClientHostConfig to always be replaced with a shim, but ' + `found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` + 'Did you mean to add it there to associate it with a specific renderer?' ); }, // We wrap top-level listeners into guards on www. './packages/react-dom/src/events/EventListener.js': (bundleType, entry) => { switch (bundleType) { case FB_WWW_DEV: case FB_WWW_PROD: case FB_WWW_PROFILING: if (__EXPERIMENTAL__) { // In modern builds we don't use the indirection. We just use raw DOM. return null; } else { // Use the www fork which is integrated with TimeSlice profiling. return './packages/react-dom/src/events/forks/EventListener-www.js'; } default: return null; } }, './packages/use-sync-external-store/src/useSyncExternalStore.js': ( bundleType, entry ) => { if (entry.startsWith('use-sync-external-store/shim')) { return './packages/use-sync-external-store/src/forks/useSyncExternalStore.forward-to-shim.js'; } if (entry !== 'use-sync-external-store') { // Internal modules that aren't shims should use the native API from the // react package. return './packages/use-sync-external-store/src/forks/useSyncExternalStore.forward-to-built-in.js'; } return null; }, './packages/use-sync-external-store/src/isServerEnvironment.js': ( bundleType, entry ) => { if (entry.endsWith('.native')) { return './packages/use-sync-external-store/src/forks/isServerEnvironment.native.js'; } }, }); module.exports = forks;