webpack.config.dev.js 16.3 KB
Newer Older
1
// @remove-on-eject-begin
Christopher Chedeau's avatar
Christopher Chedeau committed
2
3
4
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
Sophie Alpert's avatar
Sophie Alpert committed
5
6
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
Christopher Chedeau's avatar
Christopher Chedeau committed
7
 */
8
// @remove-on-eject-end
9
'use strict';
Christopher Chedeau's avatar
Christopher Chedeau committed
10

11
const autoprefixer = require('autoprefixer');
Joe Haddad's avatar
Joe Haddad committed
12
const path = require('path');
13
14
15
16
17
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
18
const eslintFormatter = require('react-dev-utils/eslintFormatter');
Joe Haddad's avatar
Joe Haddad committed
19
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
20
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
21
22
const getClientEnvironment = require('./env');
const paths = require('./paths');
23
24
25

// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
26
const publicPath = '/';
27
28
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
Brian Ng's avatar
Brian Ng committed
29
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
30
const publicUrl = '';
31
// Get environment variables to inject into our app.
32
const env = getClientEnvironment(publicUrl);
33

34
// Options for PostCSS as we reference these options twice
Joe Haddad's avatar
Joe Haddad committed
35
36
// Adds vendor prefixing based on your specified browser support in
// package.json
37
38
const postCSSLoaderOptions = {
  // Necessary for external CSS imports to work
39
  // https://github.com/facebook/create-react-app/issues/2677
40
41
42
43
44
45
46
47
48
  ident: 'postcss',
  plugins: () => [
    require('postcss-flexbugs-fixes'),
    autoprefixer({
      flexbox: 'no-2009',
    }),
  ],
};

Fabiano Brito's avatar
Fabiano Brito committed
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
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;

// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
  const loaders = [
    require.resolve('style-loader'),
    {
      loader: require.resolve('css-loader'),
      options: cssOptions,
    },
    {
      loader: require.resolve('postcss-loader'),
      options: postCSSLoaderOptions,
    },
  ];
  if (preProcessor) {
    loaders.push(require.resolve(preProcessor));
  }
  return loaders;
};

