@@ -44,8 +44,51 @@ if (env.stringified['process.env'].NODE_ENV !== '"production"') {
44
44
throw new Error ( 'Production builds must have NODE_ENV=production.' ) ;
45
45
}
46
46
47
- // Note: defined here because it will be used more than once.
48
- const cssFilename = 'static/css/[name].[contenthash:8].css' ;
47
+ // style files regexes
48
+ const cssRegex = / \. c s s $ / ;
49
+ const cssModuleRegex = / \. m o d u l e \. c s s $ / ;
50
+ const sassRegex = / \. ( s c s s | s a s s ) $ / ;
51
+ const sassModuleRegex = / \. m o d u l e \. ( s c s s | s a s s ) $ / ; // common function to get style loaders
52
+
53
+ const getStyleLoaders = ( cssOptions , preProcessor ) => {
54
+ const loaders = [
55
+ MiniCssExtractPlugin . loader ,
56
+ {
57
+ loader : require . resolve ( 'css-loader' ) ,
58
+ options : cssOptions ,
59
+ } ,
60
+ {
61
+ // Options for PostCSS as we reference these options twice
62
+ // Adds vendor prefixing based on your specified browser support in
63
+ // package.json
64
+ loader : require . resolve ( 'postcss-loader' ) ,
65
+ options : {
66
+ // Necessary for external CSS imports to work
67
+ // https://github.com/facebook/create-react-app/issues/2677
68
+ ident : 'postcss' ,
69
+ plugins : ( ) => [
70
+ require ( 'postcss-flexbugs-fixes' ) ,
71
+ require ( 'postcss-preset-env' ) ( {
72
+ autoprefixer : {
73
+ flexbox : 'no-2009' ,
74
+ } ,
75
+ stage : 3 ,
76
+ } ) ,
77
+ ] ,
78
+ sourceMap : shouldUseSourceMap ,
79
+ } ,
80
+ } ,
81
+ ] ;
82
+ if ( preProcessor ) {
83
+ loaders . push ( {
84
+ loader : require . resolve ( preProcessor ) ,
85
+ options : {
86
+ sourceMap : shouldUseSourceMap ,
87
+ } ,
88
+ } ) ;
89
+ }
90
+ return loaders ;
91
+ } ;
49
92
50
93
// ExtractTextPlugin expects the build output to be flat.
51
94
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
@@ -188,118 +231,59 @@ module.exports = {
188
231
} ,
189
232
] ,
190
233
} ,
191
- // The notation here is somewhat confusing.
192
234
// "postcss" loader applies autoprefixer to our CSS.
193
235
// "css" loader resolves paths in CSS and adds assets as dependencies.
194
- // "style" loader normally turns CSS into JS modules injecting <style>,
195
- // but unlike in development configuration, we do something different.
196
- // `ExtractTextPlugin` first applies the "postcss" and "css" loaders
197
- // (second argument), then grabs the result CSS and puts it into a
198
- // separate file in our build process. This way we actually ship
199
- // a single CSS file in production instead of JS code injecting <style>
200
- // tags. If you use code splitting, however, any async bundles will still
201
- // use the "style" loader inside the async code so CSS from them won't be
202
- // in the main CSS file.
203
- // SASS/SCSS supported.
236
+ // `MiniCSSExtractPlugin` extracts styles into CSS
237
+ // files. If you use code splitting, async bundles will have their own separate CSS chunk file.
238
+ // By default we support CSS Modules with the extension .module.css
204
239
{
205
- test : / \. c s s $ / ,
206
- loader : ExtractTextPlugin . extract (
207
- Object . assign (
208
- {
209
- fallback : {
210
- loader : require . resolve ( 'style-loader' ) ,
211
- options : {
212
- hmr : false ,
213
- } ,
214
- } ,
215
- use : [
216
- {
217
- loader : require . resolve ( 'css-loader' ) ,
218
- options : {
219
- importLoaders : 1 ,
220
- minimize : true ,
221
- sourceMap : shouldUseSourceMap ,
222
- } ,
223
- } ,
224
- {
225
- loader : require . resolve ( 'postcss-loader' ) ,
226
- options : {
227
- // Necessary for external CSS imports to work
228
- // https://github.com/facebookincubator/create-react-app/issues/2677
229
- ident : 'postcss' ,
230
- plugins : ( ) => [
231
- require ( 'postcss-flexbugs-fixes' ) ,
232
- autoprefixer ( {
233
- browsers : [
234
- '>1%' ,
235
- 'last 4 versions' ,
236
- 'Firefox ESR' ,
237
- 'not ie < 9' , // React doesn't support IE8 anyway
238
- ] ,
239
- flexbox : 'no-2009' ,
240
- } ) ,
241
- ] ,
242
- } ,
243
- } ,
244
- ] ,
245
- } ,
246
- extractTextPluginOptions
247
- )
240
+ test : cssRegex ,
241
+ exclude : cssModuleRegex ,
242
+ loader : getStyleLoaders ( {
243
+ importLoaders : 1 ,
244
+ sourceMap : shouldUseSourceMap ,
245
+ } ) ,
246
+ } ,
247
+ // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
248
+ // using the extension .module.css
249
+ {
250
+ test : cssModuleRegex ,
251
+ loader : getStyleLoaders ( {
252
+ importLoaders : 1 ,
253
+ sourceMap : shouldUseSourceMap ,
254
+ modules : true ,
255
+ getLocalIdent : getCSSModuleLocalIdent ,
256
+ } ) ,
257
+ } ,
258
+ // Opt-in support for SASS. The logic here is somewhat similar
259
+ // as in the CSS routine, except that "sass-loader" runs first
260
+ // to compile SASS files into CSS.
261
+ // By default we support SASS Modules with the
262
+ // extensions .module.scss or .module.sass
263
+ {
264
+ test : sassRegex ,
265
+ exclude : sassModuleRegex ,
266
+ loader : getStyleLoaders (
267
+ {
268
+ importLoaders : 2 ,
269
+ sourceMap : shouldUseSourceMap ,
270
+ } ,
271
+ 'sass-loader'
248
272
) ,
249
- // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
250
273
} ,
274
+ // Adds support for CSS Modules, but using SASS
275
+ // using the extension .module.scss or .module.sass
251
276
{
252
- test : / \. s c s s $ / ,
253
- loader : ExtractTextPlugin . extract (
254
- Object . assign (
255
- {
256
- fallback : {
257
- loader : require . resolve ( 'style-loader' ) ,
258
- options : {
259
- hmr : false ,
260
- } ,
261
- } ,
262
- use : [
263
- {
264
- loader : require . resolve ( 'css-loader' ) ,
265
- options : {
266
- importLoaders : 1 ,
267
- minimize : true ,
268
- sourceMap : shouldUseSourceMap ,
269
- } ,
270
- } ,
271
- {
272
- loader : require . resolve ( 'postcss-loader' ) ,
273
- options : {
274
- // Necessary for external CSS imports to work
275
- // https://github.com/facebookincubator/create-react-app/issues/2677
276
- ident : 'postcss' ,
277
- plugins : ( ) => [
278
- require ( 'postcss-flexbugs-fixes' ) ,
279
- autoprefixer ( {
280
- browsers : [
281
- '>1%' ,
282
- 'last 4 versions' ,
283
- 'Firefox ESR' ,
284
- 'not ie < 9' , // React doesn't support IE8 anyway
285
- ] ,
286
- flexbox : 'no-2009' ,
287
- } ) ,
288
- ] ,
289
- } ,
290
- } ,
291
- {
292
- loader : require . resolve ( 'sass-loader' ) ,
293
- options : {
294
- importLoaders : 1 ,
295
- } ,
296
- } ,
297
- ] ,
298
- } ,
299
- extractTextPluginOptions
300
- )
277
+ test : sassModuleRegex ,
278
+ loader : getStyleLoaders (
279
+ {
280
+ importLoaders : 2 ,
281
+ sourceMap : shouldUseSourceMap ,
282
+ modules : true ,
283
+ getLocalIdent : getCSSModuleLocalIdent ,
284
+ } ,
285
+ 'sass-loader'
301
286
) ,
302
- // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
303
287
} ,
304
288
// "file" loader makes sure assets end up in the `build` folder.
305
289
// When you `import` an asset, you get its filename.
0 commit comments