config/webpack.config.js   A
last analyzed

Complexity

Total Complexity 20
Complexity/F 2.86

Size

Lines of Code 677
Function Count 7

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 20
eloc 319
mnd 13
bc 13
fnc 7
dl 0
loc 677
rs 10
bpm 1.8571
cpm 2.8571
noi 0
c 0
b 0
f 0
1
2
const fs = require('fs');
3
const path = require('path');
4
const webpack = require('webpack');
5
const resolve = require('resolve');
6
const PnpWebpackPlugin = require('pnp-webpack-plugin');
7
const HtmlWebpackPlugin = require('html-webpack-plugin');
8
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
9
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
10
const TerserPlugin = require('terser-webpack-plugin');
11
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
12
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
13
const safePostCssParser = require('postcss-safe-parser');
14
const ManifestPlugin = require('webpack-manifest-plugin');
15
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
16
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
17
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
18
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
19
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
20
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
21
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt');
22
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
23
const getClientEnvironment = require('./env');
24
const paths = require('./paths');
25
26
// Source maps are resource heavy and can cause out of memory issue for large source files.
27
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
28
29
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
30
// makes for a smoother build process.
31
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
32
33
// Check if TypeScript is setup
34
const useTypeScript = fs.existsSync(paths.appTsConfig);
35
36
// style files regexes
37
const cssRegex = /\.css$/;
38
const cssModuleRegex = /\.module\.css$/;
39
const sassRegex = /\.(scss|sass)$/;
40
const sassModuleRegex = /\.module\.(scss|sass)$/;
41
42
// This is the production and development configuration.
43
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
44
/* eslint-disable complexity */
45
module.exports = (webpackEnv) => {
46
  const isEnvDevelopment = webpackEnv === 'development';
47
  const isEnvProduction = webpackEnv === 'production';
48
49
  // Webpack uses `publicPath` to determine where the app is being served from.
50
  // It requires a trailing slash, or the file assets will get an incorrect path.
51
  // In development, we always serve from the root. This makes config easier.
52
  const publicPath = isEnvProduction
53
    ? paths.servedPath
54
    : isEnvDevelopment && '/';
55
56
  // Some apps do not use client-side routing with pushState.
57
  // For these, "homepage" can be set to "." to enable relative asset paths.
58
  const shouldUseRelativeAssetPaths = publicPath === './';
59
60
  // `publicUrl` is just like `publicPath`, but we will provide it to our app
61
  // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
62
  // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
63
  const publicUrl = isEnvProduction
64
    ? publicPath.slice(0, -1)
65
    : isEnvDevelopment && '';
66
67
  // Get environment variables to inject into our app.
68
  const env = getClientEnvironment(publicUrl);
69
70
  // common function to get style loaders
71
  const getStyleLoaders = (cssOptions, preProcessor) => {
72
    const loaders = [
73
      isEnvDevelopment && require.resolve('style-loader'),
74
      isEnvProduction && {
75
        loader: MiniCssExtractPlugin.loader,
76
        options: Object.assign(
77
          {},
78
          shouldUseRelativeAssetPaths ? { publicPath: '../../' } : undefined
79
        ),
80
      },
81
      {
82
        loader: require.resolve('css-loader'),
83
        options: cssOptions,
84
      },
85
      {
86
87
        // Options for PostCSS as we reference these options twice
88
        // Adds vendor prefixing based on your specified browser support in
89
        // package.json
90
        loader: require.resolve('postcss-loader'),
91
        options: {
92
93
          // Necessary for external CSS imports to work
94
          // https://github.com/facebook/create-react-app/issues/2677
95
          ident: 'postcss',
96
          plugins: () => [
97
            require('postcss-flexbugs-fixes'),
98
            require('postcss-preset-env')({
99
              autoprefixer: {
100
                flexbox: 'no-2009',
101
              },
102
              stage: 3,
103
            }),
104
          ],
105
          sourceMap: isEnvProduction && shouldUseSourceMap,
106
        },
107
      },
108
    ].filter(Boolean);
109
110
    if (preProcessor) {
111
      loaders.push({
112
        loader: require.resolve(preProcessor),
113
        options: {
114
          sourceMap: isEnvProduction && shouldUseSourceMap,
115
        },
116
      });
117
    }
118
119
    return loaders;
120
  };
121
122
  return {
123
    mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
124
125
    // Stop compilation early in production
126
    bail: isEnvProduction,
127
    devtool: isEnvProduction
128
      ? shouldUseSourceMap
129
        ? 'source-map'
130
        : false
131
      : isEnvDevelopment && 'cheap-module-source-map',
132
133
    // These are the "entry points" to our application.
134
    // This means they will be the "root" imports that are included in JS bundle.
135
    entry: [
136
137
      // Include an alternative client for WebpackDevServer. A client's job is to
138
      // connect to WebpackDevServer by a socket and get notified about changes.
139
      // When you save a file, the client will either apply hot updates (in case
140
      // of CSS changes), or refresh the page (in case of JS changes). When you
141
      // make a syntax error, this client will display a syntax error overlay.
142
      // Note: instead of the default WebpackDevServer client, we use a custom one
143
      // to bring better experience for Create React App users. You can replace
144
      // the line below with these two lines if you prefer the stock client:
145
      // require.resolve('webpack-dev-server/client') + '?/',
146
      // require.resolve('webpack/hot/dev-server'),
147
      isEnvDevelopment &&
148
        require.resolve('react-dev-utils/webpackHotDevClient'),
149
150
      // Finally, this is your app's code:
151
      paths.appIndexJs,
152
153
      // We include the app code last so that if there is a runtime error during
154
      // initialization, it doesn't blow up the WebpackDevServer client, and
155
      // changing JS code would still trigger a refresh.
156
    ].filter(Boolean),
157
    output: {
158
159
      // The build folder.
160
      path: isEnvProduction ? paths.appBuild : undefined,
161
162
      // Add /* filename */ comments to generated require()s in the output.
163
      pathinfo: isEnvDevelopment,
164
165
      // There will be one main bundle, and one file per asynchronous chunk.
166
      // In development, it does not produce real files.
167
      filename: isEnvProduction
168
        ? 'static/js/[name].[chunkhash:8].js'
169
        : isEnvDevelopment && 'static/js/bundle.js',
170
171
      // There are also additional JS chunk files if you use code splitting.
172
      chunkFilename: isEnvProduction
173
        ? 'static/js/[name].[chunkhash:8].chunk.js'
174
        : isEnvDevelopment && 'static/js/[name].chunk.js',
175
176
      // We inferred the "public path" (such as / or /my-project) from homepage.
177
      // We use "/" in development.
178
      publicPath,
179
180
      // Point sourcemap entries to original disk location (format as URL on Windows)
181
      devtoolModuleFilenameTemplate: isEnvProduction
182
        ? (info) =>
183
          path
184
            .relative(paths.appSrc, info.absoluteResourcePath)
185
            .replace(/\\/g, '/')
186
        : isEnvDevelopment &&
187
          ((info) => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
188
    },
189
    optimization: {
190
      minimize: isEnvProduction,
191
      minimizer: [
192
193
        // This is only used in production mode
194
        new TerserPlugin({
195
          terserOptions: {
196
            parse: {
197
198
              // we want terser to parse ecma 8 code. However, we don't want it
199
              // to apply any minfication steps that turns valid ecma 5 code
200
              // into invalid ecma 5 code. This is why the 'compress' and 'output'
201
              // sections only apply transformations that are ecma 5 safe
202
              // https://github.com/facebook/create-react-app/pull/4234
203
              ecma: 8,
204
            },
205
            compress: {
206
              ecma: 5,
207
              warnings: false,
208
209
              // Disabled because of an issue with Uglify breaking seemingly valid code:
210
              // https://github.com/facebook/create-react-app/issues/2376
211
              // Pending further investigation:
212
              // https://github.com/mishoo/UglifyJS2/issues/2011
213
              comparisons: false,
214
215
              // Disabled because of an issue with Terser breaking valid code:
216
              // https://github.com/facebook/create-react-app/issues/5250
217
              // Pending futher investigation:
218
              // https://github.com/terser-js/terser/issues/120
219
              inline: 2,
220
            },
221
            mangle: {
222
              safari10: true,
223
            },
224
            output: {
225
              ecma: 5,
226
              comments: false,
227
228
              // Turned on because emoji and regex is not minified properly using default
229
              // https://github.com/facebook/create-react-app/issues/2488
230
              ascii_only: true,
231
            },
232
          },
233
234
          // Use multi-process parallel running to improve the build speed
235
          // Default number of concurrent runs: os.cpus().length - 1
236
          parallel: true,
237
238
          // Enable file caching
239
          cache: true,
240
          sourceMap: shouldUseSourceMap,
241
        }),
242
243
        // This is only used in production mode
244
        new OptimizeCSSAssetsPlugin({
245
          cssProcessorOptions: {
246
            parser: safePostCssParser,
247
            map: shouldUseSourceMap
248
              ? {
249
250
                // `inline: false` forces the sourcemap to be output into a
251
                // separate file
252
                inline: false,
253
254
                // `annotation: true` appends the sourceMappingURL to the end of
255
                // the css file, helping the browser find the sourcemap
256
                annotation: true,
257
              }
258
              : false,
259
          },
260
        }),
261
      ],
262
263
      // Automatically split vendor and commons
264
      // https://twitter.com/wSokra/status/969633336732905474
265
      // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
266
      splitChunks: {
267
        chunks: 'all',
268
        name: false,
269
      },
270
271
      // Keep the runtime chunk separated to enable long term caching
272
      // https://twitter.com/wSokra/status/969679223278505985
273
      runtimeChunk: true,
274
    },
275
    resolve: {
276
277
      // This allows you to set a fallback for where Webpack should look for modules.
278
      // We placed these paths second because we want `node_modules` to "win"
279
      // if there are any conflicts. This matches Node resolution mechanism.
280
      // https://github.com/facebook/create-react-app/issues/253
281
      modules: [ 'node_modules' ].concat(
282
283
        // It is guaranteed to exist because we tweak it in `env.js`
284
        process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
285
      ),
286
287
      // These are the reasonable defaults supported by the Node ecosystem.
288
      // We also include JSX as a common component filename extension to support
289
      // some tools, although we do not recommend using it, see:
290
      // https://github.com/facebook/create-react-app/issues/290
291
      // `web` extension prefixes have been added for better support
292
      // for React Native Web.
293
      extensions: paths.moduleFileExtensions
294
        .map((ext) => `.${ext}`)
295
        .filter((ext) => useTypeScript || !ext.includes('ts')),
296
      alias: {
297
298
        // Support React Native Web
299
        // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
300
        'react-native': 'react-native-web',
301
      },
302
      plugins: [
303
304
        // Adds support for installing with Plug'n'Play, leading to faster installs and adding
305
        // guards against forgotten dependencies and such.
306
        PnpWebpackPlugin,
307
308
        // Prevents users from importing files from outside of src/ (or node_modules/).
309
        // This often causes confusion because we only process files within src/ with babel.
310
        // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
311
        // please link the files into your node_modules/ and let module-resolution kick in.
312
        // Make sure your source files are compiled, as they will not be processed in any way.
313
        new ModuleScopePlugin(paths.appSrc, [ paths.appPackageJson ]),
314
      ],
315
    },
316
    resolveLoader: {
317
      plugins: [
318
319
        // Also related to Plug'n'Play, but this time it tells Webpack to load its loaders
320
        // from the current package.
321
        PnpWebpackPlugin.moduleLoader(module),
322
      ],
323
    },
324
    module: {
325
      strictExportPresence: true,
326
      rules: [
327
328
        // Disable require.ensure as it's not a standard language feature.
329
        { parser: { requireEnsure: false } },
330
331
        // First, run the linter.
332
        // It's important to do this before Babel processes the JS.
333
        {
334
          test: /\.(js|mjs|jsx)$/,
335
          enforce: 'pre',
336
          use: [
337
            {
338
              options: {
339
                formatter: require.resolve('react-dev-utils/eslintFormatter'),
340
                eslintPath: require.resolve('eslint'),
341
342
              },
343
              loader: require.resolve('eslint-loader'),
344
            },
345
          ],
346
          include: paths.appSrc,
347
        },
348
        {
349
350
          // "oneOf" will traverse all following loaders until one will
351
          // match the requirements. When no loader matches it will fall
352
          // back to the "file" loader at the end of the loader list.
353
          oneOf: [
354
355
            // "url" loader works like "file" loader except that it embeds assets
356
            // smaller than specified limit in bytes as data URLs to avoid requests.
357
            // A missing `test` is equivalent to a match.
358
            {
359
              test: [ /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/ ],
360
              loader: require.resolve('url-loader'),
361
              options: {
362
                limit: 10000,
363
                name: 'static/media/[name].[hash:8].[ext]',
364
              },
365
            },
366
367
            // Process application JS with Babel.
368
            // The preset includes JSX, Flow, TypeScript, and some ESnext features.
369
            {
370
              test: /\.(js|mjs|jsx|ts|tsx)$/,
371
              include: paths.appSrc,
372
              loader: require.resolve('babel-loader'),
373
              options: {
374
                customize: require.resolve(
375
                  'babel-preset-react-app/webpack-overrides'
376
                ),
377
378
                plugins: [
379
                  [
380
                    require.resolve('babel-plugin-named-asset-import'),
381
                    {
382
                      loaderMap: {
383
                        svg: {
384
                          ReactComponent:
385
                            '@svgr/webpack?-prettier,-svgo![path]',
386
                        },
387
                      },
388
                    },
389
                  ],
390
                ],
391
392
                // This is a feature of `babel-loader` for webpack (not Babel itself).
393
                // It enables caching results in ./node_modules/.cache/babel-loader/
394
                // directory for faster rebuilds.
395
                cacheDirectory: true,
396
                cacheCompression: isEnvProduction,
397
                compact: isEnvProduction,
398
              },
399
            },
400
401
            // Process any JS outside of the app with Babel.
402
            // Unlike the application JS, we only compile the standard ES features.
403
            {
404
              test: /\.(js|mjs)$/,
405
              exclude: /@babel(?:\/|\\{1,2})runtime/,
406
              loader: require.resolve('babel-loader'),
407
              options: {
408
                babelrc: false,
409
                configFile: false,
410
                compact: false,
411
                presets: [
412
                  [
413
                    require.resolve('babel-preset-react-app/dependencies'),
414
                    { helpers: true },
415
                  ],
416
                ],
417
                cacheDirectory: true,
418
                cacheCompression: isEnvProduction,
419
420
                // If an error happens in a package, it's possible to be
421
                // because it was compiled. Thus, we don't want the browser
422
                // debugger to show the original code. Instead, the code
423
                // being evaluated would be much more helpful.
424
                sourceMaps: false,
425
              },
426
            },
427
428
            // "postcss" loader applies autoprefixer to our CSS.
429
            // "css" loader resolves paths in CSS and adds assets as dependencies.
430
            // "style" loader turns CSS into JS modules that inject <style> tags.
431
            // In production, we use MiniCSSExtractPlugin to extract that CSS
432
            // to a file, but in development "style" loader enables hot editing
433
            // of CSS.
434
            // By default we support CSS Modules with the extension .module.css
435
            {
436
              test: cssRegex,
437
              exclude: cssModuleRegex,
438
              use: getStyleLoaders({
439
                importLoaders: 1,
440
                sourceMap: isEnvProduction && shouldUseSourceMap,
441
              }),
442
443
              // Don't consider CSS imports dead code even if the
444
              // containing package claims to have no side effects.
445
              // Remove this when webpack adds a warning or an error for this.
446
              // See https://github.com/webpack/webpack/issues/6571
447
              sideEffects: true,
448
            },
449
450
            // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
451
            // using the extension .module.css
452
            {
453
              test: cssModuleRegex,
454
              use: getStyleLoaders({
455
                importLoaders: 1,
456
                sourceMap: isEnvProduction && shouldUseSourceMap,
457
                modules: true,
458
                getLocalIdent: getCSSModuleLocalIdent,
459
              }),
460
            },
461
462
            // Opt-in support for SASS (using .scss or .sass extensions).
463
            // By default we support SASS Modules with the
464
            // extensions .module.scss or .module.sass
465
            {
466
              test: sassRegex,
467
              exclude: sassModuleRegex,
468
              use: getStyleLoaders(
469
                {
470
                  importLoaders: 2,
471
                  sourceMap: isEnvProduction && shouldUseSourceMap,
472
                },
473
                'sass-loader'
474
              ),
475
476
              // Don't consider CSS imports dead code even if the
477
              // containing package claims to have no side effects.
478
              // Remove this when webpack adds a warning or an error for this.
479
              // See https://github.com/webpack/webpack/issues/6571
480
              sideEffects: true,
481
            },
482
483
            // Adds support for CSS Modules, but using SASS
484
            // using the extension .module.scss or .module.sass
485
            {
486
              test: sassModuleRegex,
487
              use: getStyleLoaders(
488
                {
489
                  importLoaders: 2,
490
                  sourceMap: isEnvProduction && shouldUseSourceMap,
491
                  modules: true,
492
                  getLocalIdent: getCSSModuleLocalIdent,
493
                },
494
                'sass-loader'
495
              ),
496
            },
497
498
            // "file" loader makes sure those assets get served by WebpackDevServer.
499
            // When you `import` an asset, you get its (virtual) filename.
500
            // In production, they would get copied to the `build` folder.
501
            // This loader doesn't use a "test" so it will catch all modules
502
            // that fall through the other loaders.
503
            {
504
              loader: require.resolve('file-loader'),
505
506
              // Exclude `js` files to keep "css" loader working as it injects
507
              // its runtime that would otherwise be processed through "file" loader.
508
              // Also exclude `html` and `json` extensions so they get processed
509
              // by webpacks internal loaders.
510
              exclude: [ /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/ ],
511
              options: {
512
                name: 'static/media/[name].[hash:8].[ext]',
513
              },
514
            },
515
516
            // ** STOP ** Are you adding a new loader?
517
            // Make sure to add the new loader(s) before the "file" loader.
518
          ],
519
        },
520
      ],
521
    },
522
    plugins: [
523
524
      // Generates an `index.html` file with the <script> injected.
525
      new HtmlWebpackPlugin(
526
        Object.assign(
527
          {},
528
          {
529
            inject: true,
530
            template: paths.appHtml,
531
          },
532
          isEnvProduction
533
            ? {
534
              minify: {
535
                removeComments: true,
536
                collapseWhitespace: true,
537
                removeRedundantAttributes: true,
538
                useShortDoctype: true,
539
                removeEmptyAttributes: true,
540
                removeStyleLinkTypeAttributes: true,
541
                keepClosingSlash: true,
542
                minifyJS: true,
543
                minifyCSS: true,
544
                minifyURLs: true,
545
              },
546
            }
547
            : undefined
548
        )
549
      ),
550
551
      // Inlines the webpack runtime script. This script is too small to warrant
552
      // a network request.
553
      isEnvProduction &&
554
        shouldInlineRuntimeChunk &&
555
        new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [ /runtime~.+[.]js/ ]),
556
557
      // Makes some environment variables available in index.html.
558
      // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
559
      // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
560
      // In production, it will be an empty string unless you specify "homepage"
561
      // in `package.json`, in which case it will be the pathname of that URL.
562
      // In development, this will be an empty string.
563
      new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
564
565
      // This gives some necessary context to module not found errors, such as
566
      // the requesting resource.
567
      new ModuleNotFoundPlugin(paths.appPath),
568
569
      // Makes some environment variables available to the JS code, for example:
570
      // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
571
      // It is absolutely essential that NODE_ENV is set to production
572
      // during a production build.
573
      // Otherwise React will be compiled in the very slow development mode.
574
      new webpack.DefinePlugin(env.stringified),
575
576
      // This is necessary to emit hot updates (currently CSS only):
577
      isEnvDevelopment && new webpack.HotModuleReplacementPlugin(),
578
579
      // Watcher doesn't work well if you mistype casing in a path so we use
580
      // a plugin that prints an error when you attempt to do this.
581
      // See https://github.com/facebook/create-react-app/issues/240
582
      isEnvDevelopment && new CaseSensitivePathsPlugin(),
583
584
      // If you require a missing module and then `npm install` it, you still have
585
      // to restart the development server for Webpack to discover it. This plugin
586
      // makes the discovery automatic so you don't have to restart.
587
      // See https://github.com/facebook/create-react-app/issues/186
588
      isEnvDevelopment &&
589
        new WatchMissingNodeModulesPlugin(paths.appNodeModules),
590
      isEnvProduction &&
591
        new MiniCssExtractPlugin({
592
593
          // Options similar to the same options in webpackOptions.output
594
          // both options are optional
595
          filename: 'static/css/[name].[contenthash:8].css',
596
          chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
597
        }),
598
599
      // Generate a manifest file which contains a mapping of all asset filenames
600
      // to their corresponding output file so that tools can pick it up without
601
      // having to parse `index.html`.
602
      new ManifestPlugin({
603
        fileName: 'asset-manifest.json',
604
        publicPath,
605
      }),
606
607
      // Moment.js is an extremely popular library that bundles large locale files
608
      // by default due to how Webpack interprets its code. This is a practical
609
      // solution that requires the user to opt into importing specific locales.
610
      // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
611
      // You can remove this if you don't use Moment.js:
612
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
613
614
      // Generate a service worker script that will precache, and keep up to date,
615
      // the HTML & assets that are part of the Webpack build.
616
      isEnvProduction &&
617
        new WorkboxWebpackPlugin.GenerateSW({
618
          clientsClaim: true,
619
          exclude: [ /\.map$/, /asset-manifest\.json$/ ],
620
          importWorkboxFrom: 'cdn',
621
          navigateFallback: `${publicUrl}/index.html`,
622
          navigateFallbackBlacklist: [
623
624
            // Exclude URLs starting with /_, as they're likely an API call
625
            new RegExp('^/_'),
626
627
            // Exclude URLs containing a dot, as they're likely a resource in
628
            // public/ and not a SPA route
629
            new RegExp('/[^/]+\\.[^/]+$'),
630
          ],
631
        }),
632
633
      // TypeScript type checking
634
      useTypeScript &&
635
        new ForkTsCheckerWebpackPlugin({
636
          typescript: resolve.sync('typescript', {
637
            basedir: paths.appNodeModules,
638
          }),
639
          async: false,
640
          checkSyntacticErrors: true,
641
          tsconfig: paths.appTsConfig,
642
          compilerOptions: {
643
            module: 'esnext',
644
            moduleResolution: 'node',
645
            resolveJsonModule: true,
646
            isolatedModules: true,
647
            noEmit: true,
648
            jsx: 'preserve',
649
          },
650
          reportFiles: [
651
            '**',
652
            '!**/*.json',
653
            '!**/__tests__/**',
654
            '!**/?(*.)(spec|test).*',
655
            '!**/src/setupProxy.*',
656
            '!**/src/setupTests.*',
657
          ],
658
          watch: paths.appSrc,
659
          silent: true,
660
          formatter: typescriptFormatter,
661
        }),
662
    ].filter(Boolean),
663
664
    // Some libraries import Node modules but don't use them in the browser.
665
    // Tell Webpack to provide empty mocks for them so importing them works.
666
    node: {
667
      dgram: 'empty',
668
      fs: 'empty',
669
      net: 'empty',
670
      tls: 'empty',
671
      child_process: 'empty',
672
    },
673
674
    // Turn off performance processing because we utilize
675
    // our own hints via the FileSizeReporter
676
    performance: false,
677
  };
678
};
679