74
75
76
// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
// The production configuration is different and lives in a separate file.
Dan Abramov's avatar
Dan Abramov committed
77
module.exports = {
78
  // You may want 'eval' instead if you prefer to see the compiled output in DevTools.
79
  // See the discussion in https://github.com/facebook/create-react-app/issues/343.
80
  devtool: 'cheap-module-source-map',
81
82
83
  // These are the "entry points" to our application.
  // This means they will be the "root" imports that are included in JS bundle.
  // The first two entry points enable "hot" CSS and auto-refreshes for JS.
84
  entry: [
85
86
    // We ship a few polyfills by default:
    require.resolve('./polyfills'),
87
88
89
90
91
92
93
94
95
96
97
    // Include an alternative client for WebpackDevServer. A client's job is to
    // connect to WebpackDevServer by a socket and get notified about changes.
    // When you save a file, the client will either apply hot updates (in case
    // of CSS changes), or refresh the page (in case of JS changes). When you
    // make a syntax error, this client will display a syntax error overlay.
    // Note: instead of the default WebpackDevServer client, we use a custom one
    // to bring better experience for Create React App users. You can replace
    // the line below with these two lines if you prefer the stock client:
    // require.resolve('webpack-dev-server/client') + '?/',
    // require.resolve('webpack/hot/dev-server'),
    require.resolve('react-dev-utils/webpackHotDevClient'),
98
    // Finally, this is your app's code:
99
    paths.appIndexJs,
100
101
102
    // We include the app code last so that if there is a runtime error during
    // initialization, it doesn't blow up the WebpackDevServer client, and
    // changing JS code would still trigger a refresh.
103
  ],
Dan Abramov's avatar
Dan Abramov committed
104
  output: {
105
    // Add /* filename */ comments to generated require()s in the output.
Dan Abramov's avatar
Dan Abramov committed
106
    pathinfo: true,
107
108
109
    // This does not produce a real file. It's just the virtual path that is
    // served by WebpackDevServer in development. This is the JS bundle
    // containing code from all our entry points, and the Webpack runtime.
110
    filename: 'static/js/bundle.js',
111
112
    // There are also additional JS chunk files if you use code splitting.
    chunkFilename: 'static/js/[name].chunk.js',
113
    // This is the URL that app is served from. We use "/" in development.
114
    publicPath: publicPath,
115
    // Point sourcemap entries to original disk location (format as URL on Windows)
Joe Haddad's avatar
Joe Haddad committed
116
    devtoolModuleFilenameTemplate: info =>
117
      path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
Dan Abramov's avatar
Dan Abramov committed
118
  },
119
  resolve: {
Dan Abramov's avatar
Dan Abramov committed
120
    // This allows you to set a fallback for where Webpack should look for modules.
Joe Haddad's avatar
Joe Haddad committed
121
122
    // We placed these paths second because we want `node_modules` to "win"
    // if there are any conflicts. This matches Node resolution mechanism.
123
    // https://github.com/facebook/create-react-app/issues/253
124
    modules: ['node_modules'].concat(
125
      // It is guaranteed to exist because we tweak it in `env.js`
126
      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
127
    ),
128
    // These are the reasonable defaults supported by the Node ecosystem.
129
130
    // We also include JSX as a common component filename extension to support
    // some tools, although we do not recommend using it, see:
131
    // https://github.com/facebook/create-react-app/issues/290
132
133
    // `web` extension prefixes have been added for better support
    // for React Native Web.
Joe Haddad's avatar
Joe Haddad committed
134
    extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
135
    alias: {
136
137
138
139
      // @remove-on-eject-begin
      // Resolve Babel runtime relative to react-scripts.
      // It usually still works on npm 3 without this but it would be
      // unfortunate to rely on, as react-scripts could be symlinked,
Clement Hoang's avatar
Clement Hoang committed
140
141
142
      // and thus @babel/runtime might not be resolvable from the source.
      '@babel/runtime': path.dirname(
        require.resolve('@babel/runtime/package.json')
143
144
      ),
      // @remove-on-eject-end
145
146
      // Support React Native Web
      // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
147
148
      'react-native': 'react-native-web',
    },
Joe Haddad's avatar
Joe Haddad committed
149
150
151
152
153
154
    plugins: [
      // Prevents users from importing files from outside of src/ (or node_modules/).
      // This often causes confusion because we only process files within src/ with babel.
      // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
      // please link the files into your node_modules/ and let module-resolution kick in.
      // Make sure your source files are compiled, as they will not be processed in any way.
155
      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
Joe Haddad's avatar
Joe Haddad committed
156
    ],
157
  },
Dan Abramov's avatar
Dan Abramov committed
158
  module: {
159
    strictExportPresence: true,
Joe Haddad's avatar
Joe Haddad committed
160
    rules: [
161
162
      // Disable require.ensure as it's not a standard language feature.
      { parser: { requireEnsure: false } },
Dan Abramov's avatar
Dan Abramov committed
163

Joe Haddad's avatar
Joe Haddad committed
164
165
      // First, run the linter.
      // It's important to do this before Babel processes the JS.
Dan Abramov's avatar
Dan Abramov committed
166
      {
Joe Haddad's avatar
Joe Haddad committed
167
        test: /\.(js|jsx|mjs)$/,
Joe Haddad's avatar
Joe Haddad committed
168
        enforce: 'pre',
169
170
171
        use: [
          {
            options: {
172
              formatter: eslintFormatter,
Đinh Quang Trung's avatar
Đinh Quang Trung committed
173
              eslintPath: require.resolve('eslint'),
174
              baseConfig: {
175
                extends: [require.resolve('eslint-config-react-app')],
176
              },
177
              // @remove-on-eject-begin
178
              ignore: false,
179
              useEslintrc: false,
180
              // @remove-on-eject-end
181
            },
182
            loader: require.resolve('eslint-loader'),
Joe Haddad's avatar
Joe Haddad committed
183
          },
184
        ],
185
186
        include: paths.srcPaths,
        exclude: [/[/\\\\]node_modules[/\\\\]/],
Joe Haddad's avatar
Joe Haddad committed
187
      },
Dan Abramov's avatar
Dan Abramov committed
188
      {
189
190
191
192
193
194
195
        // "oneOf" will traverse all following loaders until one will
        // match the requirements. When no loader matches it will fall
        // back to the "file" loader at the end of the loader list.
        oneOf: [
          // "url" loader works like "file" loader except that it embeds assets
          // smaller than specified limit in bytes as data URLs to avoid requests.
          // A missing `test` is equivalent to a match.
196
          {
197
198
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: require.resolve('url-loader'),
Joe Haddad's avatar
Joe Haddad committed
199
            options: {
200
201
              limit: 10000,
              name: 'static/media/[name].[hash:8].[ext]',
202
203
            },
          },
204
205
          // Process application JS with Babel.
          // The preset includes JSX, Flow, and some ESnext features.
206
          {
Joe Haddad's avatar
Joe Haddad committed
207
            test: /\.(js|jsx|mjs)$/,
208
209
            include: paths.srcPaths,
            exclude: [/[/\\\\]node_modules[/\\\\]/],
210
211
212
213
214
215
216
217
218
219
            use: [
              // This loader parallelizes code compilation, it is optional but
              // improves compile time on larger projects
              require.resolve('thread-loader'),
              {
                loader: require.resolve('babel-loader'),
                options: {
                  // @remove-on-eject-begin
                  babelrc: false,
                  // @remove-on-eject-end
220
                  presets: [require.resolve('babel-preset-react-app')],
221
222
223
224
225
226
227
228
229
230
231
232
                  plugins: [
                    [
                      require.resolve('babel-plugin-named-asset-import'),
                      {
                        loaderMap: {
                          svg: {
                            ReactComponent: 'svgr/webpack![path]',
                          },
                        },
                      },
                    ],
                  ],
233
234
235
236
                  // This is a feature of `babel-loader` for webpack (not Babel itself).
                  // It enables caching results in ./node_modules/.cache/babel-loader/
                  // directory for faster rebuilds.
                  cacheDirectory: true,
237
                  highlightCode: true,
238
239
240
                },
              },
            ],
241
          },
242
243
244
245
          // Process any JS outside of the app with Babel.
          // Unlike the application JS, we only compile the standard ES features.
          {
            test: /\.js$/,
246
247
248
249
250
251
252
253
254
255
256
257
258
            use: [
              // This loader parallelizes code compilation, it is optional but
              // improves compile time on larger projects
              require.resolve('thread-loader'),
              {
                loader: require.resolve('babel-loader'),
                options: {
                  babelrc: false,
                  compact: false,
                  presets: [
                    require.resolve('babel-preset-react-app/dependencies'),
                  ],
                  cacheDirectory: true,
259
                  highlightCode: true,
260
261
262
                },
              },
            ],
263
          },
264
265
266
267
268
          // "postcss" loader applies autoprefixer to our CSS.
          // "css" loader resolves paths in CSS and adds assets as dependencies.
          // "style" loader turns CSS into JS modules that inject <style> tags.
          // In production, we use a plugin to extract that CSS to a file, but
          // in development "style" loader enables hot editing of CSS.
269
          // By default we support CSS Modules with the extension .module.css
270
          {
Fabiano Brito's avatar
Fabiano Brito committed
271
272
273
274
275
            test: cssRegex,
            exclude: cssModuleRegex,
            use: getStyleLoaders({
              importLoaders: 1,
            }),
276
277
278
279
          },
          // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
          // using the extension .module.css
          {
Fabiano Brito's avatar
Fabiano Brito committed
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
            test: cssModuleRegex,
            use: getStyleLoaders({
              importLoaders: 1,
              modules: true,
              getLocalIdent: getCSSModuleLocalIdent,
            }),
          },
          // Opt-in support for SASS (using .scss or .sass extensions).
          // Chains the sass-loader with the css-loader and the style-loader
          // to immediately apply all styles to the DOM.
          // By default we support SASS Modules with the
          // extensions .module.scss or .module.sass
          {
            test: sassRegex,
            exclude: sassModuleRegex,
            use: getStyleLoaders({ importLoaders: 2 }, 'sass-loader'),
          },
          // Adds support for CSS Modules, but using SASS
          // using the extension .module.scss or .module.sass
          {
            test: sassModuleRegex,
            use: getStyleLoaders(
302
              {
Fabiano Brito's avatar
Fabiano Brito committed
303
304
305
                importLoaders: 2,
                modules: true,
                getLocalIdent: getCSSModuleLocalIdent,
306
              },
Fabiano Brito's avatar
Fabiano Brito committed
307
308
              'sass-loader'
            ),
309
          },
310
311
312
313
314
          // The GraphQL loader preprocesses GraphQL queries in .graphql files.
          {
            test: /\.(graphql)$/,
            loader: 'graphql-tag/loader',
          },
315
316
317
          // "file" loader makes sure those assets get served by WebpackDevServer.
          // When you `import` an asset, you get its (virtual) filename.
          // In production, they would get copied to the `build` folder.
318
          // This loader doesn't use a "test" so it will catch all modules
319
320
321
          // that fall through the other loaders.
          {
            // Exclude `js` files to keep "css" loader working as it injects
322
            // its runtime that would otherwise be processed through "file" loader.
323
324
            // Also exclude `html` and `json` extensions so they get processed
            // by webpacks internal loaders.
325
            exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
326
327
328
            loader: require.resolve('file-loader'),
            options: {
              name: 'static/media/[name].[hash:8].[ext]',
329
330
331
332
            },
          },
        ],
      },
333
      // ** STOP ** Are you adding a new loader?
334
      // Make sure to add the new loader(s) before the "file" loader.
335
    ],
Dan Abramov's avatar
Dan Abramov committed
336
337
  },
  plugins: [
338
339
    // Makes some environment variables available in index.html.
    // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
340
341
    // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    // In development, this will be an empty string.
342
    new InterpolateHtmlPlugin(env.raw),
343
    // Generates an `index.html` file with the <script> injected.
Max's avatar
Max committed
344
345
    new HtmlWebpackPlugin({
      inject: true,
346
      template: paths.appHtml,
Max's avatar
Max committed
347
    }),
348
349
    // Add module names to factory functions so they appear in browser profiler.
    new webpack.NamedModulesPlugin(),
350
    // Makes some environment variables available to the JS code, for example:
351
    // if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
352
    new webpack.DefinePlugin(env.stringified),
353
    // This is necessary to emit hot updates (currently CSS only):
354
    new webpack.HotModuleReplacementPlugin(),
355
356
    // Watcher doesn't work well if you mistype casing in a path so we use
    // a plugin that prints an error when you attempt to do this.
357
    // See https://github.com/facebook/create-react-app/issues/240
358
    new CaseSensitivePathsPlugin(),
359
360
361
    // If you require a missing module and then `npm install` it, you still have
    // to restart the development server for Webpack to discover it. This plugin
    // makes the discovery automatic so you don't have to restart.
362
    // See https://github.com/facebook/create-react-app/issues/186
363
    new WatchMissingNodeModulesPlugin(paths.appNodeModules),
364
365
366
367
368
369
    // Moment.js is an extremely popular library that bundles large locale files
    // by default due to how Webpack interprets its code. This is a practical
    // solution that requires the user to opt into importing specific locales.
    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
    // You can remove this if you don't use Moment.js:
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
370
371
372
373
  ],
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
374
    dgram: 'empty',
375
376
    fs: 'empty',
    net: 'empty',
377
    tls: 'empty',
378
    child_process: 'empty',
Joe Haddad's avatar
Joe Haddad committed
379
380
381
382
383
  },
  // Turn off performance hints during development because we don't do any
  // splitting or minification in interest of speed. These warnings become
  // cumbersome.
  performance: {
384
385
    hints: false,
  },
Dan Abramov's avatar
Dan Abramov committed
386
};