DllPlugin
和 DllReferencePlugin
用某种方法实现了拆分 bundles,同时还大幅度提升了构建的速度。"DLL" 一词代表微软最初引入的动态链接库。
DllPlugin
此插件用于在单独的 webpack 配置中创建一个 dll-only-bundle。 此插件会生成一个名为 manifest.json
的文件,这个文件是用于让 DllReferencePlugin 能够映射到相应的依赖上。
context
(可选): manifest 文件中请求的 context (默认值为 webpack 的 context)format
(boolean = false):如果为true
,则 manifest json 文件 (输出文件) 将被格式化。name
:暴露出的 DLL 的函数名(TemplatePaths:[fullhash]
&[name]
)path
:manifest.json 文件的 绝对路径(输出文件)entryOnly
(boolean = true):如果为true
,则仅暴露入口type
:dll bundle 的类型
new webpack.DllPlugin(options);
在给定的 path
路径下创建一个 manifest.json
文件。这个文件包含了从 require 和 import 中 request 到模块 id 的映射。 DllReferencePlugin
也会用到这个文件。
此插件与 output.library 的选项相结合可以暴露出(也称为放入全局作用域)dll 函数。
DllReferencePlugin
此插件配置在 webpack 的主配置文件中,此插件会把 dll-only-bundles 引用到需要的预编译的依赖中。
context
:(绝对路径) manifest (或者是内容属性)中请求的上下文extensions
:用于解析 dll bundle 中模块的扩展名 (仅在使用 'scope' 时使用)。manifest
:包含content
和name
的对象,或者是一个字符串 —— 编译时用于加载 JSON manifest 的绝对路径content
(可选): 请求到模块 id 的映射(默认值为manifest.content
)name
(可选):dll 暴露地方的名称(默认值为manifest.name
)(可参考externals)scope
(可选):dll 中内容的前缀sourceType
(可选):dll 是如何暴露的 (libraryTarget)
new webpack.DllReferencePlugin(options);
通过引用 dll 的 manifest 文件来把依赖的名称映射到模块的 id 上,之后再在需要的时候通过内置的 __webpack_require__
函数来 require
对应的模块。
dll配置创建 webpack.dll.config.js
const path = require('path')
const DllPlugin = require('webpack/lib/DllPlugin')
const { srcPath, distPath } = require('./paths')
module.exports = {
mode: 'development',
// JS 执行入口文件
entry: {
// 把 React 相关模块的放到一个单独的动态链接库
react: ['react', 'react-dom']
},
output: {
// 输出的动态链接库的文件名称,[name] 代表当前动态链接库的名称,
// 也就是 entry 中配置的 react 和 polyfill
filename: '[name].dll.js',
// 输出的文件都放到 dist 目录下
path: distPath,
// 存放动态链接库的全局变量名称,例如对应 react 来说就是 _dll_react
// 之所以在前面加上 _dll_ 是为了防止全局变量冲突
library: '_dll_[name]',
},
plugins: [
// 接入 DllPlugin
new DllPlugin({
// 动态链接库的全局变量名称,需要和 output.library 中保持一致
// 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
// 例如 react.manifest.json 中就有 "name": "_dll_react"
name: '_dll_[name]',
// 描述动态链接库的 manifest.json 文件输出时的文件名称
path: path.join(distPath, '[name].manifest.json'),
}),
],
}
打包:
在我们的index.html引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="./react.dll.js"></script>
</body>
</html>
使用DllReferencePlugin
const path = require('path')
const webpack = require('webpack')
const { smart } = require('webpack-merge')
const webpackCommonConf = require('./webpack.common.js')
const { srcPath, distPath } = require('./paths')
// 第一,引入 DllReferencePlugin
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin');
module.exports = smart(webpackCommonConf, {
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
loader: ['babel-loader'],
include: srcPath,
exclude: /node_modules/ // 第二,不要再转换 node_modules 的代码
},
]
},
plugins: [
new webpack.DefinePlugin({
// window.ENV = 'production'
ENV: JSON.stringify('development')
}),
// 第三,告诉 Webpack 使用了哪些动态链接库
new DllReferencePlugin({
// 描述 react 动态链接库的文件内容
manifest: require(path.join(distPath, 'react.manifest.json')),
}),
// 因为我们生成的缓存代码是在dll文件夹,我们要借助以下插件把dll下的文件帮运到dist文件夹下面
new AddAssetHtmlWebpackPlugin({
outputPath:"../dist",
filepath:path.resolve(__dirname, "../dll/_dll_react.js")
}),
],
devServer: {
port: 8080,
progress: true, // 显示打包的进度条
contentBase: distPath, // 根目录
open: true, // 自动打开浏览器
compress: true, // 启动 gzip 压缩
// 设置代理
proxy: {
// 将本地 /api/xxx 代理到 localhost:3000/api/xxx
'/api': 'http://localhost:3000',
// 将本地 /api2/xxx 代理到 localhost:3000/xxx
'/api2': {
target: 'http://localhost:3000',
pathRewrite: {
'/api2': ''
}
}
}
}
})