webpack 之 webpack 构建速度和体积优化的高版本设置、多进程多实例构建、多进程多实例并行压缩、预编译资源模块、缓存优化速度和缩小构建目标

本文详细介绍了如何通过升级webpack和Node.js版本,利用V8优化、多进程多实例构建、HappyPack和thread-loader提升构建速度。同时,展示了并行压缩技术如parallel-uglify-plugin和terser-webpack-plugin的使用。此外,还讨论了预编译资源模块、DllPlugin与DllReferencePlugin的应用,以及缓存策略,包括babel-loader和terser-webpack-plugin的缓存设置,以实现更快的二次构建速度。最后,提到了缩小构建目标的方法,如排除node_modules,优化resolve配置,以进一步提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、webpack 构建速度和体积优化的高版本设置、多进程多实例构建、多进程多实例并行压缩、预编译资源模块、缓存优化速度和缩小构建目标
  1. 构建速度优化,使用高版本的 webpackNode.js,构建时间降低了 60% - 98%。使用 webpack4 的优化原因,如下所示:
  • V8 带来的优化,for of 替代 forEach、MapSet 替代 Object、includes 替代 indexOf 等等
  • 默认使用更快的 md4 hash 算法
  • webpack AST 可以直接从 loader 传递给 AST,减少解析时间
  • 使用字符串方法替代正则表达式
  1. 多进程/多实例构建,资源并行解析可选方案,thread-loader、parallel-webpack、HappyPack 等等。
  2. 多进程/多实例,使用 HappyPack 解析资源,原理是每次 webpack 解析一个模块,HappyPack 会将它及它的依赖分配给 worker 线程中,代码如下:
export.plugins = [
  new HappyPack({
    id: 'jsx',
    threads: 4,
    loaders: ['babel-loader']
  }),
  
  new HappyPack({
    id: 'styles',
    threads: 2,
    loaders: ['style-loader', 'css-loader', 'less-loader']
  })
];
  1. 多进程/多实例,使用 thread-loader 解析资源,原理是每次 webpack 解析一个模块,threa-loader 会将它及它的依赖分配给 worker 线程中,代码如下:
module.exports = smp.wrap({
   entry: entry,
   output: {
    path: path.join(_dirname, 'dist'),
    filename: '[name]_[chunkhash:8].js'
  },
  mode: 'production',
  module: {
    rules: [
      {
         test: /.js$/,
         use: [
           {
             loader: 'thread-loader',
             options: {
                workers: 3
             }
           },
           'babel-loader',
           // 'eslint-loader'
         ]
      }
    ]
  }
})
  1. 多进程/多实例的并行压缩,如下所示:
  • 使用 parallel-uglify-plugin 插件,代码如下:
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');

module.exports = {
  plugins: [
     new ParallelUglifyPlugin({
         uglifyJS: {
            output: {
              beautify: false,
              comments: false,
            },
            compress: {
              warnings: false,
              drop_console: true,
              collapse_vars: true,
              reduce_vars: true
            }
         }
     })
  ]
};
  • uglifyjs-webpack-plugin 开启 parallel 参数,代码如下:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  plugins: [
     new UglifyJsPlugin({
        uglifyOptions: {
           warnings: false,
           parse: {},
           compress: {},
           mangle: true,
           output: null,
           toplevel: false,
           nameCache: null,
           ie8: false,
           keep_fnames: false
        },
        parallel: true
     })
  ]
};
  • terser-webpack-plugin 开启 parallel 参数,代码如下:
const TerserWebpackPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
     minimizer: [
       new TerserWebpackPlugin({
          parallel: 4
       })
     ]
  }
};
  1. 分包,设置 Externals,思路是将 react、react-dom 基础包通过 cdn 引入,不打入 bundle 中,方法是使用 html-webpack-externals-plugin
  2. 对于进一步分包,预编译资源模块,思路是将 react、react-dom、redux、react-redux 基础包和业务基础包打包成一个文件,方法是使用 DLLPlugin 进行分包,DllReferencePluginmanifest.json 引用,代码如下:
const path = require('path');
const webpack = require('webpack');

module.exports = {
  context: process.cwd(),
  resolve: {
    extensions: ['.js', '.jsx', '.json', '.less', '.css'],
    modules: [_dirname, 'node_modules']
  },
  entry: {
    library: [
      'react',
      'react-dom',
      'redux',
      'react-redux'
    ]
  },
  output: {
    filename: '[name].dll.js',
    path: path.resolve(_dirname, './build/library'),
    library: '[name]'
  },
  plugins: [
    new webpack.Dllplugin({
      name: '[name]',
      path: './build/library/[name].json'
    }}
  ]
};
  1. 使用 DllReferencePlugin 引用 manifest.json,在 webpack.config.js 引入,代码如下:
module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./build/library/manifest.josn')
    })
  ]
};
  1. 缓存的目的是提升二次构建速度,缓存思路,如下所示:
  • babel-loader 开启缓存
  • terser-webpack-plugin 开启缓存
  • 使用 cache-loader 或者 hard-source-webpack-plugin
  1. 缩小构建目标,目的是尽可能的少构建模块,比如 babel-loader 不解析 node_modules,代码如下:
module.exports = {
  rules: {
    test: /\.js$/,
    loader: 'happypack/loader',
    exclude: 'node_modules'
  }
}
  1. 减少文件搜索范围,优化 resolve.modules 配置,减少模块搜索层级,优化 resolve.mainFields 配置,优化 resolve.extensions 配置,合理使用 alias,代码如下:
module.exports = {
  resolve: {
    alias: {
      react: path.resolve(_dirname, './node_modules/react/dist/react.min.js'),
    },
    modules: [path.resolve(_dirname, 'node_modules')],
    extensions: ['.js'],
    mainFields: ['main'],
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值