使用 Webpack 的 DllPlugin 提升项目构建速度
栏目: JavaScript · 发布时间: 7年前
内容简介:本文介绍了 Webpack 中 DllPlugin 插件的使用,以及配合使用 AddAssetHtmlPlugin 将构建好的 JS 文件插入到 html 页面中。本文项目代码位置:欢迎 Star!
本文介绍了 Webpack 中 DllPlugin 插件的使用,以及配合使用 AddAssetHtmlPlugin 将构建好的 JS 文件插入到 html 页面中。
本文 Demo 地址
本文项目代码位置: 源码地址
欢迎 Star!
DLLPlugin 和 DllReferencePlugin 简介
DLLPlugin 就是将包含大量复用模块且不会频繁更新的库进行编译,只需要编译一次,编译完成后存在指定的文件(这里可以称为动态链接库)中。在之后的构建过程中不会再对这些模块进行编译,而是直接使用 DllReferencePlugin 来引用动态链接库的代码。因此可以大大提高构建速度。一般会对常用的第三方模块使用这种方式,例如 react、react-dom、lodash 等等。只要这些模块不升级更新,这些动态链接库就不需要重新编译。
在 Webpack 中进行使用
需要插件
Webpack 已经内置了对动态链接库的支持,需要通过两个内置插件的配合使用。它们分别是:
- DllPlugin 插件:用于打包出一个个单独的动态链接库文件
- DllReferencePlugin 插件:用于在主配置文件中去引入 DllPlugin 插件打包好的动态链接库文件
创建项目
找一个空文件夹,打开命令行,执行命令
# 创建项目目录 $ mkdir webpack-dll-demo # 初始化 package.json 文件 $ npm init -y # 创建 src 文件夹 $ mkdir src # 创建 public 文件夹 $ mkdir public # 安装需要用到的插件 $ npm install webpack webpack-cli html-webpacl-plugin clean-webpacl-plugin friendly-errors-webpack-plugin -D # 安装 lodash 插件,用于演示 DllPlugin 用法 $ npm install lodash 复制代码
在 public 目录下创建 index.html 文件
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>Webpak DllPlugin 的使用</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
复制代码
在 src 目录下创建 index.js 文件
index.js
import { join } from 'lodash';
function createSpan(){
const element = document.createElement('span');
element.innerHTML = join(['Hello', 'DllPlugin'], ' , ');
return element;
}
document.querySelector('#root').appendChild(createSpan());
复制代码
当前项目目录结构
webpack-prod-demo |- /public |- index.html |- /src |- index.js |- package.json 复制代码
使用 DllPlugin 和 DllReferencePlugin(分为三步)
一、先编写一个配置文件专门用来编译生成动态链接库(使用 DllPlugin)
webpack_dll.config.js
const path = require('path');
const webpack = require('webpack');
const CleanWebpaclPlugin = require('clean-webpack-plugin');
const FirendlyErrorePlugin = require('friendly-errors-webpack-plugin');
module.exports = {
mode: 'production',
entry: {
// 将 lodash 模块作为入口编译成动态链接库
lodash: ['lodash']
},
output: {
// 指定生成文件所在目录
// 由于每次打包生产环境时会清空 dist 文件夹,因此这里我将它们存放在了 public 文件夹下
path: path.resolve(__dirname, 'public/vendor'),
// 指定文件名
filename: '[name].dll.js',
// 存放动态链接库的全局变量名称,例如对应 lodash 来说就是 lodash_dll_lib
// 这个名称需要与 DllPlugin 插件中的 name 属性值对应起来
// 之所以在前面 _dll_lib 是为了防止全局变量冲突
library: '[name]_dll_lib'
},
plugins: [
new CleanWebpaclPlugin(['vendor'], {
root: path.resolve(__dirname, 'public')
}),
new FirendlyErrorePlugin(),
// 接入 DllPlugin
new webpack.DllPlugin({
// 描述动态链接库的 manifest.json 文件输出时的文件名称
// 由于每次打包生产环境时会清空 dist 文件夹,因此这里我将它们存放在了 public 文件夹下
path: path.join(__dirname, 'public', 'vendor', '[name].manifest.json'),
// 动态链接库的全局变量名称,需要和 output.library 中保持一致
// 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
// 例如 lodash.manifest.json 中就有 "name": "lodash_dll_lib"
name: '[name]_dll_lib'
})
]
}
复制代码
二、编写配置文件用来打包项目(使用 DllReferencePlugin)
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpaclPlugin = require('clean-webpack-plugin');
const FirendlyErrorePlugin = require('friendly-errors-webpack-plugin');
module.exports = {
mode: 'production',
devtool: 'source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'build-[hash:5].js'
},
plugins: [
new HTMLWebpackPlugin({
title: 'Webpak DllPlugin 的使用',
template: './public/index.html'
}),
new CleanWebpaclPlugin(['dist']),
new FirendlyErrorePlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
// 告诉 Webpack 使用了哪些动态链接库
new webpack.DllReferencePlugin({
// 描述 lodash 动态链接库的文件内容
manifest: require('./public/vendor/lodash.manifest.json')
})
]
}
复制代码
三、在 index.html 文件中引入动态链接库
由于动态链接库我们一般只编译一次,之后就不用编译,复用模块都被打包到了动态链接库中,因此入口的 index.js 文件中已经不包含这些模块了,所以要在 index.html 中单独引入。
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>Webpak DllPlugin 的使用</title>
</head>
<body>
<div id="root"></div>
<script src="../public/vendor/lodash.dll.js"></script>
</body>
</html>
复制代码
注意:由于在打包项目的时候会清理掉 dist 文件,所以我将生成的动态链接库放到了 public 目录下,所以这里是引入 public 下的动态链接库。
我们在 package.json 中添加两条指令:
- build:打包项目
- build:dll:编译生成动态链接库
package.json
...
"scripts": {
"build": "webpack --config webpack.config.js",
"build:dll": "webpack --config webpack_dll.config.js"
}
...
复制代码
运行
根据上面所说的三个步骤,Dll 的用法已经结束了。现在我们运行一下看看结果。
打开命令行,执行命令
# 生成动态链接库,只需要运行一次这个指令,以后打包项目不需要再执行这个指令 $ npm run build:dll # 打包项目 $ npm run build 复制代码
在浏览器中打开 dist 文件夹下的 index.html 文件,可以看到浏览器上出现:Hello , DllPlugin。说明项目配置成功。
DllPlugin 和 DllReferencePlugin 分别做了什么
运行 npm run build:dll
指令之后,可以看到项目中 public 目录下多出了一个 vendor 的文件夹,可以看到其中包含两个文件:
-
lodash.dll.js里面包含lodash的基础运行环境,也就是 lodash 模块 -
lodash.manifest.json也是由 DllPlugin 生成出,用于描述动态链接库文件中包含哪些模块
lodash.dll.js
var lodash_dll_lib=... // 此处代码过多,进行省略 复制代码
lodash.manifest.json
{"name":"lodash_dll_lib","content":{"./node_modules/lodash/lodash.js":{"id":1,"buildMeta":{"providedExports":true}},"./node_modules/webpack/buildin/global.js":{"id":2,"buildMeta":{"providedExports":true}},"./node_modules/webpack/buildin/module.js":{"id":3,"buildMeta":{"providedExports":true}}}}
复制代码
对比之后可以明白:
-
一个动态链接库文件中包含了大量模块的代码,这些模块存放在一个数组里,用数组的索引号作为 ID。 并且还通过 lodash_dll_lib 变量把自己暴露在了全局中,也就是可以通过 window.lodash_dll_lib 可以访问到它里面包含的模块
-
manifest.json 文件清楚地描述了与其对应的 dll.js 文件中包含了哪些模块,以及每个模块的路径和 ID
至此,Dll 的使用以及配置完成了。但是这里还有值得思考的地方:目前看来,项目可以正常运行,但是现在动态链接库是存放到 public 目录下的,如果我们需要将项目打包上线的话,如何能够让动态链接库自动也存放到 dist 目录下呢?如何在我们不手动添加脚本的情况下,自动将动态链接库引入到 index.html 文件中呢?如果有兴趣的话,可以继续往下来看一看配合 add-asset-html-webpack-plugin 的使用。
add-asset-html-webpack-plugin 的使用
上面也已经说了,虽然 Dll 的使用和配置没有问题了,但是还不是很满意,打包的时候不能将动态链接库自动的存放到 dist 文件夹,也不能自动在 html 文件中引入动态链接库脚本。所以这时候 add-asset-html-webpack-plugin 就派上用场了。
安装插件
$ npm install add-asset-html-webpack-plugin -D 复制代码
使用
在 webpack.config.js 文件中进行使用
webpack.config.js
...;
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
...,
plugins: [
...,
// 该插件将把给定的 JS 或 CSS 文件添加到 webpack 配置的文件中,并将其放入资源列表 html webpack插件注入到生成的 html 中。
new AddAssetHtmlPlugin([
{
// 要添加到编译中的文件的绝对路径,以及生成的HTML文件。支持globby字符串
filepath: require.resolve(path.resolve(__dirname, 'public/vendor/lodash.dll.js')),
// 文件输出目录
outputPath: 'vendor',
// 脚本或链接标记的公共路径
publicPath: 'vendor'
}
])
]
}
复制代码
此时可以删除 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>Webpak DllPlugin 的使用</title>
</head>
<body>
<div id="root"></div>
<!-- 删除下面这行引入脚本 -->
- <script src="../public/vendor/lodash.dll.js"></script>
</body>
</html>
复制代码
运行项目
打开命令行,执行命令:
# 打包项目 $ npm run build 复制代码
-
现在查看项目中 dist 文件夹,可以看到 public 目录下 vendor 文件夹中的 js 文件已经全部自动拷贝到 dist 目录中的 vendor 文件夹下了
-
打开 dist 文件夹中的 index.html 文件,可以看到已经自动将生成的脚本文件引入了
-
在浏览器中打开 index.html,可以看到 'Hello , DllPlugin' 也能够正常显示
add-asset-html-webpack-plugin 更多配置请参考 github 地址: AddAssetHtmlPlugin 配置
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 在 Android Studio 里使用构建分析器提升构建性能
- 使用 happypack 提升 Webpack 项目构建速度
- 构建安全计划 提升应用程序安全能力
- Next.js 7发布,构建速度提升40%
- 探索webpack构建速度提升方法和优化策略
- 码云 Jenkins 插件更新 1.1.2 ,PR 构建能力提升
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First HTML5 Programming
Eric Freeman、Elisabeth Robson / O'Reilly Media / 2011-10-18 / USD 49.99
What can HTML5 do for you? If you're a web developer looking to use this new version of HTML, you might be wondering how much has really changed. Head First HTML5 Programming introduces the key featur......一起来看看 《Head First HTML5 Programming》 这本书的介绍吧!