头图

模块分包

为何需要对前端进行分包

在前端的自动化部署过程中,随着项目体积的不断增大,服务器打包的压力也在逐渐变大,打包时占用服务资源太大,这个时候就需要考虑如何减轻打包的压力。减轻的方式一般有两种:

  • 使用splitChunksPlugincommonChunksPlugin,抽出公共引用的代码,避免重复打包
  • 抽调公共模块或者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] )
pathmanifest.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.mapfilepath.gztrue
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')
    })
]

引入后即可在正常运行和打包工程


luxigaola
159 声望5 粉丝

开发者路西高辣