-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig-overrides.js
130 lines (99 loc) · 3.06 KB
/
config-overrides.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
'use strict';
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const { loaderNameMatches } = require('react-app-rewired');
module.exports = (config, env) => {
const envIsProd = env === 'production';
config = rewireSass(config, envIsProd);
return config;
};
const rewireSass = (config, envIsProd) => {
/*
* Build style-loader rules
*/
// Find current index & rules
let styleIndexAndRules = findIndexAndRules(config.module.rules, rule => {
return String(rule.test) === String(/\.css$/);
});
// Find the exact loader
let styleLoader = !envIsProd
? styleIndexAndRules.rules[styleIndexAndRules.index].use[0]
: findRule(styleIndexAndRules.rules[styleIndexAndRules.index], rule => loaderNameMatches(rule, 'style-loader'))
.loader;
// Build new rules
let styleRules = {
loader: styleLoader,
options: {
hmr: !envIsProd
}
};
/*
* Build css-loader rules
*/
// Find current rules
let cssRules = findRule(config.module.rules, rule => loaderNameMatches(rule, 'css-loader'));
// Append options
Object.assign(cssRules.options, {
importLoaders: 2,
minimize: envIsProd,
sourceMap: !envIsProd
});
/*
* Build css-loader rules
*/
// Find current rules
let postcssRules = findRule(config.module.rules, rule => loaderNameMatches(rule, 'postcss-loader'));
// Append options
Object.assign(postcssRules.options, {
sourceMap: !envIsProd
});
/*
* Build css-loader rules
*/
let sassRules = {
loader: path.resolve(__dirname, 'node_modules/sass-loader/lib/loader.js'),
options: {
sourceMap: !envIsProd
}
};
/*
* Add chain of loader-rules
*/
// Build chain for development
let sassChainDev = {
test: /(\.scss|\.sass)$/,
use: [styleRules, cssRules, postcssRules, sassRules]
};
// Build chain for production
let sassChainProd = {
test: /(\.scss|\.sass)$/,
use: ExtractTextPlugin.extract({
fallback: styleRules,
use: [cssRules, postcssRules, sassRules]
})
};
// Replace style-loader rules with the correct chain
styleIndexAndRules.rules.splice(styleIndexAndRules.index, 1, envIsProd ? sassChainProd : sassChainDev);
// Exclude SASS from the wildcard rules
let fileRule = findRule(config.module.rules, rule => {
return Boolean(rule.exclude);
});
fileRule.exclude.push(/(\.scss|\.sass)$/);
return config;
};
const findRule = (rules, matcher) => {
let indexAndRules = findIndexAndRules(rules, matcher);
return indexAndRules.found ? indexAndRules.rules[indexAndRules.index] : undefined;
};
const findIndexAndRules = (rules, matcher) => {
let indexAndRules = { found: false };
rules = Array.isArray(rules) ? rules : findChildren(rules);
rules.some((rule, index) => {
indexAndRules = matcher(rule) ? { found: true, index, rules } : findIndexAndRules(findChildren(rule), matcher);
return indexAndRules.found;
});
return indexAndRules;
};
const findChildren = rule => {
return rule.use || rule.oneOf || (Array.isArray(rule.loader) && rule.loader) || [];
};