国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

webpack dll打包重復(fù)問題優(yōu)化的解決

2019-11-19 12:45:00
字體:
供稿:網(wǎng)友

關(guān)于webpack dll的使用,我這里不做過多介紹,網(wǎng)上都有,一擼一大把,今天我要說的是在使用dll plugin過程中出現(xiàn)的一個(gè)包依賴問題,這個(gè)問題導(dǎo)致打出來的包會包含重復(fù)的代碼。

優(yōu)化背景

最近在給公司項(xiàng)目優(yōu)化的時(shí)候,由于 內(nèi)部CDN上傳文件大小限制了500K ,所以用了webpack dll來進(jìn)行拆分打包,我將拆分的包分為三部分:

  • vue生態(tài)包( vuevuexvue-routervuex-classvue-class-component 等周邊生態(tài)的庫)
  • vue插件包( vee-validate 、內(nèi)部UI庫,圖片預(yù)覽等vue插件庫)
  • 第三方包( axios 、內(nèi)部一些錯(cuò)誤統(tǒng)計(jì)、上報(bào),員工水印等這些脫離于vue的第三方庫)

三部分的包名分別是 vue.dll.jsplugin.dll.jslib.dll.js ,這樣的好處是結(jié)構(gòu)清晰,最重要的原因還是分解包的大小,降低到500K以內(nèi)

但是在進(jìn)行dll打包后,我驚奇地發(fā)現(xiàn) vue.dll.jsplugin.dll.js 中會包含重復(fù)的vue的dist代碼

下面是分別是前兩部分的bundle分析圖

可以看到這倆dll都包含了vue

那么要分析問題原因,先說一下我的DLL的配置吧

DLL配置

因?yàn)閣ebpack支持多entry,所以一般多入口dll打包的話,首先會考慮一個(gè)webpack配置,多個(gè)entry入口,所以可能會出現(xiàn)

// webpack.dll.conf.jsmodule.exports = { // 其他配置先省略  entry: {    vue: ['vue', 'vuex', 'vue-router', ...],    plugin: ['vee-validate', '內(nèi)部UI庫', ...],    lib: ['axios', 'dayjs', ...]  }, plugins: [  new webpack.DllPlugin({   // dll.配置  }) ]}

但是親測這樣打包出來的文件依然有上述問題

所以結(jié)合我在之前公司所實(shí)踐的 webpack multi compiler 方式,參考webpack multi compiler ,我把webpack的配置一分為三,每一個(gè)dll包都有一個(gè)webpack配置,即

// config.jsexports.dll = [ {  name: 'vue',  libs: ['vue', 'vuex', 'vue-router', 'vuex-class', 'vue-class-component'] }, {  name: 'lib',  libs: [axios', 'dayjs', '第三方庫'] }, {  name: 'plugin',  libs: ['vee-validate', 'v-viewer', 'vue插件庫'] }]
// webpack.dll.conf.jsmodule.exports = config.dll.map(function (vendor) { return {  // 省略其他配置  entry: {   [vendor.name]: vendor.libs  },  plugins: [   new webpack.DllPlugin({    // dll.配置   })  ] }})
// dll.jsconst dllConfig = require('./webpack.dll.conf')webpack(dllConfig, function (err, stats) { if (err) throw err // 處理stats相關(guān)信息})

本以為這樣可以解決問題,但是現(xiàn)實(shí)卻是不能,所以得先分析一下問題所在

分析問題

經(jīng)過仔細(xì)的排查,發(fā)現(xiàn)是由于內(nèi)部UI庫中單獨(dú)引用了vue,即在庫中有

import Vue from 'vue'// ...// Vue相關(guān)操作// Vue.prototype.$isServer等

這樣不管是多入口打包還是multi compiler方式下都會出現(xiàn)重復(fù)的包

解決方法

分析dll的原理,其實(shí)dll在打包的時(shí)候會將所有包含的庫做一個(gè)索引,寫在一個(gè)manifest文件中,然后在引用dll的時(shí)候只需要引用這個(gè)manifest文件即可

所以我就在想,如果plugin.dll.js依賴于vue.dll.js中的vue,那么是否可以先打包vue.dll.js,然后在打包plugin.dll.js的時(shí)候引用vue.dll.js呢?

