作为一名JavaScript开发人员,您可能有很多机会来使用webpack,无论是在将前端资产与React捆绑在一起还是在转换某些TypeScript, Node.js代码时。
大多数时候,您无需直接与Webpack交互。相反,您作为构建工具的依赖项与webpack间接交互。但是,如果您开发这些构建工具或管理自己的Webpack配置,则本教程将帮助您缩短构建时间。
我们将使用DLL插件,webpack承诺在其文档中“将大大缩短加载时间”。
它是如何工作的?
DLL插件创建了两个东西:
- 一个
manifest.json
文件 - 一些不常更改的模块
如果未启用DLL插件,则webpack会编译代码库中的所有文件,无论是否已对其进行修改。这具有使编译时间超出必要时间的作用。
但是有一种方法可以告诉webpack不要麻烦重新编译几乎不变的库:例如,node_modules
文件夹中的库。
这就是DLL插件的用处。它捆绑了您指定为很少更改的代码(例如,第三方库),并且从不重新编译它们,从而大大缩短了构建时间。
DLL插件通过创建manifest.json
来执行此操作。manifest.json
用于将import
请求map到对应模块。当从其它模块import
该模块时,webpack会检查文件中是否存在该模块的条目。如果是这样,它将跳过构建该模块的步骤。
概述
DLL插件应用于几乎不变的代码模块。因此,您需要一个单独的Webpack配置文件。在此处了解如何创建供应商捆绑包。
在本教程中,我们将使用两种Webpack配置。webpack.config.js
, webpack.vendor.config.js
webpack.config.js
将是业务相关代码的主要配置;即,经常修改的代码。
webpack.vendor.config.js
将用于不变的包,例如中的库node_modules
。
要使用DLL插件,必须在相应的webpack配置中安装两个插件:
DllReferencePlugin → webpack.config.js
DllPlugin → webpack.vendor.config.js
我们将使用Webpack版本4.x,因为5.x仍处于测试阶段。但是,它们都共享相似的配置。
配置DLL插件 webpack.vendor.config.js
DLL插件具有以下强制性选项:
-
name
:这是DLL函数的名称。它可以被称为任何东西。我们将其称为vendor_lib
-
path
:这是输出清单json文件的路径。它必须是绝对路径。我们将其存储在根目录下的“ build”文件夹中。该文件将被称为vendor-manifest.json
用path.join
指定路径
path.join(__dirname, 'build', 'vendor-manifest.json')`
确保webpack.vendor.config.js
的output.library
,和DLL的name
相同
包括任意数量的入口点。在此示例中,我包含了一些真正的重量级库。使用此插件时,输出文件夹无关紧要。
webpack.vendor.config.js
配置如下
var webpack = require('webpack')
const path = require('path');
module.exports = {
mode: 'development',
entry: {
vendor: ['lodash', 'react', 'angular', 'bootstrap', 'd3', 'jquery', 'highcharts', 'vue']
},
output: {
filename: 'vendor.bundle.js',
path: path.join(__dirname, 'build'),
library: 'vendor_lib'
},
plugins: [
new webpack.DllPlugin({
name: 'vendor_lib',
path: path.join(__dirname, 'build', 'vendor-manifest.json')
})
]
}
配置DllReferencePlugin webpack.config.js
DllReferencePlugin具有两个强制字段:
-
context
:这是包含构建文件夹的目录的绝对路径。保留__dirname
-
manifest
:这是DLL的清单json文件的绝对路径。我们将其设置为。path.join(__dirname, 'build', 'vendor-manifest.json')
webpack.config.js
配置如下
const webpack = require("webpack")
var path = require("path");
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
mode: 'development',
entry: {
app: ['./src/index.js']
},
output: {
filename: 'main.bundle.js',
path: path.join(__dirname, 'build')
},
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: path.join(__dirname, 'build', 'vendor-manifest.json')
}),
// new BundleAnalyzerPlugin()
]
})
这样,我们就完成了DLL插件的设置。
编译模块
生成DLL manifest.json
首先,您需要使用webpack.vendor.config.js
运行webpack ,这将生成webpack.config.js
所需的vendor.manifest.json
。当构建的配置发生更改或供应商捆绑包中的库版本发生更改时,可以在每次开发开始时进行此构建。
将此脚本添加到您的package.json
。它将创建manifest.json
和vender bunder:
"scripts": {
"buildVendor": "webpack --config webpack.vendor.config"
}
在随后的代码更改中,您只需更改webpack.config.js
编译 main bundle
然后为main bundle添加一个构建脚本:
"scripts": {
"buildVendor": "webpack --config webpack.vendor.config",
"build": "webpack --config webpack.config.js"
}
基准测试
为了测试插件,我在文件中实例化了一个简单的Vue.js应用程序。它的src/index.js
将导入一些重量级的依赖项:
import Vue from "vue"
import lodash from 'lodash'
import 'react'
import 'angular'
import 'bootstrap'
import 'd3'
import 'jquery'
import 'highcharts'
export default function createApp() {
// vendor()
const el = document.createElement("div")
el.setAttribute("id", "app")
document.body.appendChild(el)
console.log("hello")
new Vue({
el: "#app",
render: h => h("h1", "Hello world")
})
}
document.addEventListener('DOMContentLoaded', () => {
createApp()
})
要导入由webpack配置创建的两个捆绑包,我们需要在index.html
添加以下标签
<head>
<title>Webpack DllPlugin Test</title>
<script src="/build/vendor.bundle.js"></script>
<script src="/build/main.bundle.js"></script>
</head>
测试结果
使用DllPlugin
3370+(146.6 * 100)= 18030ms
没有DllPlugin
3312+(3583.6 * 100)= 361672ms
减少了95%的构建时间!极大地提高了生产率。
结论
此优化绝不适用于您的生产版本。它仅缓存指定的包以加快开发速度。
网友评论