成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

webpack dll打包重復(fù)問(wèn)題優(yōu)化

NicolasHe / 2828人閱讀

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

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

優(yōu)化背景

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

vue生態(tài)包(vue、vuexvue-router、vuex-class、vue-class-component等周邊生態(tài)的庫(kù))

vue插件包(vee-validate、內(nèi)部UI庫(kù),圖片預(yù)覽等vue插件庫(kù))

第三方包(axios、內(nèi)部一些錯(cuò)誤統(tǒng)計(jì)、上報(bào),員工水印等這些脫離于vue的第三方庫(kù))

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

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

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

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

那么要分析問(wèn)題原因,先說(shuō)一下我的DLL的配置吧

DLL配置

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

// webpack.dll.conf.js

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

但是親測(cè)這樣打包出來(lái)的文件依然有上述問(wèn)題

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

// config.js

exports.dll = [
    {
        name: "vue",
        libs: ["vue", "vuex", "vue-router", "vuex-class", "vue-class-component"]
    },
    {
        name: "lib",
        libs: [axios", "dayjs", "第三方庫(kù)"]
    },
    {
        name: "plugin",
        libs: ["vee-validate", "v-viewer", "vue插件庫(kù)"]
    }
]
// webpack.dll.conf.js

module.exports = config.dll.map(function (vendor) {
    return {
        // 省略其他配置
        entry: {
            [vendor.name]: vendor.libs
        },
        plugins: [
            new webpack.DllPlugin({
                // dll.配置
            })
        ]
    }
})
// dll.js

const dllConfig = require("./webpack.dll.conf")

webpack(dllConfig, function (err, stats) {
    if (err) throw err
    // 處理stats相關(guān)信息
})

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

分析問(wèn)題

經(jīng)過(guò)仔細(xì)的排查,發(fā)現(xiàn)是由于內(nèi)部UI庫(kù)中多帶帶引用了vue,即在庫(kù)中有

import Vue from "vue"

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

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

解決方法

分析dll的原理,其實(shí)dll在打包的時(shí)候會(huì)將所有包含的庫(kù)做一個(gè)索引,寫(xiě)在一個(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.js

exports.dll = [
    {
        name: "vue",
        libs: ["vue", "vuex", "vue-router", "vuex-class", "vue-class-component"]
    },
    {
        name: "lib",
        libs: [axios", "dayjs", "第三方庫(kù)"]
    },
    {
        name: "plugin",
        libs: ["vee-validate", "v-viewer", "vue插件庫(kù)"],
        ref: "vue"
    }
]
// webpack.dll.conf.js

// generate config
const 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 config
const [baseVendors, refVendors] = config.dll.vendors.reduce((config, v) => {
    config[v.ref ? 1 : 0].push(v)
    return config
}, [
    [],
    []
])

// 生成base config
const getConfig = function () {
    return gen(baseVendors)
}

// 生成ref config
const getRefConfig = function () {
    return gen(refVendors)
}

module.exports = {
    getConfig,
    getRefConfig
}
// dll.js

const dllConfig = require("./webpack.dll.conf")

// 因?yàn)閞ef config依賴于base config,所以要保證base config先打包出來(lái)
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會(huì)引用vue.dll.js的manifest文件,這樣公共部分vue,就只會(huì)出現(xiàn)在vue.dll.js中了,plugin.dll.js打包后的bundle分析圖如下

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

可優(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)上述情況,那么請(qǐng)先考慮dll包是否需要拆分?拆分是否合理?

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

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

總結(jié)

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/98253.html

相關(guān)文章

  • React系列---Webpack環(huán)境搭建(三)打包性能優(yōu)化

    摘要:的選項(xiàng)中,是文件的輸出路徑是暴露的對(duì)象名,要跟保持一致是解析包路徑的上下文,這個(gè)要跟下面要配置的保持一致。最后修改一下模板,增加引用文件給入口文件再加點(diǎn)依賴模塊,方便打包觀察運(yùn)行打包可以看到,入口文件里依賴的,模塊,直接引用了。 React系列---Webpack環(huán)境搭建(一)手動(dòng)搭建React系列---Webpack環(huán)境搭建(二)不同環(huán)境不同配置React系列---Webpack環(huán)境...

    Jason_Geng 評(píng)論0 收藏0
  • 記一次使用 vue-admin-template 的優(yōu)化歷程

    摘要:同時(shí)也要引入對(duì)應(yīng)版本的先引入引入組件庫(kù)因?yàn)橐蕾囀菑耐獠恳氲?,所以需要告知在打包時(shí),依賴的來(lái)源。然后在中加入一條命令執(zhí)行或者即可完成打包。因此將此次優(yōu)化記錄下來(lái),并傳上了中。 本文原文 前言 公司有好幾個(gè)項(xiàng)目都有后臺(tái)管理系統(tǒng),為了方便開(kāi)發(fā),所以選擇了 vue 中比較火的 后臺(tái)模板 作為基礎(chǔ)模板進(jìn)行開(kāi)發(fā)。但是,開(kāi)始用的時(shí)候,作者并沒(méi)有對(duì)此進(jìn)行優(yōu)化,到項(xiàng)目上線的時(shí)候,才發(fā)現(xiàn),打包出來(lái)的文件...

    xumenger 評(píng)論0 收藏0
  • webpack 基礎(chǔ)與項(xiàng)目優(yōu)化實(shí)踐總結(jié)

    摘要:前言本文基于,主要涉及基本概念基本配置和實(shí)際項(xiàng)目打包優(yōu)化。關(guān)于概念方面參考官網(wǎng),常用配置來(lái)自于網(wǎng)絡(luò)資源,在文末有相關(guān)參考鏈接,實(shí)踐部分基于自己的項(xiàng)目進(jìn)行優(yōu)化配置。同一文件中,修改某個(gè)影響其他。 前言:本文基于weboack4.x,主要涉及webpack4 基本概念、基本配置和實(shí)際項(xiàng)目打包優(yōu)化。關(guān)于概念方面參考官網(wǎng),常用配置來(lái)自于網(wǎng)絡(luò)資源,在文末有相關(guān)參考鏈接,實(shí)踐部分基于自己的項(xiàng)目進(jìn)行...

    Scorpion 評(píng)論0 收藏0
  • webpack4.0優(yōu)化那些事兒

    摘要:配置以何種方式導(dǎo)出庫(kù)。當(dāng)檢測(cè)文件不再發(fā)生變化,會(huì)先緩存起來(lái),等等待一段時(shí)間后之后再通知監(jiān)聽(tīng)者,這個(gè)等待時(shí)間通過(guò)配置。發(fā)布到線上給用戶使用的運(yùn)行環(huán)境。 一 縮小文件搜索范圍 1 include & exclude 1) action 限制編譯范圍 2) useage module: { rules: [ { test...

    levy9527 評(píng)論0 收藏0
  • 【Vue項(xiàng)目總結(jié)】webpack常規(guī)打包優(yōu)化方案

    摘要:由于新建項(xiàng)目發(fā)版打包時(shí)間大概需要分鐘,發(fā)版時(shí)嚴(yán)重拖慢下班時(shí)間,所以特意查看了相關(guān)文檔來(lái)優(yōu)化打包速度,爭(zhēng)取早點(diǎn)下班,。分析打包文件要優(yōu)化,先分析。 由于新建項(xiàng)目發(fā)版打包時(shí)間大概需要30分鐘,發(fā)版時(shí)嚴(yán)重拖慢下班時(shí)間,所以特意查看了相關(guān)文檔來(lái)優(yōu)化打包速度,爭(zhēng)取早點(diǎn)下班,^_^。 分析打包文件 要優(yōu)化,先分析。我們先要知道到底是哪里拖慢我們的打包速度呢? 打包后生成文件分析 可以利用webpa...

    andong777 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<