心動(dòng)不如行動(dòng),趕緊嘗試一下,做出如下修改

// config.jsexports.dll = [ {  name: 'vue',  libs: ['vue', 'vuex', 'vue-router', 'vuex-class', 'vue-class-component'] }, {  name: 'lib',  libs: [axios', 'dayjs', '第三方庫'] }, {  name: 'plugin',  libs: ['vee-validate', 'v-viewer', 'vue插件庫'],  ref: 'vue' }]
// webpack.dll.conf.js// generate configconst gen = function (vendors) { return vendors.map(function (item) {  const base = {   entry: {    [item.name]: item.libs   },   plugins: [    new webpack.DllPlugin({     // dll配置    })   ]  }    if (item.ref) {   // 重點(diǎn)在這   // 在有ref的dll配置中,插入dll reference的plugin,內(nèi)容是所依賴的dll包的manifest   base.plugins.push(new webpack.DllReferencePlugin({    // dll reference其他配置    manifest: '所依賴的dll包的manifest文件路徑'   }))  }    return base })}// 根據(jù)是否有ref依賴項(xiàng),區(qū)分base config和ref configconst [baseVendors, refVendors] = config.dll.vendors.reduce((config, v) => { config[v.ref ? 1 : 0].push(v) return config}, [ [], []])// 生成base configconst getConfig = function () { return gen(baseVendors)}// 生成ref configconst getRefConfig = function () { return gen(refVendors)}module.exports = { getConfig, getRefConfig}
// dll.jsconst dllConfig = require('./webpack.dll.conf')// 因?yàn)閞ef config依賴于base config,所以要保證base config先打包出來const runWebpack = function (config) { return new Promise(function (resolve) {  webpack(config, function (err, stats) {   if (err) throw err   // ...   resolve()  }) })}module.exports = function run () { runWebpack(dllConfig.getConfig())  .then(() => runWebpack(dllConfig.getRefConfig()))}

整體變成了如下結(jié)構(gòu)

最關(guān)鍵的一步就是plugin.dl.js會引用vue.dll.js的manifest文件,這樣公共部分vue,就只會出現(xiàn)在vue.dll.js中了,plugin.dll.js打包后的bundle分析圖如下

可以很明顯地看到plugin.dll.js中已經(jīng)沒有vue dist的身影了,包的體積得到了優(yōu)化:v:

可優(yōu)化項(xiàng)

上述優(yōu)化其實(shí)只考慮了一個(gè)依賴項(xiàng),那么如果plugin.dll.js同時(shí)依賴于vue.dll.js和lib.dll.js呢?如果此時(shí)vue.dll.js也依賴于lib.dll.js呢?

如果出現(xiàn)上述情況,那么請先考慮dll包是否需要拆分?拆分是否合理?

然后再思考如何根據(jù)依賴順序思考打包順序,以及如果出現(xiàn)循環(huán)依賴,該怎么辦?

由于目前優(yōu)化需求中還未出現(xiàn)這種情況(這種情況應(yīng)該很少很少很少見),所以我這邊就沒有解決這些問題了

總結(jié)

參考平常打包通過dll reference plugin來引用dll包的manifest的方式,如果多個(gè)dll包內(nèi)出現(xiàn)了依賴,導(dǎo)致打包重復(fù),那么是可以在依賴包中運(yùn)用dll reference plugin來引用被依賴包的dll manifest,不過這樣的話,需要注意dll包的打包順序,被依賴包的dll要先于依賴包dll進(jìn)行打包

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 新泰市| 文山县| 仁怀市| 凤庆县| 阳新县| 无棣县| 固安县| 图片| 林口县| 咸宁市| 甘泉县| 芒康县| 奎屯市| 寿阳县| 孝义市| 玉龙| 柳林县| 台南县| 淅川县| 永年县| 稻城县| 四子王旗| 通山县| 嘉定区| 富裕县| 蓬溪县| 南开区| 宁陵县| 蒙城县| 湘乡市| 慈溪市| 平阴县| 太康县| 宝应县| 三原县| 井冈山市| 南郑县| 澄城县| 红河县| 沅江市| 怀集县|