-
-
Notifications
You must be signed in to change notification settings - Fork 9.2k
/
cra_config.js
85 lines (72 loc) · 2.78 KB
/
cra_config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import semver from 'semver';
import { normalizeCondition } from 'webpack/lib/RuleSet';
export function isReactScriptsInstalled() {
try {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
const reactScriptsJson = require('react-scripts/package.json');
if (semver.lt(reactScriptsJson.version, '2.0.0')) return false;
return true;
} catch (e) {
return false;
}
}
export function getStyleRules(rules) {
// Extensions of style rules we're interested in
const extensions = ['.css', '.scss', '.sass', '.module.css', '.module.scss', '.module.sass'];
return rules.reduce((styleRules, rule) => {
// If at least one style extension satisfies the rule test, the rule is one
// we want to extract
if (rule.test && extensions.some(normalizeCondition(rule.test))) {
// If the base test is for styles, return early
return styleRules.concat(rule);
}
// Get any style rules contained in rule.oneOf
if (!rule.test && rule.oneOf) {
styleRules.push(...getStyleRules(rule.oneOf));
}
// Get any style rules contained in rule.rules
if (!rule.test && rule.rules) {
styleRules.push(...getStyleRules(rule.rules));
}
return styleRules;
}, []);
}
export function getCraWebpackConfig(mode) {
if (mode === 'production') {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
return require('react-scripts/config/webpack.config.prod');
}
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
return require('react-scripts/config/webpack.config.dev');
}
export function applyCRAWebpackConfig(baseConfig) {
// Remove any rules from baseConfig that test true for any one of the extensions
const baseRulesExcludingStyles = baseConfig.module.rules.filter(
rule => !rule.test || !['.css', '.scss', '.sass'].some(normalizeCondition(rule.test))
);
// Load create-react-app config
const craWebpackConfig = getCraWebpackConfig(baseConfig.mode);
const craStyleRules = getStyleRules(craWebpackConfig.module.rules);
// Add css minification for production
const plugins = [...baseConfig.plugins];
if (baseConfig.mode === 'production') {
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins.push(
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
})
);
}
return {
...baseConfig,
module: {
...baseConfig.module,
rules: [...baseRulesExcludingStyles, ...craStyleRules],
},
plugins,
};
}