使用DLL插件优化的Webpack

2021-02-06  本文已影响0人  魂斗驴
webpack

作为一名JavaScript开发人员,您可能有很多机会来使用webpack,无论是在将前端资产与React捆绑在一起还是在转换某些TypeScript, Node.js代码时。

大多数时候,您无需直接与Webpack交互。相反,您作为构建工具的依赖项与webpack间接交互。但是,如果您开发这些构建工具或管理自己的Webpack配置,则本教程将帮助您缩短构建时间。

我们将使用DLL插件,webpack承诺在其文档中“将大大缩短加载时间”。

它是如何工作的?

DLL插件创建了两个东西:

如果未启用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插件具有以下强制性选项:

path.join指定路径

path.join(__dirname, 'build', 'vendor-manifest.json')`

确保webpack.vendor.config.jsoutput.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具有两个强制字段:

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%的构建时间!极大地提高了生产率。

结论

此优化绝不适用于您的生产版本。它仅缓存指定的包以加快开发速度。

GitHub代码

参考

Improve your webpack build with the DLL plugin

上一篇下一篇

猜你喜欢

热点阅读