Skip to content

Commit e5fca60

Browse files
committed
Allow webpack aliases to be defined in an env variable to prevent duplicate React issue (create-react-app#675)
facebook#675 (comment)
1 parent 9af0422 commit e5fca60

File tree

3 files changed

+86
-28
lines changed

3 files changed

+86
-28
lines changed

Diff for: packages/react-scripts/config/getTopLevelModules.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const paths = require('./paths');
5+
6+
const mapDependenciesToFolder = (dependencies, folder) =>
7+
dependencies.reduce(
8+
(accumulator, dependency) =>
9+
Object.assign(
10+
{},
11+
{
12+
[dependency]: path.resolve(folder, dependency),
13+
},
14+
accumulator
15+
),
16+
{}
17+
);
18+
19+
const topLevelModuleNames = () => {
20+
const config = process.env.TOP_LEVEL_MODULES;
21+
if (config) {
22+
if (config.toLowerCase() === 'true') {
23+
// return defaults
24+
return ['react', 'react-dom'];
25+
}
26+
27+
let json;
28+
try {
29+
json = JSON.parse(config);
30+
} catch (e) {
31+
// continue regardless of error
32+
}
33+
34+
if (Array.isArray(json)) {
35+
return json;
36+
} else {
37+
return config;
38+
}
39+
}
40+
};
41+
42+
const getTopLevelModules = () => {
43+
const modulesNames = topLevelModuleNames();
44+
if (modulesNames) {
45+
mapDependenciesToFolder(modulesNames, paths.appNodeModules);
46+
}
47+
return {};
48+
};
49+
50+
module.exports = getTopLevelModules;

Diff for: packages/react-scripts/config/webpack.config.dev.js

+18-14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const eslintFormatter = require('react-dev-utils/eslintFormatter');
1919
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
2020
const getClientEnvironment = require('./env');
2121
const paths = require('./paths');
22+
const getTopLevelModules = require('./getTopLevelModules');
2223

2324
// Webpack uses `publicPath` to determine where the app is being served from.
2425
// In development, we always serve from the root. This makes config easier.
@@ -91,20 +92,23 @@ module.exports = {
9192
// `web` extension prefixes have been added for better support
9293
// for React Native Web.
9394
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
94-
alias: {
95-
// @remove-on-eject-begin
96-
// Resolve Babel runtime relative to react-scripts.
97-
// It usually still works on npm 3 without this but it would be
98-
// unfortunate to rely on, as react-scripts could be symlinked,
99-
// and thus babel-runtime might not be resolvable from the source.
100-
'babel-runtime': path.dirname(
101-
require.resolve('babel-runtime/package.json')
102-
),
103-
// @remove-on-eject-end
104-
// Support React Native Web
105-
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
106-
'react-native': 'react-native-web',
107-
},
95+
alias: Object.assign(
96+
{
97+
// @remove-on-eject-begin
98+
// Resolve Babel runtime relative to react-scripts.
99+
// It usually still works on npm 3 without this but it would be
100+
// unfortunate to rely on, as react-scripts could be symlinked,
101+
// and thus babel-runtime might not be resolvable from the source.
102+
'babel-runtime': path.dirname(
103+
require.resolve('babel-runtime/package.json')
104+
),
105+
// @remove-on-eject-end
106+
// Support React Native Web
107+
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
108+
'react-native': 'react-native-web',
109+
},
110+
getTopLevelModules()
111+
),
108112
plugins: [
109113
// Prevents users from importing files from outside of src/ (or node_modules/).
110114
// This often causes confusion because we only process files within src/ with babel.

Diff for: packages/react-scripts/config/webpack.config.prod.js

+18-14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const eslintFormatter = require('react-dev-utils/eslintFormatter');
2020
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
2121
const paths = require('./paths');
2222
const getClientEnvironment = require('./env');
23+
const getTopLevelModules = require('./getTopLevelModules');
2324

2425
// Webpack uses `publicPath` to determine where the app is being served from.
2526
// It requires a trailing slash, or the file assets will get an incorrect path.
@@ -97,20 +98,23 @@ module.exports = {
9798
// `web` extension prefixes have been added for better support
9899
// for React Native Web.
99100
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
100-
alias: {
101-
// @remove-on-eject-begin
102-
// Resolve Babel runtime relative to react-scripts.
103-
// It usually still works on npm 3 without this but it would be
104-
// unfortunate to rely on, as react-scripts could be symlinked,
105-
// and thus babel-runtime might not be resolvable from the source.
106-
'babel-runtime': path.dirname(
107-
require.resolve('babel-runtime/package.json')
108-
),
109-
// @remove-on-eject-end
110-
// Support React Native Web
111-
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
112-
'react-native': 'react-native-web',
113-
},
101+
alias: Object.assign(
102+
{
103+
// @remove-on-eject-begin
104+
// Resolve Babel runtime relative to react-scripts.
105+
// It usually still works on npm 3 without this but it would be
106+
// unfortunate to rely on, as react-scripts could be symlinked,
107+
// and thus babel-runtime might not be resolvable from the source.
108+
'babel-runtime': path.dirname(
109+
require.resolve('babel-runtime/package.json')
110+
),
111+
// @remove-on-eject-end
112+
// Support React Native Web
113+
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
114+
'react-native': 'react-native-web',
115+
},
116+
getTopLevelModules()
117+
),
114118
plugins: [
115119
// Prevents users from importing files from outside of src/ (or node_modules/).
116120
// This often causes confusion because we only process files within src/ with babel.

0 commit comments

Comments
 (0)