3

webpack打包优化策略一:
DllPlugin:
运行流程,
1、生成dll文件
新建一个webpack.dll.js 并运行webpack --config webpack.dll.js

const webpack = require('webpack');
const path = require('path');
module.exports = {
    entry: {
        react: ['react', 'react-dom']
    },
    output: {
        filename: 'dll_[name].js',
        library: "[name]_[hash]",
        path: path.resolve(__dirname, 'dist/site')
    },
    plugins: [
        new webpack.DllPlugin({
            context: __dirname,
            path: path.join(__dirname, 'dist/site', '[name]-mainfest.json'),
            name: '[name]_[hash]'
        }),
    ]
}

运行命令
webpack --config webpack.dll.js
相关属性解释:
entry: 在这里配置要打包的公共库文件,这里打包的是react和react-dom
output: 文件输出配置,其中filename是文件的打包输出名称,library是打包后库的名称,path是输出的路径。
plugins: webpack插件,这里使用DllPlugin将react和react-dom打包成dll文件,其中,path是dll文件的额映射json,作用是映射库名称和他对应的node_module里的路径,name是库的名称和output.library要保持一致。
思考tips:
为什么DllPlugin中的name要和output.libray保持一致?
因为dllPlugin会生成一个mainfest.json格式的映射文件,output时会跟进libray的值去mainfest.json里找对的name,然后找到对应的node_module的路径,打包输出。

这样一个dll_react.js就会生成了
react-mainfest.json的代码截图如下
image.png
输出的dll_react.js的代码截图如下
image.png
2、使用dll文件
新建webpack.config.js并运行webpack --config webpack.config.js
webapck.config.js

const path = require('path');
const webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        main: './src/index.js'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    mode: 'development',
    devServer: {
        contentBase: './dist',
        open: true,
        port: 8080,
        hot: true,
        hotOnly: true,
        historyApiFallback: true,
        publicPath: '/'
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /(node_modules)/,
                use: {
                loader: 'babel-loader'
                }
            },
            {
                test: /\.css/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'css-loader'
                }
            },
            {
                test: /\.(svg|png|jpg)/,
                use: {
                    loader: 'url-loader'
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: '测试',
            template: 'src/index.html'
        }),
        new webpack.DllReferencePlugin({
            // 描述 react 动态链接库的文件内容
            manifest: require('./dist/site/react-mainfest.json'),
        })
    ]
}

相关参数解释
entry: 配置入口文件
output:配置输出
mode: 配置生产还是测试环境
devserver配置开发环境
module:配置rule中的相关loader
plugins: 配置webpack的插件,其中DllReferencePlugin会根据之前生成的映射json,放入mainfest参数中
通过引用 dll 的 manifest 文件来把依赖的名称映射到模块的 id 上,之后再在需要的时候通过内置的__webpack_require__函数来require他们

HtmlWebpackPlugin,在这里处理html模板
相关代码如下:

<!DOCTYPE html>
<html>
    <script src="./site/dll_react.js"></script>
    <body>
        <div id="root">
            
        </div>
    </body>
</html>

最终生成的html如下:

<!DOCTYPE html>
<html>
    <script src="./site/dll_react.js"></script>
    <body>
        <div id="root">
            
        </div>
    <script src="main.js"></script></body>
</html>

第一次运行webpack --config webpack.dll.js
之后每次运行webpack --config webpack.config.js就行了

通过一组图片能更直观的感受到
dll文件生成用了2.18s
image.png
业务组件用了3.63s
image.png
不使用dll-plugin的情况下5.75s
image.png

总结:使用dll-plugin,会把公共库打包成一个单独的库文件,每次只需打包业务代码就行了,这样就减少了公共打包的那部分时间,整体速度得到了提升。


杨龙飞
45 声望2 粉丝

喜欢思考,喜欢前端,喜欢交友,喜欢玩