mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
improved how bundles are built by exposing externals and making the process less "magical", also tidied up code and added more comments
This commit is contained in:
+19
-14
@@ -14,13 +14,14 @@ const rimraf = require('rimraf');
|
||||
const argv = require('minimist')(process.argv.slice(2));
|
||||
const {
|
||||
createModuleMap,
|
||||
getExternalModules,
|
||||
getNodeModules,
|
||||
getInternalModules,
|
||||
replaceInternalModules,
|
||||
getFbjsModuleAliases,
|
||||
replaceFbjsModuleAliases,
|
||||
ignoreFBModules,
|
||||
ignoreReactNativeModules,
|
||||
getExternalModules,
|
||||
} = require('./modules');
|
||||
const {
|
||||
bundles,
|
||||
@@ -31,7 +32,7 @@ function getAliases(paths, bundleType) {
|
||||
return Object.assign(
|
||||
createModuleMap(paths),
|
||||
getInternalModules(bundleType),
|
||||
getExternalModules(bundleType),
|
||||
getNodeModules(bundleType),
|
||||
getFbjsModuleAliases(bundleType)
|
||||
);
|
||||
}
|
||||
@@ -82,7 +83,8 @@ function updateBabelConfig(babelOpts, bundleType) {
|
||||
|
||||
function handleRollupWarnings(warning) {
|
||||
if (warning.code === 'UNRESOLVED_IMPORT') {
|
||||
return;
|
||||
console.error(warning.message);
|
||||
process.exit(1);
|
||||
}
|
||||
console.warn(warning.message || warning);
|
||||
}
|
||||
@@ -217,6 +219,8 @@ function createBundle({
|
||||
name,
|
||||
hasteName,
|
||||
bundleTypes: bundleTypesToUse,
|
||||
isRenderer,
|
||||
externals,
|
||||
}, bundleType) {
|
||||
if ((inputBundleType && inputBundleType !== bundleType)
|
||||
|| bundleTypesToUse.indexOf(bundleType) === -1) {
|
||||
@@ -227,25 +231,26 @@ function createBundle({
|
||||
const format = getFormat(bundleType);
|
||||
return rollup({
|
||||
entry: bundleType === bundleTypes.FB ? fbEntry : entry,
|
||||
plugins: getPlugins(entry, babelOpts, paths, filename, bundleType),
|
||||
external: getExternalModules(externals, bundleType, isRenderer),
|
||||
onwarn: handleRollupWarnings,
|
||||
plugins: getPlugins(entry, babelOpts, paths, filename, bundleType),
|
||||
}).then(({write}) => write(
|
||||
updateBundleConfig(config, filename, format, bundleType, hasteName)
|
||||
)).catch(console.error);
|
||||
)).catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
// clear the build folder
|
||||
rimraf(join('build', 'rollup'), () => {
|
||||
bundles.forEach(bundle =>
|
||||
createBundle(bundle, bundleTypes.DEV).then(() =>
|
||||
createBundle(bundle, bundleTypes.PROD).then(() =>
|
||||
createBundle(bundle, bundleTypes.NODE).then(() =>
|
||||
createBundle(bundle, bundleTypes.FB).then(() =>
|
||||
createBundle(bundle, bundleTypes.RN)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
Promise.resolve()
|
||||
.then(() => createBundle(bundle, bundleTypes.DEV))
|
||||
.then(() => createBundle(bundle, bundleTypes.PROD))
|
||||
.then(() => createBundle(bundle, bundleTypes.NODE))
|
||||
.then(() => createBundle(bundle, bundleTypes.FB))
|
||||
.then(() => createBundle(bundle, bundleTypes.RN))
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -35,8 +35,10 @@ const bundles = [
|
||||
sourceMap: false,
|
||||
},
|
||||
entry: 'src/umd/ReactUMDEntry.js',
|
||||
externals: [],
|
||||
fbEntry: 'src/fb/ReactFBEntry.js',
|
||||
hasteName: 'React-fb',
|
||||
isRenderer: false,
|
||||
name: 'react',
|
||||
paths: [
|
||||
'src/umd/ReactUMDEntry.js',
|
||||
@@ -64,8 +66,10 @@ const bundles = [
|
||||
sourceMap: false,
|
||||
},
|
||||
entry: 'src/umd/ReactDOMUMDEntry.js',
|
||||
externals: [],
|
||||
fbEntry: 'src/fb/ReactDOMFBEntry.js',
|
||||
hasteName: 'ReactDOMStack-fb',
|
||||
isRenderer: true,
|
||||
name: 'react-dom',
|
||||
paths: [
|
||||
'src/umd/ReactDOMUMDEntry.js',
|
||||
@@ -90,8 +94,10 @@ const bundles = [
|
||||
sourceMap: false,
|
||||
},
|
||||
entry: 'src/renderers/dom/fiber/ReactDOMFiber.js',
|
||||
externals: [],
|
||||
fbEntry: 'src/fb/ReactDOMFiberFBEntry.js',
|
||||
hasteName: 'ReactDOMFiber-fb',
|
||||
isRenderer: true,
|
||||
name: 'react-dom-fiber',
|
||||
paths: [
|
||||
'src/renderers/dom/**/*.js',
|
||||
@@ -116,8 +122,10 @@ const bundles = [
|
||||
sourceMap: false,
|
||||
},
|
||||
entry: 'src/umd/ReactDOMServerUMDEntry.js',
|
||||
externals: [],
|
||||
fbEntry: 'src/umd/ReactDOMServerUMDEntry.js',
|
||||
hasteName: 'ReactDOMServerStack',
|
||||
isRenderer: true,
|
||||
// TODO: this is taken. Do we change the build task
|
||||
// to understand react-dom/server?
|
||||
name: 'react-dom-server',
|
||||
@@ -146,8 +154,14 @@ const bundles = [
|
||||
sourceMap: false,
|
||||
},
|
||||
entry: 'src/renderers/art/ReactARTStack.js',
|
||||
externals: [
|
||||
'art/modes/current',
|
||||
'art/modes/fast-noSideEffects',
|
||||
'art/core/transform',
|
||||
],
|
||||
fbEntry: 'src/renderers/art/ReactARTStack.js',
|
||||
hasteName: 'ReactARTStack',
|
||||
isRenderer: true,
|
||||
name: 'react-art',
|
||||
paths: [
|
||||
// TODO: it relies on ReactDOMFrameScheduling. Need to move to shared/?
|
||||
@@ -171,8 +185,14 @@ const bundles = [
|
||||
sourceMap: false,
|
||||
},
|
||||
entry: 'src/renderers/art/ReactARTFiber.js',
|
||||
externals: [
|
||||
'art/modes/current',
|
||||
'art/modes/fast-noSideEffects',
|
||||
'art/core/transform',
|
||||
],
|
||||
fbEntry: 'src/renderers/art/ReactARTFiber.js',
|
||||
hasteName: 'ReactARTFiber',
|
||||
isRenderer: true,
|
||||
name: 'react-art',
|
||||
paths: [
|
||||
// TODO: it relies on ReactDOMFrameScheduling. Need to move to shared/?
|
||||
@@ -195,7 +215,20 @@ const bundles = [
|
||||
sourceMap: false,
|
||||
},
|
||||
entry: 'src/renderers/native/ReactNative.js',
|
||||
externals: [
|
||||
'InitializeCore',
|
||||
'RCTEventEmitter',
|
||||
'UIManager',
|
||||
'react/lib/ReactComponentTreeHook',
|
||||
'react/lib/checkPropTypes',
|
||||
'react/lib/ReactDebugCurrentFrame',
|
||||
'deepDiffer',
|
||||
'flattenStyle',
|
||||
'TextInputState',
|
||||
'deepFreezeAndThrowOnMutationInDev',
|
||||
],
|
||||
hasteName: 'ReactNative',
|
||||
isRenderer: true,
|
||||
name: 'react-native-renderer',
|
||||
paths: [
|
||||
'src/renderers/native/**/*.js',
|
||||
|
||||
+121
-48
@@ -12,6 +12,31 @@ const exclude = [
|
||||
'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',
|
||||
];
|
||||
|
||||
// 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) {
|
||||
const moduleMap = {};
|
||||
|
||||
@@ -27,7 +52,10 @@ function createModuleMap(paths) {
|
||||
return moduleMap;
|
||||
}
|
||||
|
||||
function getExternalModules(bundleType) {
|
||||
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.DEV:
|
||||
case bundleTypes.PROD:
|
||||
@@ -55,6 +83,77 @@ function ignoreFBModules() {
|
||||
];
|
||||
}
|
||||
|
||||
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 = [];
|
||||
|
||||
switch (bundleType) {
|
||||
case bundleTypes.DEV:
|
||||
case bundleTypes.PROD:
|
||||
if (isRenderer) {
|
||||
externalModules = [
|
||||
'react',
|
||||
];
|
||||
}
|
||||
break;
|
||||
case bundleTypes.NODE:
|
||||
case bundleTypes.RN:
|
||||
externalModules = [
|
||||
'object-assign',
|
||||
'fbjs/lib/warning',
|
||||
'fbjs/lib/emptyObject',
|
||||
'fbjs/lib/emptyFunction',
|
||||
'fbjs/lib/invariant',
|
||||
'react/lib/ReactCurrentOwner',
|
||||
];
|
||||
|
||||
if (isRenderer) {
|
||||
externalModules.push(
|
||||
'react',
|
||||
'ReactCurrentOwner',
|
||||
...fbjsModules
|
||||
);
|
||||
}
|
||||
break;
|
||||
case bundleTypes.FB:
|
||||
externalModules = [
|
||||
// note: we don't put "ReactCurrentOwner" in here
|
||||
// as we we're ignoring it from being processed
|
||||
// by rollup so it remains inline in the bundle
|
||||
'warning',
|
||||
'emptyObject',
|
||||
'emptyFunction',
|
||||
'invariant',
|
||||
];
|
||||
if (isRenderer) {
|
||||
const replacedFbModuleAliases = replaceFbjsModuleAliases(bundleType);
|
||||
const aliases = Object.keys(replacedFbModuleAliases).map(
|
||||
alias => replacedFbModuleAliases[alias]
|
||||
);
|
||||
externalModules.push(
|
||||
'React',
|
||||
...aliases
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
externalModules.push(...externals);
|
||||
return externalModules;
|
||||
}
|
||||
|
||||
function getCommonInternalModules() {
|
||||
// we tell Rollup where these files are located internally, otherwise
|
||||
// it doesn't pick them up and assumes they're external
|
||||
@@ -105,26 +204,14 @@ function getFbjsModuleAliases(bundleType) {
|
||||
switch (bundleType) {
|
||||
case bundleTypes.DEV:
|
||||
case bundleTypes.PROD:
|
||||
return {
|
||||
// we want to bundle these modules, so we re-alias them to the actual
|
||||
// file so Rollup can bundle them up
|
||||
'fbjs/lib/warning': resolve('./node_modules/fbjs/lib/warning.js'),
|
||||
'fbjs/lib/invariant': resolve('./node_modules/fbjs/lib/invariant.js'),
|
||||
'fbjs/lib/emptyFunction': resolve('./node_modules/fbjs/lib/emptyFunction.js'),
|
||||
'fbjs/lib/emptyObject': resolve('./node_modules/fbjs/lib/emptyObject.js'),
|
||||
'fbjs/lib/hyphenateStyleName': resolve('./node_modules/fbjs/lib/hyphenateStyleName.js'),
|
||||
'fbjs/lib/getUnboundedScrollPosition': resolve('./node_modules/fbjs/lib/getUnboundedScrollPosition.js'),
|
||||
'fbjs/lib/camelizeStyleName': resolve('./node_modules/fbjs/lib/camelizeStyleName.js'),
|
||||
'fbjs/lib/containsNode': resolve('./node_modules/fbjs/lib/containsNode.js'),
|
||||
'fbjs/lib/shallowEqual': resolve('./node_modules/fbjs/lib/shallowEqual.js'),
|
||||
'fbjs/lib/getActiveElement': resolve('./node_modules/fbjs/lib/getActiveElement.js'),
|
||||
'fbjs/lib/focusNode': resolve('./node_modules/fbjs/lib/focusNode.js'),
|
||||
'fbjs/lib/EventListener': resolve('./node_modules/fbjs/lib/EventListener.js'),
|
||||
'fbjs/lib/memoizeStringOnly': resolve('./node_modules/fbjs/lib/memoizeStringOnly.js'),
|
||||
'fbjs/lib/ExecutionEnvironment': resolve('./node_modules/fbjs/lib/ExecutionEnvironment.js'),
|
||||
'fbjs/lib/createNodesFromMarkup': resolve('./node_modules/fbjs/lib/createNodesFromMarkup.js'),
|
||||
'fbjs/lib/performanceNow': resolve('./node_modules/fbjs/lib/performanceNow.js'),
|
||||
};
|
||||
// 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:
|
||||
case bundleTypes.FB:
|
||||
case bundleTypes.RN:
|
||||
@@ -134,14 +221,6 @@ function getFbjsModuleAliases(bundleType) {
|
||||
}
|
||||
}
|
||||
|
||||
function ignoreReactNativeModules() {
|
||||
return [
|
||||
// This imports NativeMethodsMixin, causing
|
||||
// a circular dependency.
|
||||
'View',
|
||||
];
|
||||
}
|
||||
|
||||
function replaceFbjsModuleAliases(bundleType) {
|
||||
switch (bundleType) {
|
||||
case bundleTypes.DEV:
|
||||
@@ -152,36 +231,30 @@ function replaceFbjsModuleAliases(bundleType) {
|
||||
case bundleTypes.FB:
|
||||
// the diff for Haste to support fbjs/lib/* hasn't landed, so this
|
||||
// re-aliases them back to the non fbjs/lib/* versions
|
||||
return {
|
||||
'fbjs/lib/warning': 'warning',
|
||||
'fbjs/lib/invariant': 'invariant',
|
||||
'fbjs/lib/emptyFunction': 'emptyFunction',
|
||||
'fbjs/lib/emptyObject': 'emptyObject',
|
||||
'fbjs/lib/hyphenateStyleName': 'hyphenateStyleName',
|
||||
'fbjs/lib/getUnboundedScrollPosition': 'getUnboundedScrollPosition',
|
||||
'fbjs/lib/camelizeStyleName': 'camelizeStyleName',
|
||||
'fbjs/lib/containsNode': 'containsNode',
|
||||
'fbjs/lib/shallowEqual': 'shallowEqual',
|
||||
'fbjs/lib/getActiveElement': 'getActiveElement',
|
||||
'fbjs/lib/focusNode': 'focusNode',
|
||||
'fbjs/lib/EventListener': 'EventListener',
|
||||
'fbjs/lib/memoizeStringOnly': 'memoizeStringOnly',
|
||||
'fbjs/lib/ExecutionEnvironment': 'ExecutionEnvironment',
|
||||
'fbjs/lib/createNodesFromMarkup': 'createNodesFromMarkup',
|
||||
'fbjs/lib/performanceNow': 'performanceNow',
|
||||
// to do this, we ge the fbjsModules list of names and put them in
|
||||
// an alias object removing the fbjs/lib/ bit from the name
|
||||
const fbjsModulesAlias = {};
|
||||
fbjsModules.forEach(fbjsModule => {
|
||||
fbjsModulesAlias[fbjsModule] = fbjsModule.replace('fbjs/lib/', '');
|
||||
});
|
||||
|
||||
// additionally we add mappings for "ReactCurrentOwner" and "react"
|
||||
// so they work correctly on FB
|
||||
return Object.assign(fbjsModulesAlias, {
|
||||
'react/lib/ReactCurrentOwner': 'ReactCurrentOwner',
|
||||
"'react'": "'React'",
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createModuleMap,
|
||||
getExternalModules,
|
||||
getNodeModules,
|
||||
replaceInternalModules,
|
||||
getInternalModules,
|
||||
getFbjsModuleAliases,
|
||||
replaceFbjsModuleAliases,
|
||||
ignoreFBModules,
|
||||
ignoreReactNativeModules,
|
||||
getExternalModules,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user