本文首發於 Array_Huang的技術博客——實用至上
,非經做者贊成,請勿轉載。
原文地址: http://www.javashuo.com/article/p-xdqdewjm-z.html
若是您對本系列文章感興趣,歡迎關注訂閱這裏:https://segmentfault.com/blog/array_huang
書承上文《webpack多頁應用架構系列(十):如何打造一個自定義的bootstrap》。javascript
上文說到咱們利用webpack來打包一個可配置的bootstrap,但文末留下一個問題:因爲bootstrap十分龐大,所以每次編譯都要耗費大部分的時間在打包bootstrap這一塊,而換來的僅僅是配置的便利,十分不划算。css
我也並不是是故意賣關子,這的確是我本身開發中碰到的問題,而在撰寫完該文後,我當即着手探索解決之道。終於,發現了webpack這一大殺器:DllPlugin
&DllReferencePlugin
,打包時間過長的問題獲得完美解決。前端
DllPlugin
&DllReferencePlugin
這一方案,實際上也是屬於代碼分割的範疇,但與CommonsChunkPlugin不同的是,它不只僅是把公用代碼提取出來放到一個獨立的文件供不一樣的頁面來使用,它更重要的一點是:把公用代碼和它的使用者(業務代碼)從編譯這一步就分離出來,換句話說,咱們能夠分別來編譯公用代碼和業務代碼了。這有什麼好處呢?很簡單,業務代碼常改,而公用代碼不常改,那麼,咱們在平常修改業務代碼的過程當中,就能夠省出編譯公用代碼那一部分所耗費的時間了(是否是立刻就聯想到坑爹的bootstrap了呢)。java
整個過程大概是這樣的:jquery
DllPlugin
把公用代碼打包成一個「Dll文件」(其實本質上仍是js,只是套用概念而已);除了Dll文件外,DllPlugin
還會生成一個manifest.json文件做爲公用代碼的索引供DllReferencePlugin
使用。DllReferencePlugin
並進行編譯,達到利用DllReferencePlugin
讓業務代碼和Dll文件實現關聯的目的。Dll文件裏只適合放置不常改動的代碼,好比說第三方庫(誰也不會有事無事就升級一下第三方庫吧),尤爲是自己就龐大或者依賴衆多的庫。若是你本身整理了一套成熟的框架,開發項目時只須要在上面添磚加瓦的,那麼也能夠把這套框架也打包進Dll文件裏,甚至能夠作到多個項目共用這一份Dll文件。webpack
咱們須要專門爲Dll文件建一份webpack配置文件,不能與業務代碼共用同一份配置:git
const webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const dirVars = require('./webpack-config/base/dir-vars.config.js'); // 與業務代碼共用同一份路徑的配置表 module.exports = { output: { path: dirVars.dllDir, filename: '[name].js', library: '[name]', // 當前Dll的全部內容都會存放在這個參數指定變量名的一個全局變量下,注意與DllPlugin的name參數保持一致 }, entry: { /* 指定須要打包的js模塊 或是css/less/圖片/字體文件等資源,但注意要在module參數配置好相應的loader */ dll: [ 'jquery', '!!bootstrap-webpack!bootstrapConfig', 'metisMenu/metisMenu.min', 'metisMenu/metisMenu.min.css', ], }, plugins: [ new webpack.DllPlugin({ path: 'manifest.json', // 本Dll文件中各模塊的索引,供DllReferencePlugin讀取使用 name: '[name]', // 當前Dll的全部內容都會存放在這個參數指定變量名的一個全局變量下,注意與參數output.library保持一致 context: dirVars.staticRootDir, // 指定一個路徑做爲上下文環境,須要與DllReferencePlugin的context參數保持一致,建議統一設置爲項目根目錄 }), /* 跟業務代碼同樣,該兼容的仍是得兼容 */ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery', 'window.$': 'jquery', }), new ExtractTextPlugin('[name].css'), // 打包css/less的時候會用到ExtractTextPlugin ], module: require('./webpack-config/module.config.js'), // 沿用業務代碼的module配置 resolve: require('./webpack-config/resolve.config.js'), // 沿用業務代碼的resolve配置 };
編譯Dll文件的代碼實際上跟編譯業務代碼是同樣的,記得利用--config
指定上述專供Dll使用的webpack配置文件就行了:github
$ webpack --progress --colors --config ./webpack-dll.config.js
另外,建議能夠把該語句寫到npm scripts
裏,好記一點哈。web
咱們須要在供編譯業務代碼的webpack配置文件裏設好DllReferencePlugin
的配置項:npm
new webpack.DllReferencePlugin({ context: dirVars.staticRootDir, // 指定一個路徑做爲上下文環境,須要與DllPlugin的context參數保持一致,建議統一設置爲項目根目錄 manifest: require('../../manifest.json'), // 指定manifest.json name: 'dll', // 當前Dll的全部內容都會存放在這個參數指定變量名的一個全局變量下,注意與DllPlugin的name參數保持一致 });
配置好DllReferencePlugin
了之後,正常編譯業務代碼便可。不過要注意,必需要先編譯Dll並生成manifest.json後再編譯業務代碼;而之後每次修改Dll並從新編譯後,也要從新編譯一下業務代碼。
不須要刻意作些什麼,該怎麼require就怎麼require,webpack都會幫你處理好的了。
在每一個頁面裏,都要按這個順序來加載js文件:Dll文件 => CommonsChunkPlugin
生成的公用chunk文件(若是沒用CommonsChunkPlugin
那就忽略啦) => 頁面自己的入口文件。
有兩個注意事項:
HtmlWebpackPlugin
來生成HTML並自動加載chunk的話,請務必在<head>裏手寫<script>來加載Dll文件。file-loader
給原封不動搬運過去。下面以個人腳手架項目Array-Huang/webpack-seed爲例,測試一下(使用開發環境的webpack配置文件webpack.dev.config.js
)使用這套Dll方案先後的webpack編譯時間:
因爲該項目只是一個腳手架,涉及到的第三方庫並很少,我只把jQuery、bootstrap、metisMenu給打包進Dll文件裏了,儘管如此,仍是差了將近6秒了,相信在實際項目中,這套DllPlugin
&DllReferencePlugin
的方案能爲你省下更多的時間來找女友(大誤)。
諸位看本系列文章,搭配我在Github上的腳手架項目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed
)。
https://segmentfault.com/a/1190000006843916
https://segmentfault.com/a/1190000006863968
https://segmentfault.com/a/1190000006871991
https://segmentfault.com/a/1190000006887523
https://segmentfault.com/a/1190000006897458
https://segmentfault.com/a/1190000006907701
https://segmentfault.com/a/1190000006952432
https://segmentfault.com/a/1190000006992218
https://segmentfault.com/a/1190000007030775
https://segmentfault.com/a/1190000007043716
https://segmentfault.com/a/1190000007104372
https://segmentfault.com/a/1190000007126268
https://segmentfault.com/a/1190000007159115
本文首發於 Array_Huang的技術博客——實用至上
,非經做者贊成,請勿轉載。
原文地址: http://www.javashuo.com/article/p-xdqdewjm-z.html
若是您對本系列文章感興趣,歡迎關注訂閱這裏:https://segmentfault.com/blog/array_huang