webpack4优化——提升你的编译效率

2,554 阅读2分钟

webpack4优化

背景分析

笔者现在的项目是一个通过webpack4构建的多入口工程,随着项目入口的增多,业务代码不断增加,项目深度不断延伸,团队里有个小妹子就开始抱怨了,构建时长时间太长了......于是乎,就要想着如何优化了。

这边以当前团队中用到的一个项目为例,在不断扩展业务模块的同时,首次构建时间已经达到了70s+,这就造成了组员每人执行dev或者build都可以去泡一杯茶再回来看看构建好了没,体验很差。

Snipaste_2019-11-04_11-21-55

优化步骤

  • 抽离文件 => dllPlugin
  • 多线程编译 => happypack
  • 缓存文件 => cache-loader

dllPlugin抽离文件

webpack.dll.config.js配置,抽离公共库,这里用到了webpack.DllPlugin这个插件,这个过程会生成manifest.json 的文件

dll: {
    vue: ['vue', 'vue-router', 'vuex'],
    axios: ['axios'],
    clipboard: ['clipboard'],
    vueAwesomeSwiper: ['vue-awesome-swiper'],
    qs: ['qs'],
    nativeshare: ['nativeshare'],
    mintUi: ['mint-ui'],
    jquery: ['jquery']
}
const path = require('path');
const webpack = require('webpack');
const config = require('../config');
module.exports = {
    entry: config.dll,
    output: {
        path: path.join(config.build.assetsRoot, config.build.assetsDllRoot),
        filename: '[name]_[hash].dll.js',
        library: '[name]_[hash]_library'
    },
    plugins: [
        new webpack.DllPlugin({
            path: path.join(config.build.assetsRoot, config.build.assetsManifestRoot, '[name]-manifest.json'),
            name: '[name]_[hash]_library'
        })
    ]
};

webpack.DllReferencePlugin,通过引用 dll 的 manifest 文件来把依赖的名称映射到模块的 id 上

const dllPlugin = () => {
    const { dll } = config;
    return Object.keys(dll).map(item => new webpack.DllReferencePlugin({
        manifest: require(path.join(config.build.assetsRoot, config.build.assetsManifestRoot, `${item}-manifest.json`))
    }));
};
plugins: [
    ...dllPlugin()
]

到此为止,通过上述步骤把公共库提前分离,我们在运行下dev或者build看下编译时间

Snipaste_2019-11-04_12-31-25

dllPlugin参考官方文档

happypack多线程编译

const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
rules: [{
    test: /\.js$/,
    use: ['happypack/loader?id=js'],
    exclude: /node_modules/
}]
plugins: [
        new HappyPack({
            id: 'js',
            threadPool: happyThreadPool,
            loaders: [ 'babel-loader' ]
        })
]

用上happypack,经过2次优化加速后,查看运行速度,缩减到52s,比第一次减少了20s

  • happypack的运行机制

HappyPack_Workflow

Snipaste_2019-11-04_12-39-06

happypack文档链接

缓存cache-loader

第二次构建时,利用上一次编译的缓存,而不是再次重复编译

module.exports = {
    module: {
        rules: [
            {
                test: /\.ext$/,
                use: [
                    'cache-loader',
                    ...loaders
                ],
                include: path.resolve('src')
            }
        ]
    }
}

第三次优化后查看编译效率,从70s+到17s+,当然这不是极致,优化还在进行

Snipaste_2019-11-04_12-51-04

cache-loader的参考链接

总结一下

通过本次优化,其核心优化的方向即一下三点

  • 提取分离那些不怎么变动的公共库 dllPlugin
  • 多核多线程打包happypack,多核,更是充分利用了硬件优势
  • 缓存cache-loader,缓存是为了让二次构建时,不需要再去做重复的工作

推荐几个webpack小工具

十分感谢star