沐光

记录在前端之路的点点滴滴

提升项目的构建速度

前言

随着项目的增大,越来越多的插件引入项目,使得项目的构建时间越来越长,而这很影响开发的效率。因此有没有一种方法能够优化构建的内容,提前构建好不怎么改动的插件依赖,而仅仅构建我们所写的业务代码呢?webpack 早已为我们考虑到了这个问题。

DllPlugin

简介

DllPlugin 的主要思想在于将项目内的一些不经常更改的依赖(比如 lodash)提前打包,使得项目构建时忽略这些打包文件,从而减少构建时间,提升构建速度。

参数与使用

1
new webpack.DllPlugin(options);

其中 options 含有如下参数:

  • context (optional): manifest 文件中请求的上下文(context)(默认值为 webpack 的上下文(context))
  • name: 暴露出的 DLL 的函数名 (TemplatePaths: [hash] & [name] )
  • path: manifest json 文件的绝对路径 (输出文件)

DllReferencePlugin

简介

简而言之,DllReferencePlugin 就是将 DllPlugin 打包的文件获取,在主 webpack 文件配置后,会让其在构建包时忽略掉 DllPlugin 内配置打包的文件,其依赖 DllPlugin 打包出的 manifest 文件。

参数与使用

1
new webpack.DllReferencePlugin(options);

其中 options 含有如下参数:

  • context: (绝对路径) manifest (或者是内容属性)中请求的上下文
  • manifest: 包含 content 和 name 的对象,或者在编译时(compilation)的一个用于加载的 JSON manifest 绝对路径
  • content (optional): 请求到模块 id 的映射 (默认值为 manifest.content)
  • name (optional): dll 暴露的地方的名称 (默认值为 manifest.name) (可参考 externals)
  • scope (optional): dll 中内容的前缀
  • sourceType (optional): dll 是如何暴露的 (libraryTarget)

注:与 output.library 保持 name 的一致性。

AddAssetHtmlPlugin

简介

将 dll 拆分的两个 plugin 配置好后,每次构建项目,推送远端之前都需要将我们的 dll 文件的引用动态添加到生成的 html 文件内,此插件就是实现该手动插入的过程

参数与使用

1
2
3
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

new AddAssetHtmlPlugin(options);

我们所关注的 options 配置:

  • filepath: 文件所在的地址,此处配置 dll 构建出的 .js 文件
  • outputPath: 在构建时,引用的文件最终打包至的位置
  • publicPath: script 脚本引用该文件时的绝对位置

注:此插件依赖 html-webpack-plugin,由于预构建项目内并不需要生成中间 html 文件,因此我们可以不用像示例那样配置 HtmlWebpackPlugin 来生成 .html 文件

配置示例

使用方法

初配置好或者依赖的内容有变动(比如:版本升级)使用此命令更新预打包的依赖,否则即使升级了包,最终打包后也不会有任何变化。

1
yarn dll

dllPlugins 部分配置

创建一个 webpack.dll.config.js 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');

// 配置公共请求路径
function resolve(dir) {
return path.join(__dirname, dir);
}

// dll文件存放的目录
const dllPath = '<target-file>';

module.exports = {
mode: 'production',
// 需要提取的依赖
entry: {
vendor: ['lodash'],
},
output: {
path: resolve(dllPath),
filename: '[name].dll.js',
// vendor.dll.js 中暴露出的全局变量名
// 保持与 webpack.DllPlugin 中名称一致
library: '[name]_[hash]',
},
plugins: [
// manifest.json 描述动态链接库包含了哪些内容
new webpack.DllPlugin({
path: path.join(__dirname, dllPath, 'manifest.json'),
// 保持与 output.library 中名称一致
name: '[name]_[hash]',
}),
// 清除之前打包的 dll 文件
new CleanWebpackPlugin({}),
],
};

主 webpack 打包文件配置

此处以 vue-cli3 来说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
chainWebpack: config => {
// 设置忽略打包的 vender 文件,添加已打包文件
config.plugin('dll').use(
new webpack.DllReferencePlugin({
manifest: require('./vendor/manifest.json'),
}),
);
// 将 dll 生成的 vender 自动注入到 html 文件中
config.plugin('insert').use(
new AddAssetHtmlPlugin({
// dll文件位置
filepath: path.resolve(__dirname, './vendor/*.js'),
// dll 引用 dist 路径
publicPath: 'js',
// dll最终打包到的 dist 目录位置
outputPath: 'js',
}),
);
},
};

package.json 配置

1
2
3
"scripts": {
"dll": "webpack --progress --config webpack.dll.config.js"
}

参考文档