text: 'use strict';
  
  const autoprefixer = require('autoprefixer');
  const path = require('path');
  const webpack = require('webpack');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  const ManifestPlugin = require('webpack-manifest-plugin');
  const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
  const CopyPlugin = require('copy-webpack-plugin');
  const workboxPlugin = require('workbox-webpack-plugin');
  const paths = require('../config/paths');
  const getClientEnvironment = require('./env');
  const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  const safePostCssParser = require('postcss-safe-parser');
  
  // Webpack uses `publicPath` to determine where the app is being served from.
  // It requires a trailing slash, or the file assets will get an incorrect path.
  const publicPath = paths.servedPath;
  // Source maps are resource heavy and can cause out of memory issue for large source files.
  const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
  // `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.
  // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
  const publicUrl = publicPath.slice(0, -1);
  // Get environment variables to inject into our app.
  const env = getClientEnvironment(publicUrl);
  
  const useDebugger = process.env.ELM_DEBUGGER === 'true';
  
  // This is the production configuration.
  // It compiles slowly and is focused on producing a fast and minimal bundle.
  // The development configuration is different and lives in a separate file.
  module.exports = {
    mode: 'production',
    // Don't attempt to continue if there are any errors.
    bail: true,
    // We generate sourcemaps in production. This is slow but gives good results.
    // You can exclude the *.map files from the build during deployment.
    devtool: shouldUseSourceMap ? 'source-map' : false,
    // In production, we only want to load the polyfills and the app code.
    entry: [require.resolve('./polyfills'), paths.appIndexJs],
    output: {
      // The build folder.
      path: paths.appBuild,
      // Generated JS file names (with nested folders).
      // There will be one main bundle, and one file per asynchronous chunk.
      // We don't currently advertise code splitting but Webpack supports it.
      filename: 'static/js/[name].[chunkhash:8].js',
      chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
      // We inferred the "public path" (such as / or /my-project) from homepage.
      publicPath: publicPath,
      // Point sourcemap entries to original disk location (format as URL on Windows)
      devtoolModuleFilenameTemplate: (info) =>
        path
          .relative(paths.appSrc, info.absoluteResourcePath)
          .replace(/\\/g, '/'),
    },
    optimization: {
      minimizer: [
        new UglifyJsPlugin({
          uglifyOptions: {
            // ES5 is required in the minified code if you want compatibility with IE11,
            // otherwise you can bump it up to ES8
            ecma: 5,
            // Compression settings mostly based on <https://guide.elm-lang.org/optimization/asset_size.html>
            compress: {
              passes: 2,
              warnings: false,
              // Disabled because of an issue with Uglify breaking seemingly valid code:
              // https://github.com/facebook/create-react-app/issues/2376
              // Pending further investigation:
              // https://github.com/mishoo/UglifyJS2/issues/2011
              comparisons: false,
              pure_getters: true,
              keep_fargs: false,
              unsafe_comps: true,
              unsafe: true,
              pure_funcs: [
                'A2',
                'A3',
                'A4',
                'A5',
                'A6',
                'A7',
                'A8',
                'A9',
                'F2',
                'F3',
                'F4',
                'F5',
                'F6',
                'F7',
                'F8',
                'F9',
              ],
            },
            mangle: {
              safari10: true,
            },
            output: {
              comments: false,
              // Turned on because emoji and regex is not minified properly using default
              // https://github.com/facebook/create-react-app/issues/2488
              ascii_only: true,
            },
          },
          // Use multi-process parallel running to improve the build speed
          // Default number of concurrent runs: os.cpus().length - 1
          parallel: true,
          // Enable file caching
          cache: true,
          sourceMap: shouldUseSourceMap,
        }),
        new OptimizeCSSAssetsPlugin({
          cssProcesorOptions: {
            parser: safePostCssParser,
            map: shouldUseSourceMap
              ? {
                  // This forces the sourcemap to be output into a separate file
                  inline: false,
                  // This appends the sourceMappingURL to the end of the css file,
                  // helping the browser find the sourcemap
                  annotation: true,
                }
              : false,
          },
        }),
      ],
      // Automatically split vendor and commons
      // https://twitter.com/wSokra/status/969633336732905474
      splitChunks: {
        chunks: 'all',
      },
      // Keep the runtime chunk seperated to enable long term caching
      // https://twitter.com/wSokra/status/969679223278505985
      runtimeChunk: true,
    },
    resolve: {
      modules: ['node_modules'],
      extensions: ['.js', '.mjs', '.elm'],
    },
    module: {
      strictExportPresence: true,
  
      rules: [
        {
          test: /\.js$/,
          exclude: [/[/\\\\]elm-stuff[/\\\\]/, /[/\\\\]node_modules[/\\\\]/],
          loader: require.resolve('babel-loader'),
          options: {
            // Latest stable ECMAScript features
            presets: [
              [
                require.resolve('@babel/preset-env'),
                {
                  // `entry` transforms `@babel/polyfill` into individual requires for
                  // the targeted browsers. This is safer than `usage` which performs
                  // static code analysis to determine what's required.
                  // This is probably a fine default to help trim down bundles when
                  // end-users inevitably import '@babel/polyfill'.
                  useBuiltIns: 'entry',
                  // Set the corejs version we are using to avoid warnings in console
                  corejs: 3,
                  // Do not transform modules to CJS
                  modules: false,
                },
              ],
            ],
            plugins: [
              // Polyfills the runtime needed for async/await and generators
              [
                require('@babel/plugin-transform-runtime').default,
                {
                  helpers: false,
                  regenerator: true,
                },
              ],
            ],
          },
        },
        // Process any JS outside of the app with Babel.
        // Unlike the application JS, we only compile the standard ES features.
        {
          test: /\.m?js$/,
          use: [
            {
              loader: require.resolve('babel-loader'),
              options: {
                babelrc: false,
                compact: false,
                presets: [
                  [
                    // Latest stable ECMAScript features
                    require('@babel/preset-env').default,
                    {
                      // Do not transform modules to CJS
                      modules: false,
                    },
                  ],
                ],
                cacheDirectory: true,
                highlightCode: true,
              },
            },
          ],
        },
        {
          test: /\.elm$/,
          exclude: [/[/\\\\]elm-stuff[/\\\\]/, /[/\\\\]node_modules[/\\\\]/],
          use: [
            // string-replace-loader works as InterpolateHtmlPlugin for Elm,
            // it replaces all of the %PUBLIC_URL% with the URL of your
            // application, so you could serve static assets outside of the
            // module system.
            {
              loader: require.resolve('string-replace-loader'),
              query: {
                search: '%PUBLIC_URL%',
                replace: publicUrl,
                flags: 'g',
              },
            },
            {
              loader: require.resolve('elm-asset-webpack-loader'),
            },
            {
              // Use the local installation of elm make
              loader: require.resolve('elm-webpack-loader'),
              options: {
                // If ELM_DEBUGGER was set to "true", enable it. Otherwise
                // for invalid values, "false" and as a default, disable it
                debug: useDebugger,
                optimize: !useDebugger,
                pathToElm: paths.elm,
              },
            },
          ],
        },
  
        // "postcss" loader applies autoprefixer to our CSS.
        // "css" loader resolves paths in CSS and adds assets as dependencies.
        // `MiniCSSExtractPlugin` extracts styles into CSS
        // files. If you use code splitting, async bundles will have their own separate CSS chunk file.
        // By default we support CSS Modules with the extension .module.css
        {
          test: /\.css$/,
          exclude: /\.module\.css$/,
          use: [
            MiniCssExtractPlugin.loader,
            {
              loader: require.resolve('css-loader'),
              options: {
                importLoaders: 1,
                sourceMap: shouldUseSourceMap,
              },
            },
            {
              loader: require.resolve('postcss-loader'),
              options: {
                // Necessary for external CSS imports to work
                // https://github.com/facebook/create-react-app/issues/2677
                postcssOptions: {
                  plugins: () => [
                    require('postcss-flexbugs-fixes'),
                    autoprefixer({
                      flexbox: 'no-2009',
                    }),
                  ],
                },
              },
            },
          ],
        },
  
        {
          exclude: [
            /\.html$/,
            /\.js$/,
            /\.mjs$/,
            /\.elm$/,
            /\.css$/,
            /\.scss$/,
            /\.sass$/,
            /\.json$/,
            /\.svg$/,
          ],
          loader: require.resolve('url-loader'),
          options: {
            limit: 10000,
            name: 'static/media/[name].[hash:8].[ext]',
          },
        },
        // "file" loader for svg
        {
          test: /\.svg$/,
          loader: require.resolve('file-loader'),
          options: {
            name: 'static/media/[name].[hash:8].[ext]',
          },
        },
      ],
    },
    plugins: [
      // Generates an `index.html` file with the <script> injected.
      new HtmlWebpackPlugin({
        inject: true,
        template: paths.appHtml,
        minify: {
          removeComments: true,
          collapseWhitespace: true,
          removeRedundantAttributes: true,
          useShortDoctype: true,
          removeEmptyAttributes: true,
          removeStyleLinkTypeAttributes: true,
          keepClosingSlash: true,
          minifyJS: true,
          minifyCSS: true,
          minifyURLs: true,
        },
      }),
      // Makes some environment variables available in index.html.
      // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
      // <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
      // In production, it will be an empty string unless you specify "homepage"
      // in `package.json`, in which case it will be the pathname of that URL.
      new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
      // Makes some environment variables available to the JS code, for example:
      // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
      // It is absolutely essential that NODE_ENV was set to production here.
      // Otherwise React will be compiled in the very slow development mode.
      new webpack.DefinePlugin(env.stringified),
      // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
      new MiniCssExtractPlugin({
        // Options similar to the same options in webpackOptions.output
        // both options are optional
        filename: 'static/css/[name].[contenthash:8].css',
        chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
      }),
      // Generate a manifest file which contains a mapping of all asset filenames
      // to their corresponding output file so that tools can pick it up without
      // having to parse `index.html`.
      new ManifestPlugin({
        fileName: 'asset-manifest.json',
        publicPath: publicPath,
      }),
      // Copies the public folder to the build folder
      new CopyPlugin([{ from: './public/', to: './' }]),
      // Generate a service worker script that will precache, and keep up to date,
      // the HTML & assets that are part of the Webpack build.
      new workboxPlugin.GenerateSW({
        swDest: './service-worker.js',
        skipWaiting: true,
        clientsClaim: true,
      }),
    ],
    // 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: {
      dgram: 'empty',
      fs: 'empty',
      net: 'empty',
      tls: 'empty',
      child_process: 'empty',
    },
  
    // Turn off performance processing because we utilize
    // our own hints via the FileSizeReporter
    performance: false,
  };
  