Files
react/scripts/rollup/modules.js
T

284 lines
8.3 KiB
JavaScript

"use strict";
const { resolve, basename } = require('path');
const { sync } = require('glob');
const {
bundleTypes,
} = require('./bundles');
const exclude = [
'src/**/__benchmarks__/**/*.js',
'src/**/__tests__/**/*.js',
'src/**/__mocks__/**/*.js',
];
// these are the FBJS modules that are used throughout our bundles
const fbjsModules = [
'fbjs/lib/warning',
'fbjs/lib/invariant',
'fbjs/lib/emptyFunction',
'fbjs/lib/emptyObject',
'fbjs/lib/hyphenateStyleName',
'fbjs/lib/getUnboundedScrollPosition',
'fbjs/lib/camelizeStyleName',
'fbjs/lib/containsNode',
'fbjs/lib/shallowEqual',
'fbjs/lib/getActiveElement',
'fbjs/lib/focusNode',
'fbjs/lib/EventListener',
'fbjs/lib/memoizeStringOnly',
'fbjs/lib/ExecutionEnvironment',
'fbjs/lib/createNodesFromMarkup',
'fbjs/lib/performanceNow',
];
// these files need to be copied to the facebook-www build
const facebookWWWSrcDependencies = [
'src/test/reactComponentExpect.js',
'src/renderers/dom/shared/eventPlugins/TapEventPlugin.js',
];
// this function builds up a very niave Haste-like moduleMap
// that works to create up an alias map for modules to link
// up to their actual disk location so Rollup can properly
// bundle them
function createModuleMap(paths, extractErrors) {
const moduleMap = {};
paths.forEach(path => {
const files = sync(path, exclude);
files.forEach(file => {
if (extractErrors) {
extractErrors(file);
}
const moduleName = basename(file, '.js');
moduleMap[moduleName] = resolve(file);
});
});
return moduleMap;
}
function getNodeModules(bundleType) {
// rather than adding the rollup node resolve plugin,
// we can instead deal with the only node module that is used
// for UMD bundles - object-assign
switch (bundleType) {
case bundleTypes.UMD_DEV:
case bundleTypes.UMD_PROD:
return {
'object-assign': resolve('./node_modules/object-assign/index.js'),
};
case bundleTypes.NODE_DEV:
case bundleTypes.NODE_PROD:
case bundleTypes.FB:
case bundleTypes.RN:
return {};
}
}
function ignoreFBModules() {
return [
// At FB, we don't know them statically:
'ReactFeatureFlags',
'ReactDOMFeatureFlags',
// In FB bundles, we preserve an inline require to ReactCurrentOwner.
// See the explanation in FB version of ReactCurrentOwner in www:
'react/lib/ReactCurrentOwner',
'ReactCurrentOwner',
];
}
function ignoreReactNativeModules() {
return [
// This imports NativeMethodsMixin, causing
// a circular dependency.
'View',
];
}
function getExternalModules(externals, bundleType, isRenderer) {
// external modules tell Rollup that we should not attempt
// to bundle these modules and instead treat them as
// external depedencies to the bundle. so for CJS bundles
// this means having a require("name-of-external-module") at
// the top of the bundle. for UMD bundles this means having
// both a require and a global check for them
let externalModules = externals;
switch (bundleType) {
case bundleTypes.UMD_DEV:
case bundleTypes.UMD_PROD:
if (isRenderer) {
externalModules.push(
'react'
);
}
break;
case bundleTypes.NODE_DEV:
case bundleTypes.NODE_PROD:
case bundleTypes.RN:
externalModules.push(
'object-assign',
...fbjsModules
);
if (isRenderer) {
externalModules.push(
'react'
);
}
break;
case bundleTypes.FB:
externalModules.push(
...fbjsModules
);
if (isRenderer) {
externalModules.push(
'React'
);
}
break;
}
return externalModules;
}
function getInternalModules() {
// we tell Rollup where these files are located internally, otherwise
// it doesn't pick them up and assumes they're external
return {
reactProdInvariant: resolve('./src/shared/utils/reactProdInvariant.js'),
'react/lib/ReactDebugCurrentFrame': resolve('./src/isomorphic/classic/element/ReactDebugCurrentFrame.js'),
};
}
function replaceInternalModules() {
// we inline these modules in the bundles rather than leave them as external
return {
'react-dom/lib/ReactPerf': resolve('./src/renderers/shared/ReactPerf.js'),
'react-dom/lib/ReactTestUtils': resolve('./src/test/ReactTestUtils.js'),
'react-dom/lib/ReactInstanceMap': resolve('./src/renderers/shared/shared/ReactInstanceMap.js'),
'react-dom': resolve('./src/renderers/dom/ReactDOM.js'),
};
}
function getFbjsModuleAliases(bundleType) {
switch (bundleType) {
case bundleTypes.UMD_DEV:
case bundleTypes.UMD_PROD:
// we want to bundle these modules, so we re-alias them to the actual
// file so Rollup can bundle them up
const fbjsModulesAlias = {};
fbjsModules.forEach(fbjsModule => {
fbjsModulesAlias[fbjsModule] = resolve(`./node_modules/${fbjsModule}`);
});
return fbjsModulesAlias;
case bundleTypes.NODE_DEV:
case bundleTypes.NODE_PROD:
case bundleTypes.FB:
case bundleTypes.RN:
// for FB we don't want to bundle the above modules, instead keep them
// as external require() calls in the bundle
return {};
}
}
function replaceFbjsModuleAliases(bundleType) {
switch (bundleType) {
case bundleTypes.UMD_DEV:
case bundleTypes.UMD_PROD:
case bundleTypes.NODE_DEV:
case bundleTypes.NODE_PROD:
case bundleTypes.RN:
return {};
case bundleTypes.FB:
// additionally we add mappings for "react"
// so they work correctly on FB, this will change soon
return {
"'react'": "'React'",
};
}
}
// for renderers, we want them to require the __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner
// on the React bundle itself rather than require module directly.
// For the React bundle, ReactCurrentOwner should be bundled as part of the bundle
// itself and exposed on __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
const shimReactCurrentOwner = resolve('./scripts/rollup/shims/rollup/ReactCurrentOwnerRollupShim.js');
const realReactCurrentOwner = resolve('./src/isomorphic/classic/element/ReactCurrentOwner.js')
function getReactCurrentOwnerModuleAlias(bundleType, isRenderer) {
if (bundleType === 'FB') {
// In FB bundles, we preserve an inline require to ReactCurrentOwner.
// See the explanation in FB version of ReactCurrentOwner in www.
return {};
}
if (isRenderer) {
return {
'ReactCurrentOwner': shimReactCurrentOwner,
'react/lib/ReactCurrentOwner': shimReactCurrentOwner,
};
} else {
return {
'ReactCurrentOwner': realReactCurrentOwner,
'react/lib/ReactCurrentOwner': realReactCurrentOwner,
};
}
}
// this works almost identically to the ReactCurrentOwner shim above
const shimReactCheckPropTypes = resolve('./scripts/rollup/shims/rollup/ReactCheckPropTypesRollupShim.js');
const realCheckPropTypes = resolve('./src/isomorphic/classic/types/checkPropTypes.js')
function getReactCheckPropTypesModuleAlias(bundleType, isRenderer) {
if (isRenderer) {
return {
'checkPropTypes': shimReactCheckPropTypes,
'react/lib/checkPropTypes': shimReactCheckPropTypes,
};
} else {
return {
'checkPropTypes': realCheckPropTypes,
'react/lib/checkPropTypes': realCheckPropTypes,
};
}
}
// this works almost identically to the ReactCurrentOwner shim above
const shimReactComponentTreeHook = resolve('./scripts/rollup/shims/rollup/ReactComponentTreeHookRollupShim.js');
const realReactComponentTreeHook = resolve('./src/isomorphic/hooks/ReactComponentTreeHook.js');
function getReactComponentTreeHookModuleAlias(bundleType, isRenderer) {
if (isRenderer) {
return {
'ReactComponentTreeHook': shimReactComponentTreeHook,
'react/lib/ReactComponentTreeHook': shimReactComponentTreeHook,
};
} else {
return {
'ReactComponentTreeHook': realReactComponentTreeHook,
'react/lib/ReactComponentTreeHook': realReactComponentTreeHook,
};
}
}
module.exports = {
createModuleMap,
getNodeModules,
replaceInternalModules,
getInternalModules,
getFbjsModuleAliases,
replaceFbjsModuleAliases,
ignoreFBModules,
ignoreReactNativeModules,
getExternalModules,
getReactCurrentOwnerModuleAlias,
getReactCheckPropTypesModuleAlias,
getReactComponentTreeHookModuleAlias,
facebookWWWSrcDependencies,
};