概念
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
複製程式碼
具體專案結構,請看下圖
下面開始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 中單獨引入。
兩種方案
- 手動新增script,手動copy打包好的dll資料夾到dist,麻煩反覆,很不爽
- 使用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
}
])
]
}
複製程式碼
兩者區別
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檔案下的檔案