webpack优化

141 阅读2分钟

优化开发体验

优化构建速度 优化使用体验 优化输出质量

webpack工作原理

  • 初始化:启动构建,读取与合并配置参数,加载Plugin,实例化Compiler
  • 编译:从Entry触发,针对每个module,调用loader去翻译文件内容,递归进行编译处理
  • 输出:将编译后的module组合成chunk,将chunk转换成文件,输出到系统

优化Loader配置

由于Loader对文件的转化操作很好使,所以尽可能少的文件被Loader处理

  • resolve.module
 resolve: {
    //  __dirname: 当前工作目录,项目跟目录
    modules: [path.resolve(__dirname), 'node_modules'],
    // 先尝试 ts,tsx 后缀的 TypeScript 源码文件
    extensions: ['.ts', '.js']
  },
  • resolve.alias

DllPlugin 动态链接库

  • 将网页依赖的基础模块抽离出来,打包到一个个单独的动态链接库中
  • 当需要导入的模块存在于某个动态链接库时,这个模块不能被再次打包,而去动态链接库中引用

使用HappyPack

将任务分解给多个子进程去并发执行,子进程处理完后再将结果发送给主线程

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HappyPack = require('happypack');

module.exports = {
  module: {
    rules: [
      {
        test: /.js$/,
        // 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
        use: ['happypack/loader?id=babel'],
        // 排除 node_modules 目录下的文件,node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
        exclude: path.resolve(__dirname, 'node_modules'),
      },
      {
        // 把对 .css 文件的处理转交给 id 为 css 的 HappyPack 实例
        test: /.css$/,
        use: ExtractTextPlugin.extract({
          use: ['happypack/loader?id=css'],
        }),
      },
    ]
  },
  plugins: [
    new HappyPack({
      // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
      id: 'babel',
      // 如何处理 .js 文件,用法和 Loader 配置中一样
      loaders: ['babel-loader?cacheDirectory'],
      // ... 其它配置项
    }),
    new HappyPack({
      id: 'css',
      // 如何处理 .css 文件,用法和 Loader 配置中一样
      loaders: ['css-loader'],
    }),
    new ExtractTextPlugin({
      filename: `[name].css`,
    }),
  ],
};

压缩代码

使用 ParallelUglifyPlugin、 UglifyJsPlugin

使用ParallelUglifyPlugin会开启多个子进程,将多个文件的压缩工作分配给多个子进程 UglifyPlugin: 一个个压缩并输出

CDN加速

Tree Shaking

剔除项目中不用的死代码

提取公共代码

  • CommonsChunkPlugin
    new CommonsChunkPlugin({
      // 从 common 和 base 两个现成的 Chunk 中提取公共的部分
      chunks: ['common', 'base'],
      // 把公共的部分放到 base 中
      name: 'base'
    }),
  • 分割代码,按需加载

将每一类合并为一个Chunk

使用Prepack

prepack-webpack-plugin

优化代码在运行时的效率

开启 Scope Hoisting

作用域提升 打包出的代码文件更小,运行更快

  • 原理:分析某块之间的依赖关系,尽可能将被打散的模块合并到一个函数中
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
module.exports = {
  plugins: [
    // 开启 Scope Hoisting
    new ModuleConcatenationPlugin(),
  ],
};