有些時候我們經常一個項目中開發不同的功能,有可能一個前端項目中夾雜着不同系統之間的需求,最后打包發布的時候經常會將與項目不相關的代碼一同打包進去,實際來講這種操作也是不嚴謹的。那有沒有辦法可以根據某些不同的配置來實現打包的結果不同呢?答案是肯定的。在介紹下邊的方法之前,希望讀者有一些關於webpack以及Vue router的概念和應用,廢話不多說,開始介紹。
首先來講webpack,webpack是一個模塊打包器他會收集各個組件之間的依賴關系,並通過此依賴關系來將所有的js、css、jpg等等都打成一個一個的組件依賴。而在Vue中也是使用webpack來進行模塊打包工作,那么在Vue中有沒有明確的依賴關系描述呢?在Vue中的所有的跳轉都是通過Vue router進行的,那是不是可以認為router擁有着組件之間的依賴關系。而router中跳轉的關鍵是通過不同的router.js加載不同的*.Vue組件,而后通過別名或者path進行跳轉。當然的在router中需要使用index.js文件來引入不同的router.js,由此Vue才可以正確的去尋找並去加載*.Vue文件。
既然知道了Vue是通過router中index.js文件去加載的,那么就意味着可以通過定義不同的index.js來實現打包差異化。但是,定義多個index.js雖然可行,打包的時候webpack又怎么會知道加載那個index.js文件呢?這時候就可以使用webpack中的一個內置組件NormalModuleReplacementPlugin來完成(NormalModuleReplacementPlugin的原理請自行GooGle),首先,使用npm run build的時候Vue會去加載webpack.prod.conf.js文件,這時候就可以在webpack.prod.conf.js文件中使用NormalModuleReplacementPlugin,方法如下:
var appTarget = env.PROJ_NAME plugins: [ new webpack.NormalModuleReplacementPlugin(/.*APP_TARGET\./, function (resourse) { var str = appTarget.replace("\"","").replace("\"",""); resourse.request = resourse.request.replace(/APP_TARGET/, `${str}`); }), ]
這個組件的實際上是所有的xxxx.APP_TARGET后邊的APP_TARGET替換為指定的字符,由此再去加載文件,其中env.PROJ_NAME是定義在prod.env.js中的一個標識,這樣就可以通過定義在prod.env.js中的這個標識去尋找相對應的index_xxxx.js文件,進而實現打包差異化。比如,你需要A項目的代碼,只需要將prod.env.js中的PROJ_NAME字段改為A
'use strict' module.exports = { NODE_ENV: '"production"', PROJ_NAME:'"A"' }
這樣Vue就會去加載index_A.js,同理當你需要B項目代碼的時候只需要將PROJ_NAME更改為B即可。
當決定使用以上方法的時候,在main.js文件中引入路由主文件就不可以像下邊這樣引用了
import router from './router/index.js'
要修改成
import router from './router/index_APP_TARGET.js'
這樣引用router才會去動態加載並實現打包差異化,這時候用戶需要在定義不同的index.js文件來實現不同的vue組件引用,比如
index_A.js
index_B.js
index_C.js
在上述條件都完成之后可以使用以下命令來驗證打包結果
npm run build --report
注:npm run build --report 命令實際是對 webpack-bundle-analyzer的一個使用 webpack-bundle-analyzer是一個可視化資源分析工具 用戶可以在其中查看資源的分布情況