webpack gets stuck again? in compile stage

Bug report

What is the current behavior?

When I run npm run build:aot The process is stuck in different files each time but always at 68%% – 69%%
69%% building modules 1720/1726 modules 6 active …ient/node_modules/....js

The memory is used over 10GB, normally only 2GB at most.

The build:aot run as follows: npm run clean:dist && npm run clean:aot && cross-env BUILD_AOT=1 SOURCE_MAP=0 npm run webpack -- --config config/webpack.prod.js --progress --profile --bail

Also, I increased the memory allocation to webpack command: node --max_old_space_size=12288 node_modules/webpack/bin/webpack.js

My node version is v10.2.1, npm version is 5.6.0 or 6.1.0 all the same issue

List of package used I think it may cause the issue:

"@types/uglify-js": "^3.0.2",
"@angular/cli": "^6.0.5",
"@types/node": "^10.1.3",
"node-sass": "^4.9.0",
"sass-loader": "^7.0.1",
"postcss-loader": "^2.1.5",

"@types/webpack": "^4.4.0",
"add-asset-html-webpack-plugin": "~2.1.3",
"assets-webpack-plugin": "^3.5.1",
"compression-webpack-plugin": "^1.1.11",
"copy-webpack-plugin": "^4.5.1",
"html-webpack-plugin": "^3.2.0",
"ngc-webpack": "^4.1.2",
"optimize-css-assets-webpack-plugin": "^4.0.2",
"preload-webpack-plugin": "^2.3.0",
"script-ext-html-webpack-plugin": "^2.0.1",
"uglifyjs-webpack-plugin": "^1.2.5",

"webpack": "^4.10.0",
"webpack-bundle-analyzer": "^2.13.1",
"webpack-cli": "^2.1.4",
"webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "~3.1.4",
"webpack-inline-manifest-plugin": "^4.0.1",
"webpack-merge": "~4.1.2"

All above are updated to the current latest

If the current behavior is a bug, please provide the steps to reproduce.

The prod webpack config is as follows:

