Skip to content

Commit cd704af

Browse files
committed
Update webpack config to use real create-react-app 2.0 SASS config
1 parent c6e7aaa commit cd704af

File tree

2 files changed

+167
-172
lines changed

2 files changed

+167
-172
lines changed

packages/react-scripts/config/webpack.config.dev.js

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,47 @@ const publicUrl = '';
3131
// Get environment variables to inject into our app.
3232
const env = getClientEnvironment(publicUrl);
3333

34+
// style files regexes
35+
const cssRegex = /\.css$/;
36+
const cssModuleRegex = /\.module\.css$/;
37+
const sassRegex = /\.(scss|sass)$/;
38+
const sassModuleRegex = /\.module\.(scss|sass)$/;
39+
40+
// common function to get style loaders
41+
const getStyleLoaders = (cssOptions, preProcessor) => {
42+
const loaders = [
43+
require.resolve('style-loader'),
44+
{
45+
loader: require.resolve('css-loader'),
46+
options: cssOptions,
47+
},
48+
{
49+
// Options for PostCSS as we reference these options twice
50+
// Adds vendor prefixing based on your specified browser support in
51+
// package.json
52+
loader: require.resolve('postcss-loader'),
53+
options: {
54+
// Necessary for external CSS imports to work
55+
// https://github.com/facebook/create-react-app/issues/2677
56+
ident: 'postcss',
57+
plugins: () => [
58+
require('postcss-flexbugs-fixes'),
59+
require('postcss-preset-env')({
60+
autoprefixer: {
61+
flexbox: 'no-2009',
62+
},
63+
stage: 3,
64+
}),
65+
],
66+
},
67+
},
68+
];
69+
if (preProcessor) {
70+
loaders.push(require.resolve(preProcessor));
71+
}
72+
return loaders;
73+
};
74+
3475
// This is the development configuration.
3576
// It is focused on developer experience and fast rebuilds.
3677
// The production configuration is different and lives in a separate file.
@@ -188,76 +229,46 @@ module.exports = {
188229
// "style" loader turns CSS into JS modules that inject <style> tags.
189230
// In production, we use a plugin to extract that CSS to a file, but
190231
// in development "style" loader enables hot editing of CSS.
191-
// SASS/SCSS supported.
232+
// By default we support CSS Modules with the extension .module.css
192233
{
193-
test: /\.css$/,
194-
use: [
195-
require.resolve('style-loader'),
196-
{
197-
loader: require.resolve('css-loader'),
198-
options: {
199-
importLoaders: 1,
200-
},
201-
},
202-
{
203-
loader: require.resolve('postcss-loader'),
204-
options: {
205-
// Necessary for external CSS imports to work
206-
// https://github.com/facebookincubator/create-react-app/issues/2677
207-
ident: 'postcss',
208-
plugins: () => [
209-
require('postcss-flexbugs-fixes'),
210-
autoprefixer({
211-
browsers: [
212-
'>1%',
213-
'last 4 versions',
214-
'Firefox ESR',
215-
'not ie < 9', // React doesn't support IE8 anyway
216-
],
217-
flexbox: 'no-2009',
218-
}),
219-
],
220-
},
221-
},
222-
],
234+
test: cssRegex,
235+
exclude: cssModuleRegex,
236+
use: getStyleLoaders({
237+
importLoaders: 1,
238+
}),
223239
},
240+
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
241+
// using the extension .module.css
224242
{
225-
test: /\.scss$/,
226-
use: [
227-
require.resolve('style-loader'),
228-
{
229-
loader: require.resolve('css-loader'),
230-
options: {
231-
importLoaders: 1,
232-
},
233-
},
234-
{
235-
loader: require.resolve('postcss-loader'),
236-
options: {
237-
// Necessary for external CSS imports to work
238-
// https://github.com/facebookincubator/create-react-app/issues/2677
239-
ident: 'postcss',
240-
plugins: () => [
241-
require('postcss-flexbugs-fixes'),
242-
autoprefixer({
243-
browsers: [
244-
'>1%',
245-
'last 4 versions',
246-
'Firefox ESR',
247-
'not ie < 9', // React doesn't support IE8 anyway
248-
],
249-
flexbox: 'no-2009',
250-
}),
251-
],
252-
},
253-
},
243+
test: cssModuleRegex,
244+
use: getStyleLoaders({
245+
importLoaders: 1,
246+
modules: true,
247+
getLocalIdent: getCSSModuleLocalIdent,
248+
}),
249+
},
250+
// Opt-in support for SASS (using .scss or .sass extensions).
251+
// Chains the sass-loader with the css-loader and the style-loader
252+
// to immediately apply all styles to the DOM.
253+
// By default we support SASS Modules with the
254+
// extensions .module.scss or .module.sass
255+
{
256+
test: sassRegex,
257+
exclude: sassModuleRegex,
258+
use: getStyleLoaders({ importLoaders: 2 }, 'sass-loader'),
259+
},
260+
// Adds support for CSS Modules, but using SASS
261+
// using the extension .module.scss or .module.sass
262+
{
263+
test: sassModuleRegex,
264+
use: getStyleLoaders(
254265
{
255-
loader: require.resolve('sass-loader'),
256-
options: {
257-
importLoaders: 1,
258-
},
266+
importLoaders: 2,
267+
modules: true,
268+
getLocalIdent: getCSSModuleLocalIdent,
259269
},
260-
],
270+
'sass-loader'
271+
),
261272
},
262273
// "file" loader makes sure those assets get served by WebpackDevServer.
263274
// When you `import` an asset, you get its (virtual) filename.

packages/react-scripts/config/webpack.config.prod.js

Lines changed: 91 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,51 @@ if (env.stringified['process.env'].NODE_ENV !== '"production"') {
4444
throw new Error('Production builds must have NODE_ENV=production.');
4545
}
4646

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 = /\.css$/;
49+
const cssModuleRegex = /\.module\.css$/;
50+
const sassRegex = /\.(scss|sass)$/;
51+
const sassModuleRegex = /\.module\.(scss|sass)$/;// 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+
};
4992

5093
// ExtractTextPlugin expects the build output to be flat.
5194
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
@@ -188,118 +231,59 @@ module.exports = {
188231
},
189232
],
190233
},
191-
// The notation here is somewhat confusing.
192234
// "postcss" loader applies autoprefixer to our CSS.
193235
// "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
204239
{
205-
test: /\.css$/,
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'
248272
),
249-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
250273
},
274+
// Adds support for CSS Modules, but using SASS
275+
// using the extension .module.scss or .module.sass
251276
{
252-
test: /\.scss$/,
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'
301286
),
302-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
303287
},
304288
// "file" loader makes sure assets end up in the `build` folder.
305289
// When you `import` an asset, you get its filename.

0 commit comments

Comments
 (0)