python 音速_webpack多页应用架构系列(十一):预打包Dll,实现webpack音速编译
前言
上文說(shuō)到我們利用webpack來(lái)打包一個(gè)可配置的bootstrap,但文末留下一個(gè)問(wèn)題:由于bootstrap十分龐大,因此每次編譯都要耗費(fèi)大部分的時(shí)間在打包bootstrap這一塊,而換來(lái)的僅僅是配置的便利,十分不劃算。
我也并非是故意賣關(guān)子,這的確是我自己開(kāi)發(fā)中碰到的問(wèn)題,而在撰寫完該文后,我立即著手探索解決之道。終于,發(fā)現(xiàn)了webpack這一大殺器:DllPlugin&DllReferencePlugin,打包時(shí)間過(guò)長(zhǎng)的問(wèn)題得到完美解決。
解決方案的機(jī)制和原理
DllPlugin&DllReferencePlugin這一方案,實(shí)際上也是屬于代碼分割的范疇,但與CommonsChunkPlugin不一樣的是,它不僅僅是把公用代碼提取出來(lái)放到一個(gè)獨(dú)立的文件供不同的頁(yè)面來(lái)使用,它更重要的一點(diǎn)是:把公用代碼和它的使用者(業(yè)務(wù)代碼)從編譯這一步就分離出來(lái),換句話說(shuō),我們可以分別來(lái)編譯公用代碼和業(yè)務(wù)代碼了。這有什么好處呢?很簡(jiǎn)單,業(yè)務(wù)代碼常改,而公用代碼不常改,那么,我們?cè)谌粘P薷臉I(yè)務(wù)代碼的過(guò)程中,就可以省出編譯公用代碼那一部分所耗費(fèi)的時(shí)間了(是不是馬上就聯(lián)想到坑爹的bootstrap了呢)。
整個(gè)過(guò)程大概是這樣的:
利用DllPlugin把公用代碼打包成一個(gè)“Dll文件”(其實(shí)本質(zhì)上還是js,只是套用概念而已);除了Dll文件外,DllPlugin還會(huì)生成一個(gè)manifest.json文件作為公用代碼的索引供DllReferencePlugin使用。
在業(yè)務(wù)代碼的webpack配置文件中配置好DllReferencePlugin并進(jìn)行編譯,達(dá)到利用DllReferencePlugin讓業(yè)務(wù)代碼和Dll文件實(shí)現(xiàn)關(guān)聯(lián)的目的。
在各個(gè)頁(yè)面
中,先加載Dll文件,再加載業(yè)務(wù)代碼文件。適用范圍
Dll文件里只適合放置不常改動(dòng)的代碼,比如說(shuō)第三方庫(kù)(誰(shuí)也不會(huì)有事無(wú)事就升級(jí)一下第三方庫(kù)吧),尤其是本身就龐大或者依賴眾多的庫(kù)。如果你自己整理了一套成熟的框架,開(kāi)發(fā)項(xiàng)目時(shí)只需要在上面添磚加瓦的,那么也可以把這套框架也打包進(jìn)Dll文件里,甚至可以做到多個(gè)項(xiàng)目共用這一份Dll文件。
如何配置哪些代碼需要打包進(jìn)Dll文件?
我們需要專門為Dll文件建一份webpack配置文件,不能與業(yè)務(wù)代碼共用同一份配置:
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const dirVars = require('./webpack-config/base/dir-vars.config.js'); // 與業(yè)務(wù)代碼共用同一份路徑的配置表
module.exports = {
output: {
path: dirVars.dllDir,
filename: '[name].js',
library: '[name]', // 當(dāng)前Dll的所有內(nèi)容都會(huì)存放在這個(gè)參數(shù)指定變量名的一個(gè)全局變量下,注意與DllPlugin的name參數(shù)保持一致
},
entry: {
/*
指定需要打包的js模塊
或是css/less/圖片/字體文件等資源,但注意要在module參數(shù)配置好相應(yīng)的loader
*/
dll: [
'jquery', '!!bootstrap-webpack!bootstrapConfig',
'metisMenu/metisMenu.min', 'metisMenu/metisMenu.min.css',
],
},
plugins: [
new webpack.DllPlugin({
path: 'manifest.json', // 本Dll文件中各模塊的索引,供DllReferencePlugin讀取使用
name: '[name]', // 當(dāng)前Dll的所有內(nèi)容都會(huì)存放在這個(gè)參數(shù)指定變量名的一個(gè)全局變量下,注意與參數(shù)output.library保持一致
context: dirVars.staticRootDir, // 指定一個(gè)路徑作為上下文環(huán)境,需要與DllReferencePlugin的context參數(shù)保持一致,建議統(tǒng)一設(shè)置為項(xiàng)目根目錄
}),
/* 跟業(yè)務(wù)代碼一樣,該兼容的還是得兼容 */
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
}),
new ExtractTextPlugin('[name].css'), // 打包c(diǎn)ss/less的時(shí)候會(huì)用到ExtractTextPlugin
],
module: require('./webpack-config/module.config.js'), // 沿用業(yè)務(wù)代碼的module配置
resolve: require('./webpack-config/resolve.config.js'), // 沿用業(yè)務(wù)代碼的resolve配置
};
如何編譯Dll文件?
編譯Dll文件的代碼實(shí)際上跟編譯業(yè)務(wù)代碼是一樣的,記得利用--config指定上述專供Dll使用的webpack配置文件就好了:
$ webpack --progress --colors --config ./webpack-dll.config.js
另外,建議可以把該語(yǔ)句寫到npm scripts里,好記一點(diǎn)哈。
如何讓業(yè)務(wù)代碼關(guān)聯(lián)Dll文件?
我們需要在供編譯業(yè)務(wù)代碼的webpack配置文件里設(shè)好DllReferencePlugin的配置項(xiàng):
new webpack.DllReferencePlugin({
context: dirVars.staticRootDir, // 指定一個(gè)路徑作為上下文環(huán)境,需要與DllPlugin的context參數(shù)保持一致,建議統(tǒng)一設(shè)置為項(xiàng)目根目錄
manifest: require('../../manifest.json'), // 指定manifest.json
name: 'dll', // 當(dāng)前Dll的所有內(nèi)容都會(huì)存放在這個(gè)參數(shù)指定變量名的一個(gè)全局變量下,注意與DllPlugin的name參數(shù)保持一致
});
配置好DllReferencePlugin了以后,正常編譯業(yè)務(wù)代碼即可。不過(guò)要注意,必須要先編譯Dll并生成manifest.json后再編譯業(yè)務(wù)代碼;而以后每次修改Dll并重新編譯后,也要重新編譯一下業(yè)務(wù)代碼。
如何在業(yè)務(wù)代碼里使用Dll文件打包的module/資源?
不需要刻意做些什么,該怎么require就怎么require,webpack都會(huì)幫你處理好的了。
如何整合Dll?
在每個(gè)頁(yè)面里,都要按這個(gè)順序來(lái)加載js文件:Dll文件 => CommonsChunkPlugin生成的公用chunk文件(如果沒(méi)用CommonsChunkPlugin那就忽略啦) => 頁(yè)面本身的入口文件。
有兩個(gè)注意事項(xiàng):
如果你是像我一樣利用HtmlWebpackPlugin來(lái)生成HTML并自動(dòng)加載chunk的話,請(qǐng)務(wù)必在
里手寫 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的python 音速_webpack多页应用架构系列(十一):预打包Dll,实现webpack音速编译的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: “含啸对雾岑”上一句是什么
- 下一篇: c++ for循环 流程图_python