0
点赞
收藏
分享

微信扫一扫

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

一、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'],
  }
}
举报

相关推荐

0 条评论