mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
* Enable Yarn workspaces for packages/* * Move src/isomorphic/* into packages/react/src/* * Create index.js stubs for all packages in packages/* This makes the test pass again, but breaks the build because npm/ folders aren't used yet. I'm not sure if we'll keep this structure--I'll just keep working and fix the build after it settles down. * Put FB entry point for react-dom into packages/* * Move src/renderers/testing/* into packages/react-test-renderer/src/* Note that this is currently broken because Jest ignores node_modules, and so Yarn linking makes Jest skip React source when transforming. * Remove src/node_modules It is now unnecessary. Some tests fail though. * Add a hacky workaround for Jest/Workspaces issue Jest sees node_modules and thinks it's third party code. This is a hacky way to teach Jest to still transform anything in node_modules/react* if it resolves outside of node_modules (such as to our packages/*) folder. I'm not very happy with this and we should revisit. * Add a fake react-native package * Move src/renderers/art/* into packages/react-art/src/* * Move src/renderers/noop/* into packages/react-noop-renderer/src/* * Move src/renderers/dom/* into packages/react-dom/src/* * Move src/renderers/shared/fiber/* into packages/react-reconciler/src/* * Move DOM/reconciler tests I previously forgot to move * Move src/renderers/native-*/* into packages/react-native-*/src/* * Move shared code into packages/shared It's not super clear how to organize this properly yet. * Add back files that somehow got lost * Fix the build * Prettier * Add missing license headers * Fix an issue that caused mocks to get included into build * Update other references to src/ * Re-run Prettier * Fix lint * Fix weird Flow violation I didn't change this file but Flow started complaining. Caleb said this annotation was unnecessarily using $Abstract though so I removed it. * Update sizes * Fix stats script * Fix packaging fixtures Use file: instead of NODE_PATH since NODE_PATH. NODE_PATH trick only worked because we had no react/react-dom in root node_modules, but now we do. file: dependency only works as I expect in Yarn, so I moved the packaging fixtures to use Yarn and committed lockfiles. Verified that the page shows up. * Fix art fixture * Fix reconciler fixture * Fix SSR fixture * Rename native packages
337 lines
9.1 KiB
JavaScript
337 lines
9.1 KiB
JavaScript
'use strict';
|
|
|
|
const resolve = require('path').resolve;
|
|
const basename = require('path').basename;
|
|
const sync = require('glob').sync;
|
|
const bundleTypes = require('./bundles').bundleTypes;
|
|
const moduleTypes = require('./bundles').moduleTypes;
|
|
const extractErrorCodes = require('../error-codes/extract-errors');
|
|
|
|
const exclude = [
|
|
'**/__benchmarks__/**/*.js',
|
|
'**/__tests__/**/*.js',
|
|
'**/__mocks__/**/*.js',
|
|
];
|
|
|
|
const UMD_DEV = bundleTypes.UMD_DEV;
|
|
const UMD_PROD = bundleTypes.UMD_PROD;
|
|
const NODE_DEV = bundleTypes.NODE_DEV;
|
|
const NODE_PROD = bundleTypes.NODE_PROD;
|
|
const FB_DEV = bundleTypes.FB_DEV;
|
|
const FB_PROD = bundleTypes.FB_PROD;
|
|
const RN_DEV = bundleTypes.RN_DEV;
|
|
const RN_PROD = bundleTypes.RN_PROD;
|
|
|
|
const ISOMORPHIC = moduleTypes.ISOMORPHIC;
|
|
|
|
const errorCodeOpts = {
|
|
errorMapFilePath: 'scripts/error-codes/codes.json',
|
|
};
|
|
|
|
// 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',
|
|
];
|
|
|
|
const devOnlyFilesToStubOut = [
|
|
"'ReactDebugCurrentFrame'",
|
|
"'ReactComponentTreeHook'",
|
|
"'ReactPerf'",
|
|
"'ReactTestUtils'",
|
|
];
|
|
|
|
const legacyModules = [
|
|
'create-react-class',
|
|
'create-react-class/factory',
|
|
'prop-types',
|
|
'prop-types/checkPropTypes',
|
|
];
|
|
|
|
// 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, bundleType) {
|
|
const moduleMap = {};
|
|
|
|
paths.forEach(path => {
|
|
const files = sync(path, {ignore: exclude});
|
|
|
|
files.forEach(file => {
|
|
if (extractErrors) {
|
|
extractErrors(file);
|
|
}
|
|
const moduleName = basename(file, '.js');
|
|
|
|
moduleMap[moduleName] = resolve(file);
|
|
});
|
|
});
|
|
// if this is FB, we want to remove ReactCurrentOwner and lowPriorityWarning,
|
|
// so we can handle it with a different case
|
|
if (bundleType === FB_DEV || bundleType === FB_PROD) {
|
|
delete moduleMap.ReactCurrentOwner;
|
|
delete moduleMap.lowPriorityWarning;
|
|
}
|
|
return moduleMap;
|
|
}
|
|
|
|
function getNodeModules(bundleType, moduleType) {
|
|
// 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 UMD_DEV:
|
|
case UMD_PROD:
|
|
return {
|
|
// Bundle object-assign once in the isomorphic React, and then use
|
|
// that from the renderer UMD. Avoids bundling it in both UMDs.
|
|
'object-assign': moduleType === ISOMORPHIC
|
|
? resolve('./node_modules/object-assign/index.js')
|
|
: resolve('./scripts/rollup/shims/rollup/assign.js'),
|
|
// include the ART package modules directly by aliasing them from node_modules
|
|
'art/modes/current': resolve('./node_modules/art/modes/current.js'),
|
|
'art/modes/fast-noSideEffects': resolve(
|
|
'./node_modules/art/modes/fast-noSideEffects.js'
|
|
),
|
|
'art/core/transform': resolve('./node_modules/art/core/transform.js'),
|
|
};
|
|
case NODE_DEV:
|
|
case NODE_PROD:
|
|
case FB_DEV:
|
|
case FB_PROD:
|
|
case RN_DEV:
|
|
case RN_PROD:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
function ignoreFBModules() {
|
|
return [
|
|
// At FB, we don't know them statically:
|
|
'ReactFeatureFlags',
|
|
// In FB bundles, we preserve an inline require to ReactCurrentOwner.
|
|
// See the explanation in FB version of ReactCurrentOwner in www:
|
|
'ReactCurrentOwner',
|
|
'lowPriorityWarning',
|
|
];
|
|
}
|
|
|
|
function ignoreReactNativeModules() {
|
|
return [
|
|
// This imports NativeMethodsMixin, causing a circular dependency.
|
|
'View',
|
|
];
|
|
}
|
|
|
|
function getExternalModules(externals, bundleType, moduleType) {
|
|
// external modules tell Rollup that we should not attempt
|
|
// to bundle these modules and instead treat them as
|
|
// external dependencies 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.slice();
|
|
switch (bundleType) {
|
|
case UMD_DEV:
|
|
case UMD_PROD:
|
|
if (moduleType !== ISOMORPHIC) {
|
|
externalModules.push('react');
|
|
}
|
|
break;
|
|
case NODE_DEV:
|
|
case NODE_PROD:
|
|
case RN_DEV:
|
|
case RN_PROD:
|
|
fbjsModules.forEach(module => externalModules.push(module));
|
|
externalModules.push('object-assign');
|
|
if (moduleType !== ISOMORPHIC) {
|
|
externalModules.push('react');
|
|
}
|
|
break;
|
|
case FB_DEV:
|
|
case FB_PROD:
|
|
fbjsModules.forEach(module => externalModules.push(module));
|
|
externalModules.push('object-assign');
|
|
externalModules.push('ReactCurrentOwner');
|
|
externalModules.push('lowPriorityWarning');
|
|
if (moduleType !== ISOMORPHIC) {
|
|
externalModules.push('React');
|
|
if (externalModules.indexOf('react-dom') > -1) {
|
|
externalModules.push('ReactDOM');
|
|
}
|
|
}
|
|
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(
|
|
'./packages/shared/src/utils/reactProdInvariant.js'
|
|
),
|
|
};
|
|
}
|
|
|
|
function getFbjsModuleAliases(bundleType) {
|
|
switch (bundleType) {
|
|
case UMD_DEV:
|
|
case 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 NODE_DEV:
|
|
case NODE_PROD:
|
|
case FB_DEV:
|
|
case FB_PROD:
|
|
case RN_DEV:
|
|
case RN_PROD:
|
|
// 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 FB_DEV:
|
|
case FB_PROD:
|
|
// Haste at FB doesn't currently allow case sensitive names,
|
|
// and product code already uses "React". In the future,
|
|
// we will either allow both variants or migrate to lowercase.
|
|
return {
|
|
"'react'": "'React'",
|
|
"'react-dom'": "'ReactDOM'",
|
|
};
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
const devOnlyModuleStub = `'${resolve('./scripts/rollup/shims/rollup/DevOnlyStubShim.js')}'`;
|
|
|
|
function replaceDevOnlyStubbedModules(bundleType) {
|
|
switch (bundleType) {
|
|
case UMD_DEV:
|
|
case NODE_DEV:
|
|
case FB_DEV:
|
|
case RN_DEV:
|
|
case RN_PROD:
|
|
return {};
|
|
case FB_PROD:
|
|
case UMD_PROD:
|
|
case NODE_PROD:
|
|
const devOnlyModuleAliases = {};
|
|
devOnlyFilesToStubOut.forEach(devOnlyModule => {
|
|
devOnlyModuleAliases[devOnlyModule] = devOnlyModuleStub;
|
|
});
|
|
return devOnlyModuleAliases;
|
|
}
|
|
}
|
|
|
|
function replaceLegacyModuleAliases(bundleType) {
|
|
switch (bundleType) {
|
|
case UMD_DEV:
|
|
case UMD_PROD:
|
|
const modulesAlias = {};
|
|
legacyModules.forEach(legacyModule => {
|
|
const modulePath = legacyModule.includes('/')
|
|
? legacyModule
|
|
: `${legacyModule}/index`;
|
|
const resolvedPath = resolve(`./node_modules/${modulePath}`);
|
|
modulesAlias[`'${legacyModule}'`] = `'${resolvedPath}'`;
|
|
});
|
|
return modulesAlias;
|
|
case NODE_DEV:
|
|
case NODE_PROD:
|
|
case FB_DEV:
|
|
case FB_PROD:
|
|
case RN_DEV:
|
|
case RN_PROD:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
function replaceBundleStubModules(bundleModulesToStub) {
|
|
const stubbedModules = {};
|
|
|
|
if (Array.isArray(bundleModulesToStub)) {
|
|
bundleModulesToStub.forEach(module => {
|
|
stubbedModules[`'${module}'`] = devOnlyModuleStub;
|
|
});
|
|
}
|
|
|
|
return stubbedModules;
|
|
}
|
|
|
|
function getAliases(paths, bundleType, moduleType, extractErrors) {
|
|
return Object.assign(
|
|
createModuleMap(
|
|
paths,
|
|
extractErrors && extractErrorCodes(errorCodeOpts),
|
|
bundleType
|
|
),
|
|
getInternalModules(),
|
|
getNodeModules(bundleType, moduleType),
|
|
getFbjsModuleAliases(bundleType)
|
|
);
|
|
}
|
|
|
|
function replaceFeatureFlags(featureFlags) {
|
|
if (!featureFlags) {
|
|
return {};
|
|
}
|
|
return {
|
|
"'ReactFeatureFlags'": `'${resolve(featureFlags)}'`,
|
|
};
|
|
}
|
|
|
|
function getDefaultReplaceModules(
|
|
bundleType,
|
|
bundleModulesToStub,
|
|
featureFlags
|
|
) {
|
|
return Object.assign(
|
|
{},
|
|
replaceFbjsModuleAliases(bundleType),
|
|
replaceDevOnlyStubbedModules(bundleType),
|
|
replaceLegacyModuleAliases(bundleType),
|
|
replaceBundleStubModules(bundleModulesToStub),
|
|
replaceFeatureFlags(featureFlags)
|
|
);
|
|
}
|
|
|
|
function getExcludedHasteGlobs() {
|
|
return exclude;
|
|
}
|
|
|
|
module.exports = {
|
|
getExcludedHasteGlobs,
|
|
getDefaultReplaceModules,
|
|
getAliases,
|
|
ignoreFBModules,
|
|
ignoreReactNativeModules,
|
|
getExternalModules,
|
|
};
|