DllPlugin
DllPlugin 和 DllReferencePlugin 用某种方法实现了拆分 bundles,同时还大幅度提升了构建的速度。"DLL" 一词代表微软最初引入的动态链接库。
通过使用 DllPlugin 可以拆分项目中版本不经常变更的或者包大小比较大的三方依赖。将依赖拆分成单独的 bundles,这样可以提升项目打包速度、减少包体积来加快加载速度。
使用
本章中主要介绍 DllPlugin 的使用及配置,由于需要打包第三方依赖库,所以下面以 lodash 为例。
安装 lodash
npm install loadsh --save-dev
webpack.config.dll.js
新建一个 webpack.config.dll.js 文件,用来添加 dll 配置,在执行打包命令之前先生成 dll 文件。
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
lodash: ['lodash']
},
output: {
filename: '[name]_dll.js',
library: "[name]",
path: path.resolve(__dirname, 'dist/dll')
},
plugins: [
new webpack.DllPlugin({
context: __dirname,
path: path.join(__dirname, 'dist/dll', '[name]-mainfest.json'),
name: '[name]'
}),
]
}
在上面的配置中,entry 为项目入库文件,output 为项目输出文件名称及输出目录。其中要注意的是 output 中的 library 参数,增加 library 配置后 mainfest.json 会暴露 dll 库的全局名称。此参数定义的名称要与 DllPlugin 插件中的 name 属性定义名称一致。
在命令行执行 npx webpack --config webpack.config.dll.js 命令,打包成功后在 dist 文件下可以看到生成了一个 dll.js 一个 mainfest.json 文件。
配置
context
默认值:webpack 的 context
值类型:String
作用:生成的 manifest.json 文件中 content 对象中的文件映射地址。
webpack.config.dll.js
module.exports = {
plugins: [
new webpack.DllPlugin({
// {"name":"vendors","content":{"./node_modules/lodash/lodash.js":{"id":486,"buildMeta":{}}}}
context: __dirname // 根目录地址
// 下面的 mainfest.json 文件将找不到 lodash.js,映射地址错误
// {"name":"vendors","content":{"../node_modules/lodash/lodash.js":{"id":486,"buildMeta":{}}}}
// context: 'src'
}),
]
};
format
默认值:false
值类型:Boolean
作用:如果值为 true,生成的 mainfest.json 文件将被格式化。
webpack.config.dll.js
module.exports = {
plugins: [
new webpack.DllPlugin({
// {"name":"vendors","content":{"./node_modules/lodash/lodash.js":{"id":486,"buildMeta":{}}}}
format: false,
// {
// "name": "vendors",
// "content": {
// "./node_modules/lodash/lodash.js": {
// "id": 486,
// "buildMeta": {}
// }
// }
// }
format: true
}),
]
};
name
默认值:''
值类型:String
作用:生成的 mainfest.json 文件中的 name 属性值。
webpack.config.dll.js
module.exports = {
...
plugins: [
new webpack.DllPlugin({
// {"name":"lodash-name","content":{"./node_modules/lodash/lodash.js":{"id":486,"buildMeta":{}}}}
name: "lodash-name"
})
]
};
path
默认值:无(必须)
值类型:String
作用:生成 mainfest.json 文件的路径。
webpack.config.dll.js
module.exports = {
...
plugins: [
new webpack.DllPlugin({
// 在根目录的 dist/dll 文件夹下生成 [name]-mainfest.json
path: path.join(__dirname, 'dist/dll', '[name]-mainfest.json'),
})
]
};
entryOnly
默认值:true
值类型:Boolean
作用:如果为 true,则仅暴露入口。
webpack.config.dll.js
module.exports = {
...
plugins: [
new DllPlugin({
entryOnly: false
})
]
};
建议 DllPlugin 只在 entryOnly: true 时使用,否则 DLL 中的 tree shaking 将无法工作,因为所有 exports 均可使用。
type
类型:"var" | "module" | "assign" |"assign-properties" | "this" | "window" | "self" | "global" | "commonjs" | "commonjs2" | "commonjs-module" |"commonjs-static" | "amd" | "amd-require" | "umd" | "umd2" | "jsonp" | "system"
作用:配置 dll 库暴露的方式。
webpack.config.dll.js
module.exports = {
...
plugins: [
new DllPlugin({
// {"name":"lodash-name","type":"window","content":{"./node_modules/lodash/lodash.js":{"id":486,"buildMeta":{}}}}
type: 'window'
})
]
};
总结
此章节演示了 DllPlugin 的用法和包含的配置参数。生成的 dll.js 和 mainfest.json 文件,在下个 DllReferencePlugin 章节来展示如何使用。
DllReferencePlugin
在上一章节的 DllPlugin 插件中,DllPlugin 插件会将第三方依赖生成一个 [name]-dll.js 文件和一个 [name]-manifest.json 文件,其中 [name]-dll.js 文件包含第三方依赖所有的源码,[name]-manifest.json 文件包含所有第三方依赖的名称位置和与 [name]-dll.js 映射的索引 ID,执行相应命令生成了 [name]-dll.js 和 [name]-manifest.json 后,就可以执行工程的打包命令。在 webpack 打包过程中,通过 DllReferencePlugin 插件,可以将 [name]-manifest.json 文件中的第三方依赖的映射关系进行解析,当检索到有第三方依赖的映射关系时,会将三方依赖索引 ID 值注入到使用依赖的文件中。如果没有检索到三方依赖映射关系,将去 node_modules 或者项目中查找并将检索内容添加到需要使用依赖的文件中。
使用
index.js
import _ from 'lodash';
import { name } from './main.js';
console.log(_.join(['hello', 'world'], '-'))
console.log(name);
main.js
export const name = 'dll';
webpack.config.dll.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
vendors: ['lodash', './src/main.js'],
},
output: {
filename: '[name]-dll.js',
library: "[name]",
path: path.resolve(__dirname, 'dist/dll')
},
plugins: [
new webpack.DllPlugin({
context: __dirname,
path: path.join(__dirname, 'dist/dll', '[name]-manifest.json'),
name: '[name]',
format: true
}),
]
}
在上面的配置中,将 lodash 和本地 main.js 生成 dll 文件。
webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
},
output: {
path: path.resolve(__dirname, "dist"),
filename: '[name].js'
},
plugins: [
new webpack.DllReferencePlugin({
// 对动态链接库的文件内容的描述或者映射关系,非 dll 本身
manifest: require('./dist/dll/vendors-manifest.json'),
})
]
}
在 webpack.config.js 的 DllReferencePlugin 插件中引入 DllPlugin 插件生成的 manifest.json 文件。执行 npm run build 打包命令。我们看下生成的 index.js 文件内容。
从上面的截图我们可以看到 DllReferencePlugin 插件解析了 manifest.json 中的第三方依赖对应的映射关系,将 ID 值传入到 index.js 的方法中,我们接下来需要手动将 dll/vendors-dll.js 通过 <script> 标签添加到 index.html 中。vendors-dll.js 文件中包含第三方依赖的代码和 manifest.json 中的 ID 值,index.js 中通过加载 ID 值来使用第三方依赖方法。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script defer src="./dll/vendors-dll.js"></script>
<script defer src="index.js"></script></head>
<body>
</body>
</html>
在浏览器中打开 index.html 文件,在控制台可以看到输出的内容,main.js 和 lodash 方法均可正常使用。
DllReferencePlugin 在解析 manifest.json 文件时,虽然 manifest.json 包含多个第三方依赖的映射关系,但是插件会根据 index.js 中的引用来注入对应的代码。即当 index.js 中只引用了 main.js 文件时,打包后生成的 index.js 文件则只包含 main.js 的映射关系。在实际的项目中,就可以将不常改动的第三方依赖打包成 dll,将 dll 的链接通过 CDN 等方式引入到项目中,这样可以减少主包的大小,加快打包速度。
注意:[name]-dll.js 可以通过插件动态插入到 index.html,小伙伴儿可自行查阅。
配置
context
类型:String
默认值:webpack 的 context
作用:(绝对路径) manifest 中请求的上下文。
webpack.config.js
module.exports = {
plugins: [
new webpack.DllReferencePlugin({
...
context: __dirname // 根目录地址
// 下面的配置会在 dist 文件夹下查找 manifest 的地址,当找不到 manifest.json 文件时,会将依赖代码打包到 bundle.js 中
// path.resolve(__dirname, "dist")
}),
]
};
manifest
类型:String
作用:用于加载 manifest.json 路径。
webpack.config.js
module.exports = {
plugins: [
new webpack.DllReferencePlugin({
// 动态链接库的文件内容
manifest: require('./dist/dll/vendors-manifest.json'),
}),
]
};
name
类型:String
默认值:manifest.json 的 name 属性。
作用:[name]-dll.js 暴露的全局变量方法名称,将 manifest.json 中的 索引 ID 传入全局方法中,可返回对应模块方法。
index.js
其中的 vendors(225),vendors 为 dll 暴露的全局变量,225 为 manifest.json 中 main.js 依赖的 ID 索引值。
import _ from 'lodash';
import { name } from './main.js';
console.log(_.join(['hello', 'world'], '-'))
console.log(vendors(225));
console.log(vendors(225).plugin);
main.js
export const plugin = 'dll';
webpack.config.js
module.exports = {
...
plugins: [
new webpack.DllReferencePlugin({
...
name: 'vendors'
})
]
};
打包成功后,控制台打开 dist/index.html,可以看到 输出了 hello-world、 main.js 模块代码和 main.js 代码中的 plugin 变量。
content
类型:Object
默认值:manifest.json 的 content 属性。
作用:传入请求依赖到模块 ID 的映射关系。
webpack.config.js
module.exports = {
...
plugins: [
new webpack.DllReferencePlugin({
content: {
"./src/main.js": {
"id": 225,
"exports": [
"plugin"
]
},
}
})
]
};
sourceType
类型:"var" | "assign" | "this" | "window" | "global" | "commonjs" | "commonjs2" | "commonjs-module" | "amd" | "amd-require" | "umd" | "umd2" | "jsonp" | "system"
作用:dll 中的模块代码以哪种模式暴露给外部调用 output.library.type
index.js
import { name } from './main.js';
console.log(window.vendors(225));
webpack.config.js
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
...
sourceType: 'window'
})
]
};
总结
此章节演示了 DllReferencePlugin 的用法和包含的配置参数。DllReferencePlugin 通过解析 manifest.json 将依赖的映射索引注入到需要的依赖中。通过将不常变动的依赖打包成 dll 的方式,可以减少 bundle 的大小,同时能加快打包速度。
阅读量:648
点赞量:0
收藏量:0