module.exports = function (env) {
  const ENV = (process.env.NODE_ENV = process.env.ENV = 'production');
  const supportES2015 = buildUtils.supportES2015(
    buildUtils.DEFAULT_METADATA.tsConfigPath
  );
  const sourceMapEnabled = process.env.SOURCE_MAP === '1';
  const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA, {
    host: process.env.HOST || 'localhost',
    port: process.env.PORT || 8080,
    ENV: ENV,
    HMR: false
  });

  // set environment suffix so these environments are loaded.
  METADATA.envFileSuffix = METADATA.E2E ? 'e2e.prod' : 'prod';

  return webpackMerge(commonConfig({
    env: ENV,
    metadata: METADATA
  }), {
    /**
     * Options affecting the output of the compilation.
     *
     * See: https://webpack.js.org/configuration/output/
     */
    output: {
      /**
       * The output directory as absolute path (required).
       *
       * See: https://webpack.js.org/configuration/output/#output-path
       */
      path: helpers.root('dist'),

      /**
       * Specifies the name of each output file on disk.
       * IMPORTANT: You must not specify an absolute path here!
       *
       * See: https://webpack.js.org/configuration/output/#output-filename
       */
      filename: '[name].[chunkhash].bundle.js',

      /**
       * The filename of the SourceMaps for the JavaScript files.
       * They are inside the output.path directory.
       *
       * See: https://webpack.js.org/configuration/output/#output-sourcemapfilename
       */
      sourceMapFilename: '[file].map',

      /**
       * The filename of non-entry chunks as relative path
       * inside the output.path directory.
       *
       * See: https://webpack.js.org/configuration/output/#output-chunkfilename
       */
      chunkFilename: '[name].[chunkhash].chunk.js'
    },

    module: {
      rules: [
        /**
         * Extract CSS files from .src/styles directory to external CSS file
         */
        {
          test: /\.css$/,
          use: [
            MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                minimize: {
                  safe: true
                },
                importLoaders: 2,
                sourceMap: false
              }
            },
            {
              loader: 'postcss-loader',
              options: {
                plugins: () => [require('autoprefixer')],
                sourceMap: false
              }
            }
          ],
          include: [helpers.root('src', 'styles')]
        },
        {
          test: /\.s?[ac]ss$/,
          use: [
            MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                minimize: {
                  safe: true
                },
                importLoaders: 2,
                sourceMap: false
              }
            },
            {
              loader: 'postcss-loader',
              options: {
                plugins: () => [require('autoprefixer')],
                sourceMap: false
              }
            },
            {
              loader: 'sass-loader',
              options: {
                sourceMap: false
              }
            }
          ],
          include: [helpers.root('src', 'styles')]
        },
        {
          test: /\.less$/,
          use: [
            MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                minimize: {
                  safe: true
                },
                importLoaders: 2,
                sourceMap: false
              }
            },
            {
              loader: 'postcss-loader',
              options: {
                plugins: () => [require('autoprefixer')],
                sourceMap: false
              }
            },
            {
              loader: 'less-loader',
              options: {
                sourceMap: false
              }
            }
          ],
          include: [helpers.root('src', 'styles')]
        }
      ]
    },

    // optimization: {
    //   minimizer: [
    //     new UglifyJsPlugin({
    //       sourceMap: false,
    //       cache: true,
    //       parallel: true,
    //       uglifyOptions: getUglifyOptions(supportES2015)
    //     }),
    //     new OptimizeCSSAssetsPlugin({})
    //   ],
    //   splitChunks: {
    //     cacheGroups: {
    //       styles: {
    //         name: 'styles',
    //         test: /\.css$/,
    //         chunks: 'all',
    //         enforce: true
    //       }
    //     }
    //   }
    // },

    /**
     * Add additional plugins to the compiler.
     *
     * See: https://webpack.js.org/configuration/plugins/
     */
    plugins: [
      new SourceMapDevToolPlugin({
        filename: '[file].map[query]',
        moduleFilenameTemplate: '[resource-path]',
        fallbackModuleFilenameTemplate: '[resource-path]?[hash]',
        sourceRoot: 'webpack:///'
      }),

      /**
       * Plugin: MiniCssExtractPlugin
       * Description: Extracts imported CSS files into external stylesheet
       *
       * See: https://github.com/webpack-contrib/mini-css-extract-plugin
       */
      new MiniCssExtractPlugin({
        // Options similar to the same options in webpackOptions.output
        // both options are optional
        filename: '[name].[contenthash].css',
        chunkFilename: '[id].css'
      }),

      new PurifyPlugin() /* buildOptimizer */ ,

      new HashedModuleIdsPlugin(),

      /**
       * Plugin: UglifyJsPlugin
       * Description: Minimize all JavaScript output of chunks.
       * Loaders are switched into minimizing mode.
       *
       * See: https://webpack.js.org/plugins/uglifyjs-webpack-plugin/
       *
       * NOTE: To debug prod builds uncomment //debug lines and comment //prod lines
       */
      new UglifyJsPlugin({
        sourceMap: sourceMapEnabled,
        parallel: true,
        cache: helpers.root('webpack-cache/uglify-cache'),
        uglifyOptions: getUglifyOptions(supportES2015, true),
      }),

      /**
       * Plugin: CompressionPlugin
       * Description: Prepares compressed versions of assets to serve
       * them with Content-Encoding
       *
       * See: https://github.com/webpack/compression-webpack-plugin
       */
      //  install compression-webpack-plugin
      new CompressionPlugin({
        test: /\.css$|\.html$|\.js$|\.map$/,
        threshold: 2 * 1024
      })
    ],

    /**
     * Include polyfills or mocks for various node stuff
     * Description: Node configuration
     *
     * See: https://webpack.js.org/configuration/node/
     */
    node: {
      global: true,
      crypto: 'empty',
      process: false,
      module: false,
      clearImmediate: false,
      setImmediate: false,
      fs: 'empty'
    }
  });
};

What is the expected behavior?

It builds successfully to the dist folder, not sure which package break this build

Other relevant information:
webpack version: latest
Node.js version: latest
Operating System: macos 10.13.4
Additional tools: Angular CLI, node-sass, pre

Author: Fantashit

2 thoughts on “webpack gets stuck again? in compile stage

  1. I had a similar issue, google pointed me here. Leaving my findings for the future.
    For me, it was related to sass/node-sass#857
    For me, it only existed on webpack-dev-server with node-sass on Windows.

    I resolved it by adding
    UV_THREADPOOL_SIZE=1024 to my package.json build scripts

        "run-dev": "cross-env DEV='true' NODE_ENV=development BABEL_ENV=development NODE_OPTIONS=--max_old_space_size=8192 webpack-dev-server --config webpack.dev.js --progress --color",
        "run-dev-windows": "cross-env DEV='true' NODE_ENV=development BABEL_ENV=development NODE_OPTIONS=--max_old_space_size=8192 UV_THREADPOOL_SIZE=1024 webpack-dev-server --config webpack.dev.js --progress --color",
    

    It slowed down my linux builds, so I split it into two scripts. But it turned my windows builds from never-finishing always-hanging to actually-completes (in about 3.5 minutes)

Comments are closed.