webpack之dllPlugin

343 阅读2分钟

用dllPlugin来干嘛

一般我们的代码被分为两部分,业务代码(build)和第三方库(ventor)。webpack在处理的时候,会将两部分都进行打包,但是第三方库一般是是稳定不变的,在这种情况下,多次对稳定的第三方库进行打包显得很没有必要。dllPlugin帮助我们将第三方库进行单独打包成一个文件(ventor.js),打包出来的业务代码(build.js)从ventor.js文件引用第三方库。这样,我们每次重新打包,就不需要重复打包第三方库,优化了打包的速度。

如何配置

// 第三方包单独打包的配置文件
module.exports = {
    entry: {
        ventor: ['react', 'react-dom'] // 传入数组,webpack会将多个包打包成一个chunk文件
    }, 
    output: {
        path,
        filename,
        library: '[name]' // 需要跟下面的dllPlugin.name一致
    },
    plugins: [
        new webpack.DllPlugin({
            name: '[name]' // 打包出的映射配置的name,
            path: path.resolve(__dirname, '/manifest.json') // 映射配置文件的打包输出地址

        })
    ]
}

// 根据上面的配置会打包出一个chunk文件和映射文件

// chunk文件代码类似以下
let ventor; // 这个变量名称🈶️output.library决定。挂载到全局上(window)
(function() {
    const modules = {
        'react': function(module, exports, require) { // reactku代码 },
        'react-dom': function(module, exports, require) { // reactku代码 }
    }

    function require(moduleId) {
       const module = { exports: {} };      
       modules[moduleId](module, exports, require)        return module.exports;
    }

    ventor = require;
})()

// manifest.json
{
    name: 'ventor', // 根据dllPlugin.name生成,打包业务代码的时候使用
    content: { // 映射集合,key为业务代码引用第三方包时的名称路径。value时第三方包在ventor.js里面对应的modules的key
        'react': 'react',
        'react-dom': 'react-dom'
    }
}


// 打包业务代码的配置
module.exports = {
    plugins: [
        new webpack.DllReferencePlugin({
            manifest: require('manifest.json') // 引用打包出的映射文件        })
    ]
}

// 根据上面的配置,会打包出类似下面的业务代码
// 假设入口文件代码为import React from 'react';
(function() {
    const modules = {
        'index.js':function(module, exports, webpack_require) {
            const React = webpack_require('react')
        },
        'react': function(module, exports, webpack_require) {
            // 引用ventor.js导出的ventor加载函数(ventor.js加载之后该函数会挂载到全局),加载第三方包
            // ventor变量对应manifest.json的name字段。所以dllPlugin.name要跟output.library一致
            module.exports = ventor('react'); 
        }
    }

    function webpack_require(moduleId) {
        const module = { exports: {} };
        modules[moduleId](module, exports, require);
        return module.exports;
    }
    webpack_require('index.js') // 执行入口文件
})()

参考文档

segmentfault.com/a/119000001…