const path = require('path');
const workboxPlugin = require('workbox-webpack-plugin');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const { directories } = require('./package.json');

const folder = `./${directories.build}`;

module.exports = {
  mode: 'production',

  entry: ['./src/index.tsx'],

  output: {
    path: path.join(__dirname, folder),
    filename: '[name].[contenthash:8].js',
  },

  module: {
    rules: [
      {
        test: /\.(j|t)sx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },

  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.json'],
    modules: [path.join(__dirname, 'src'), 'node_modules'],
  },

  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          toplevel: true,
          parse: {
            // we want terser to parse ecma 8 code. However, we don't want it
            // to apply any minfication steps that turns valid ecma 5 code
            // into invalid ecma 5 code. This is why the 'compress' and 'output'
            // sections only apply transformations that are ecma 5 safe
            // https://github.com/facebook/create-react-app/pull/4234
            ecma: 8,
          },
          compress: {
            passes: 2,
            ecma: 5,
            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,
            // Disabled because of an issue with Terser breaking valid code:
            // https://github.com/facebook/create-react-app/issues/5250
            // Pending futher investigation:
            // https://github.com/terser-js/terser/issues/120
            inline: 2,
          },
          mangle: {
            safari10: true,
          },
          output: {
            ecma: 5,
            comments: false,
            // Turned on because emoji and regex is not minified properly using default
            // https://github.com/facebook/create-react-app/issues/2488
            // eslint-disable-next-line @typescript-eslint/camelcase
            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,
      }),
    ],
    splitChunks: {
      chunks: 'all',
      maxInitialRequests: Infinity,
      minSize: 30 * 1000,
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name(module) {
            // get the name. E.g. node_modules/packageName/not/this/part.js
            // or node_modules/packageName
            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];

            // npm package names are URL-safe, but some servers don't like @ symbols
            return `npm.${packageName.replace('@', '')}`;
          },
        },
      },
    },
    runtimeChunk: true,
  },

  plugins: [
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: [
        `**/main*.js`,
        `**/*style*.css`,
        `**/*runtime*.js`,
        `**/*vendors*.js`,
        `**/npm*.js`,
        `**/precache-manifest*.js`,
      ],
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new webpack.HashedModuleIdsPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      },
    }),
    new webpack.DefinePlugin({
      __DEV__: false,
      __PROD__: true,
    }),
    new workboxPlugin.GenerateSW({
      swDest: 'sw.js',
      exclude: ['index.html'],
      clientsClaim: true,
      skipWaiting: true,
      importWorkboxFrom: 'cdn',
      runtimeCaching: [
        {
          urlPattern: new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'),
          handler: 'CacheFirst',
          options: {
            cacheName: 'googleFonts',
            expiration: {
              maxEntries: 30,
              maxAgeSeconds: 60 * 60 * 24 * 365,
            },
          },
        },
        {
          urlPattern: '/static',
          handler: 'CacheFirst',
        },
        {
          urlPattern: '/index.html',
          handler: 'NetworkFirst',
        },
      ],
    }),
  ],
};

@@ -3358,24 +3358,27 @@
 ugins: %5B%0A   
+ //
  new CleanWe
@@ -3390,24 +3390,27 @@
 Plugin(%7B%0A   
+ //
    cleanOnce
@@ -3432,28 +3432,31 @@
 erns: %5B%0A    
+//
     
+ 
 %60**/main*.js
@@ -3453,32 +3453,35 @@
 */main*.js%60,%0A   
+ //
      %60**/*style*
@@ -3486,24 +3486,27 @@
 e*.css%60,%0A   
+ //
      %60**/*ru
@@ -3512,32 +3512,35 @@
 untime*.js%60,%0A   
+ //
      %60**/*vendor
@@ -3542,32 +3542,35 @@
 endors*.js%60,%0A   
+ //
      %60**/npm*.js
@@ -3576,20 +3576,23 @@
 s%60,%0A    
+//
     
+ 
 %60**/prec
@@ -3610,24 +3610,27 @@
 st*.js%60,%0A   
+ //
    %5D,%0A    %7D)
@@ -3622,24 +3622,27 @@
  //   %5D,%0A   
+ //
  %7D),%0A    new

Disable cleanwebpackplugin