Webpack DllPlugin 讓構建速度柔順絲滑

流浪的先知發表於2019-03-13

概念

DLLPlugin 和 DLLReferencePlugin 用某種方法實現了拆分 bundles,同時還大大提升了構建的速度,將包含大量複用模組且不會頻繁更新的庫進行編譯,只需要編譯一次,編譯完成後存在指定的檔案中。在之後的構建過程中不會再對這些模組進行編譯,而是直接使用 DllReferencePlugin 來引用動態連結庫的程式碼。一般會對常用的第三方模組使用這種方式,例如 react、react-dom、lodash 等。只要這些模組不升級更新,這些動態連結庫就不需要重新編譯。

摘要

本文介紹了 Webpack 中 DllPlugin 外掛的使用,以及配合使用 AddAssetHtmlPlugin 或者 HtmlWebpackIncludeAssetsPlugin 將構建好的 JS 檔案插入到 html頁面中

程式碼地址

github: 原始碼
歡迎交流,Star!

專案目錄

常規webpack專案,搭建過程本文章不在描述

myreact
|- /build
  |- webpack.config.js
  |- webpack.dll.conf.js
|- /dist
  |- dll
  |- js
|- /src
  |- index.js
|- package.json
|- index.html
複製程式碼

具體專案結構,請看下圖

Webpack DllPlugin 讓構建速度柔順絲滑

下面開始DLL之旅

一.build目錄下建立webpack.dll.conf.js(DllPlugin)

const webpack = require("webpack")
const path = require('path')
const CleanWebpaclPlugin = require('clean-webpack-plugin');
const resolve = (dir) => path.join(__dirname, '..', dir);

module.exports = {
  entry: {
    # 將 react、lodash等模組作為入口編譯成動態連結庫
    vendor: ['react', 'react-dom', 'react-router-dom', 'lodash']
  },
  output: {
    # 指定生成檔案所在目錄資料夾,
    # 將它們存放在了 src 資料夾下
    path: resolve('public'),
    # 指定檔名
    library: '_dll_[name]',
    # 存放動態連結庫的全域性變數名稱,例如對應 lodash 來說就是 lodash_dll_lib
    # 這個名稱需要與 DllPlugin 外掛中的 name 屬性值對應起來
    filename: 'dll/_dll_[name].[hash].js'
  },
  plugins: [
    new CleanWebpaclPlugin(['dll'], {
        root: resolve('public')
    }),
    new webpack.DllPlugin({
      name: '_dll_[name]',
    # 和output.library中一致,值就是輸出的manifest.json中的 name值
      path: path.join(__dirname, '../public/dll', '[name].manifest.json')
    })
  ]
}
複製程式碼

二. 建立webpack.base.conf.js 使用 DllReferencePlugin

const path = require('path');
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpaclPlugin = require('clean-webpack-plugin');
const resolve = (dir) => path.join(__dirname, '..', dir);

module.exports = {
    entry: './src/index.js',
    output: {
        path: resolve('dist'),
        filename: 'js/[name].[hash].js',
        library: '_dll_[name]'
    },
    plugins: [
        # 需新增root 否則無法刪除,exclude未生效
        new CleanWebpackPlugin(['dist'], {
          root: path.join(__dirname, '..')
        }),
        new HTMLWebpackPlugin({
            title: 'Webpak DllPlugin 的使用',
            template: resolve('index.html'),
            filename: 'index.html'
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')
        }),
        # 告訴 Webpack 使用動態連結庫
        new webpack.DllReferencePlugin({
            // 描述 lodash 動態連結庫的檔案內容
            manifest: require(../public/dll/vendor.manifest')
        })
    ]
}

複製程式碼

三、在 index.html 檔案中引入動態連結庫

由於動態連結庫我們一般只編譯一次,除非依賴的三方庫更新,之後就不用編譯,因此入口的 index.js 檔案中不包含這些模組,所以要在 index.html 中單獨引入。

兩種方案

  1. 手動新增script,手動copy打包好的dll資料夾到dist,麻煩反覆,很不爽
  2. 使用add-asset-html-webpack-plugin或者html-webpack-include-assets-plugin插入到html中,簡單自動化,美滋滋

所以我們肯定會採用第二種方式,下面著重講下add-asset-html-webpack-plugin與html-webpack-include-assets-plugin外掛的使用,專案中使用add-asset-html-webpack-plugin

安裝大同小異

npm install add-asset-html-webpack-plugin -D
npm install html-webpack-include-assets-plugin -D
複製程式碼

使用也有相似的地方

webpack.base.conf.js 檔案中進行使用

# add-asset-html-webpack-plugin
...;
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
    ...,
    plugins: [
        ...,
        # 給定的 JS 或 CSS 檔案新增到 webpack 配置的檔案中,並將其放入資源列表 html webpack外掛注入到生成的 html 中。
        new AddAssetHtmlPlugin([
            {
                # 要新增到編譯中的檔案的絕對路徑
                filepath: path.resolve(__dirname,'../public/dll/_dll_vendor.js'),
                outputPath: 'dll',
                publicPath: 'dll',
                includeSourcemap: false
            }
        ])
    ]
}

複製程式碼
# html-webpack-include-assets-plugin
...;
const HtmlWebpackIncludeAssetsPlugin = require('html-webpack-include-assets-plugin');

module.exports = {
    ...,
    plugins: [
        ...,
        # 給定的 JS 或 CSS 檔案新增到 webpack 配置的檔案中,並將其放入資源列表 html webpack外掛注入到生成的 html 中。
        new HtmlWebpackIncludeAssetsPlugin([
            {
                assets: ['dll/_dll_vendor.js'],
                append: false
            }
        ])
    ]
}

複製程式碼

兩者區別

Webpack DllPlugin 讓構建速度柔順絲滑

index.html

<!DOCTYPE html>
<html>
    
    <head>
        <meta charset="UTF-8">
        <title>愛你的一隻貓哈哈哈1111</title>
    </head>
    
    <body>
        <div id='root'></div>

</html>
<script type="text/javascript" src="dll/_dll_vendor.js"></script>
<script type="text/javascript" src="/js/runtime.830efec54753fd6ed91b.js"></script>
<script type="text/javascript" src="/js/vendors.830efec54753fd6ed91b.js"></script>
<script type="text/javascript" src="/js/app.830efec54753fd6ed91b.js"></script>
複製程式碼

執行專案

 npm run build
複製程式碼

檢視dist檔案下的檔案

相關文件

webpack 中文

相關文章