由于第三方js文件变换的频率不是很大,所以利用webpack的commonChunkPlugin把第三方包打包到一起,但是发现每次改动业务文件的时候,第三方vendor文件会重新打包,如果输入文件名为[name].[chunkhash].js的话,可以看到每次都会输出新的文件,虽然在线上可以把vendor的chunkhash去掉来实现缓存效果,但是在开发和打包的时候编译速度还是多多少少会受影响。

dll定义

DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。

DllPlugin

DllPlugin可以把第三方文件打包单独的文件,例如vendor.dll.js,然后把相关的模块路径写到manifest.json文件,实现一次编译多次使用。

// webpack.dll.config.js

const webpack = require('webpack');
const path = require('path');

const vendors = [
    'react',
    'react-dom',
    'jquery',
];

module.exports = {
    // devtool: 'source-map',
    entry: {
        vendor: vendors,
    },
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: '[name]_[hash].dll.js',
        library: '[name]_[hash]',
    },
    plugins: [
        new webpack.DllPlugin({
            path: path.join(__dirname, 'dist/manifest.json'),
            name: '[name]_[hash]'
        }),
    ],
};

在控制台执行

webpack --config webpack.dll.config.js

文件夹dist生成manifest.jsonvendor_950817b068aac369aa25.dll.js两个文件

DllReferencePlugin

对生成的dll文件,我们需要在打包的时候通过DllReferencePlugin引入

// webpack.config.js

const ExtractTextPlugin = require("extract-text-webpack-plugin")
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const webpack = require("webpack");
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
    devtool: 'source-map',
    entry: {
        "index": './src/js/index.js',
    },
    output: {
        filename: "js/[name].[chunkhash].js",
        path: path.resolve(__dirname, "dist"),
    },
    module: {
        // loader
    },
    plugins: [
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require(path.join(__dirname, 'dist', 'manifest.json'))
        }),
        new ExtractTextPlugin('style/[name].[chunkhash].css'),
        new HtmlWebpackPlugin({
            chunks: ["index"],       // 只包含这个入口的文件
            filename: `index.html`,
            template: `src/index.html`
        }),
    ]
}

执行webpack打包,发现HtmlWebpackPlugin生成的html没有帮我们引入打包的dll文件,可以通过add-asset-html-webpack-plugin来引入

new AddAssetHtmlPlugin({
    includeSourcemap: false,
    filepath: path.join(__dirname,'dist/*.dll.js'),
})

在生成的html文件就会在script标签引入我们的dll.js文件,提升打包速度