模块分包
为何需要对前端进行分包
在前端的自动化部署过程中,随着项目体积的不断增大,服务器打包的压力也在逐渐变大,打包时占用服务资源太大,这个时候就需要考虑如何减轻打包的压力。减轻的方式一般有两种:
- 使用
splitChunksPlugin
或commonChunksPlugin
,抽出公共引用的代码,避免重复打包 - 抽调公共模块或者
node_modules
出来额外打包,降低一时间打包的压力
这两种方式并非是只能选其一,而是能双管齐下。一般情况下,其实使用方法1已经足够了,但不排除有特殊情况,使用splitChunks后还是感觉打包的压力略大,所以接下来就来讲讲如何使用webpack
进行模块分包
所需插件
DllPlugin1
此插件用于在单独的 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的类型 |
DllReferencePlugin2
此插件配置在 webpack
的主配置文件中,此插件会把 dll-only-bundles
引用到需要的预编译的依赖中。
属性 | 描述 |
---|---|
context | (绝对路径) manifest (或者是内容属性)中请求的上下文 |
extensions | 用于解析 dll bundle 中模块的扩展名 (仅在使用 'scope' 时使用)。 |
manifest | 用于解析 dll bundle 中模块的扩展名 (仅在使用 'scope' 时使用)。 |
content (可选) | 请求到模块 id 的映射(默认值为 manifest.content ) |
name (可选) | dll 暴露地方的名称(默认值为 manifest.name )(可参考externals) |
scope (可选) | dll 中内容的前缀 |
sourceType (可选) | dll 是如何暴露的 (libraryTarget) |
AddAssetHtmlPlugin3
该插件会将给定的 JS 或 CSS 文件添加到 Webpack
知道的文件中,并将其放入 html-webpack-plugin
注入到生成的 html
中的资产列表中。将插件添加到配置中,并为其提供一个文件路径
属性 | 描述 | 默认值 |
---|---|---|
filepath | 要添加到编译和生成的 HTML 文件的绝对路径 | 必须,除非已定义 glob |
glob | 用于查找要添加到编译中的文件的 glob。使用方法请参阅globby4 文档 | 必须,除非定义了filepath |
files | 默认情况下,资产将包含在所有文件中。如果定义了文件,资产将只包含在指定的文件球中 | [] |
hash | 如果为 "true",则会将文件的唯一哈希值追加到文件名中。这对消除缓存很有用 | false |
includeRelatedFiles | 如果为 "true",则会在编译时添加 filepath + '.*' 。例如,filepath.map 和 filepath.gz | true |
outputPath | 如果设置,将用作文件的输出目录 | |
publicPath | 如果设置,将用作脚本或链接标记的公共路径 | |
typeOfAsset | 设置为 css,以创建链接标记,而不是脚本标记 | js |
attributes | 要添加到生成标签中的额外属性。例如,在多填充脚本中添加 nomodule 就很有用。属性对象使用 key 作为属性名称,使用 value 作为属性值。如果 value 仅为 true,则不会添加任何值 | {} |
安装命令
npm i add-asset-html-webpack-plugin -D
### CleanWepackPlugin
该插件用于清除上次生成的包
#### 安装命令
npm i clean-webpack-plugin -D
使用方式
在工程中安装webpack cli
注意:安装webpack-cli依赖的webapck版本需与原工程一致
npm i webpack-cli -D
webpack.dll.conf.js
在工程根目录下添加webpack.dll.conf.js文件,并增加如下配置
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const Terserplugin = require('terser-webpack-plugin')
const { dependencies } = require('./package.json')
const DllPlugin = require('webpack').DllPlugin
const path = require('path')
module.exports = {
entry: {
node_modules: Object.keys(dependencies)
},
rules: [
{
test: /\.css$/i,
use: 'css-loader' // 将 CSS 转化成 CommonJs 模块
},
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
'style-loader',
'css-loader', // 将 Css 转化成 CommonJs 模块
'sass-loader' // 将 Sass 编译成 CSS
]
}
],
optimization: {
minimizer: [
new Terserplugin({
minify: Terserplugin.esbuildMinify,
parallel: 4, /* 使用多进程并行运行来提高构建速度 */
test: / \.js$/,
extractComments: false,
terserOptions: {
format: {
comments: false
},
compress: {
drop_console: false
}
}
})
],
minimize: true
},
output: {
path: path.join(__dirname, './dll'),
filename: '[name].dll.js',
// chunkfilename:'[name].dll.js'
library: '[name]_[hash]'
},
plugins: [
new CleanWebpackPlugin(),
new DllPlugin({
name: '[name]_[hash]',
path: path.join(__dirname, './dll', '[name].mainfest.json'),
context: __dirname
})
]
}
pakeage.json中添加打包命令
"scripts": {
"dll": "webpack --progress --config webpack.dll.conf.js"
}
运行命令生成插件
npm run dll
vue.config.js
在vue.config.js中引入打包的插件
const DllReferencePlugin = require('webpack').DllReferencePlugin
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
plugins:[
new AddAssetHtmlPlugin({
filepath:"./dll/node _modules.dll.js" //将生成的dll文件加入到index.html中
}),
new DllReferencePlugin({
context:__dirname,
mainfest:require("./dll/node_modules.mainfest.json')
})
]
引入后即可在正常运行和打包工程
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。