一、webpack.DllPlugin和webpack.DllReferencePlugin 是干嘛的?
说白了,就是把项目里面依赖的第三方库,比如react, vue, echarts, moment 这些不会经常变动的包,提前打包好。
然后在webpack构建中,引入这些提前打包好的bundle的依赖(mainfest.json
),这样在项目构建时候,就不用每次都重复编译这些不经常变动的库,从而提高webpack的打包速度
二、使用方法,从0开始一步步来
1、新建一个工程,目录结构如下
2、public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DllPlugin和DllReferencePlugin</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
3、src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from '../App';
ReactDOM.render(
<App />,
document.getElementById('app'),
);
这里不是重点,只是用react项目做例子,不管是vue,react,等等,还是其他的,都是阔以
3、src/App.js
import React from 'react';
import moment from 'moment';
const App = () => (
<div>
我是React项目
<h1>react,还是vue项目,都无妨,这里不是重点</h1>
<h1> {moment().format('YYYY-MM-DD hh:mm:ss')}</h1>
</div>
);
export default App;
三、接下来,我们看下build里的东西 (用的是webpack 4.44.1)
安装包
npm i webpack webpack-cli html-webpack-plugin path clean-webpack-plugin babel-loader -D
npm i @babel/core @babel/preset-env @babel/preset-react -D
npm i react react-dom moment -S
1、首先看下咋门不用DllPlugin和DllReferencePlugin的时候的构建速度
build/webpack.base.conf.js
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: "production",
entry: {
app: path.resolve(__dirname, '../src/index.js'),
},
output: {
filename: "js/bundle.js",
path: path.resolve(__dirname, '../dist')
},
optimization: {
minimize: true,
},
module: {
rules: [
{
test: /\.(js|jsx)?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
},
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: 'public/index.html',
inject: 'body'
}),
],
};
2、package.json的scripts里面添加
"build": "webpack --config build/webpack.base.conf.js",
3、运行 npm run build
的结果
我们看到 bundle.js 非常大,速度6246秒多
4、现在加上,DllPlugin和DllReferencePlugin
- 在build/webpack.dll.config.js里面加上
new webpack.DllPlugin({
path: path.resolve(__dirname, '../static/[name]-manifest.json'),
name: '[name]_lib',
})
- build/webpack.dll.config.js全文件
const webpack = require('webpack');
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: "production",
entry: {
//把第三方库集中打包
vendor: ['react', 'react-dom', 'moment']
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, '../static'),
library: '[name]_lib',
},
plugins: [
new CleanWebpackPlugin(),
new webpack.DllPlugin({
path: path.resolve(__dirname, '../static/[name]-manifest.json'),
name: '[name]_lib', //这个name 和 library 对应
})
]
};
- 最后在 package.json里面加上
"build:dll": "webpack --config build/webpack.dll.config.js",
-
然后运行
npm run build:dll
, 此时在根目录下面自动创建了一个static
文件夹vendor.dll.js
是第第三方库的打包后的文件,vendor-manifest.json
是对第三方库的一个引用,(稍后再webpack.base.cong.js
里面用到),这样我们就把第三方库提前打包好了 -
接下再
webpack.base.cong.js
里面添加
new webpack.DllReferencePlugin({
manifest: require(path.join(__dirname, '../static/vendor-manifest.json'))
}),
- 然后再运行
npm run build
重新打包
此时`bundle.js`变成了`1.47kib`了和之前对比小了非常非常非常多。
而且速度也变成了 2200ms (之前是6246) 着实提升不少
那么这个时候我们看下`dist/index.html`还是没有自动引入提前打包号的`vendor.dll.js`
- 有两个方法引入
1:再public/index.html里面手动把static/vendor.dll.js引入到body后面
2:利用html-webpack-plugin 来引入
- 我们来用html-webpack-plugin自动引入
// webpack.base.conf.js里面添加
new HtmlWebpackPlugin({
template: 'public/index.html',
inject: 'body',
dllName: ['static/vendor.dll.js']
}),
- 修改public/index.html
<% if (htmlWebpackPlugin.options.dllName) { %>
<script src="<%=htmlWebpackPlugin.options.dllName%>"></script>
<% } %>
这里是ejs的语法,动态加载 HtmlWebpackPlugin 里面的 dllName
-
再运行
npm run build
此时看到dist/html里面打包后的文件已经引入了static/vendor.dll.js
-
利用 copy-webpack-plugin 把
static
里面的文件移动到dist
里面来
new CopyWebpackPlugin({
patterns: [
{ from: path.join(__dirname, '../static'),
to: path.join(__dirname, '../dist/static')},
],
}),
- 再运行
npm run build
,完成
来到dist
目录下 运行 anywhere
一、结语
感谢各位老铁,点赞加关注, demo地址: github.com/iwen-pengh/…