-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
122 lines (102 loc) · 3.71 KB
/
index.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
const regexDoc = /pages[\\/]_document\./
const regexLikeCss = /\.(css|scss|sass)$/
const regexMoreLikeCss = /\.(css|scss|sass|styl|less)$/
const regexCssGlobal = /(?<!\.module)\.css$/
const regexCssModules = /\.module\.css$/
const regexSassGlobal = /(?<!\.module)\.(scss|sass)$/
const regexSassModules = /\.module\.(scss|sass)$/
const regexStylusGlobal = /(?<!\.module)\.styl$/
const regexStylusModules = /\.module\.styl$/
const regexLessGlobal = /(?<!\.module)\.less$/
const regexLessModules = /\.module\.less$/
const ammendOneOfRules = config => (a, c) => {
const { context: ctx, stylusOptions, lessOptions} = config
const stylusLoader = {
loader: 'stylus-loader',
options: { sourceMap: true, stylusOptions }
}
const lessLoader = {
loader: 'less-loader',
options: { sourceMap: true, lessOptions}
}
const matchesRegExpTest = 'test' in c
&& c.test instanceof RegExp
&& c.test.source
const matchesRegExpIssuer = 'issuer' in c
&& c.issuer instanceof RegExp
&& c.issuer.source
const regStrArr = a => a
.map(t => `${t instanceof RegExp ? 'r' : 's'}>>${t}`)
.sort()
.join()
const matchArray = a => b => regStrArr(a) === regStrArr(b)
const testAccepts = ('test' in c
&& Array.isArray(c.test)
&& matchArray(c.test)
|| (() => false))
const issuerAccepts = ('issuer' in c
&& 'and' in c.issuer
&& Array.isArray(c.issuer.and)
&& matchArray(c.issuer.and)
|| (() => false))
const issuerAvoids = ('issuer' in c
&& 'not' in c.issuer
&& Array.isArray(c.issuer.not)
&& matchArray(c.issuer.not)
|| (() => false))
if (matchesRegExpTest === regexLikeCss.source && matchesRegExpIssuer === regexDoc.source) {
c = [{ ...c, test: regexMoreLikeCss }]
return [].concat(a, c)
}
if (matchesRegExpTest === regexSassModules.source && issuerAccepts([ctx]) && issuerAvoids([/node_modules/])) {
c = [ c,
{ ...c, test: regexStylusModules, use: [].concat(...c.use.slice(0, -1), stylusLoader) },
{ ...c, test: regexLessModules, use: [].concat(...c.use.slice(0, -1), lessLoader) },
]
return [].concat(a, c)
}
if (testAccepts([regexCssModules, regexSassModules])) {
c = [{ ...c, test: [].concat(c.test, regexStylusModules, regexLessModules) }]
return [].concat(a, c)
}
// A bit of a hacky way to check custom _App file ... but async/promise isn't allowed in NextJS configs so yeah.
if (matchesRegExpTest === regexSassGlobal.source && issuerAccepts([ c.issuer && c.issuer.and && /_app\./.test(c.issuer.and.join()) && c.issuer.and ])) {
c = [ c,
{ ...c, test: regexStylusGlobal, use: [].concat(...c.use.slice(0, -1), stylusLoader) },
{ ...c, test: regexLessGlobal, use: [].concat(...c.use.slice(0, -1), lessLoader) },
]
return [].concat(a, c)
}
if (testAccepts([regexCssGlobal, regexSassGlobal]) && issuerAccepts([/node_modules/])) {
c = [{ ...c, test: [].concat(c.test, regexStylusGlobal, regexLessGlobal) }]
return [].concat(a, c)
}
if (testAccepts([regexCssGlobal, regexSassGlobal])) {
c = [{ ...c, test: [].concat(c.test, regexStylusGlobal, regexLessGlobal) }]
return [].concat(a, c)
}
if (matchesRegExpIssuer === regexLikeCss.source) {
c = [{ ...c, issuer: regexMoreLikeCss }]
return [].concat(a, c)
}
return [].concat(a, c)
}
module.exports = (nextConfig = {}) => ({
...nextConfig,
webpack(config, options) {
const rules = config.module.rules.map(rule => 'oneOf' in rule
? ({ ...rule, oneOf: rule.oneOf.reduce(ammendOneOfRules(config)) })
: rule
)
config.module.rules = rules
if (typeof nextConfig.webpack === 'function') {
config = nextConfig.webpack(config, options)
}
return config
},
webpackDevMiddleware(config, options) {
if (typeof nextConfig.webpackDevMiddleware === 'function')
config = nextConfig.webpackDevMiddleware(config, options)
return config
}
})