使用 Webpack 的 DllPlugin 提升项目构建速度
栏目: JavaScript · 发布时间: 5年前
内容简介:本文介绍了 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 构建能力提升
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。