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

資訊專欄INFORMATION COLUMN

代碼分割與懶加載情況下(code-splitting+lazyload)抽離懶加載模塊的公用模塊代碼

zebrayoung / 1792人閱讀

摘要:但是同時,抽離到父模塊,也意味著如果有一個懶加載的路由沒有用到模塊,但是實際上引入了父模塊,也為這也引入了的代碼。

前言

我們清楚,在 webpack 中通過CommonsChunkPlugin 可以將 entry 的入口文件中引用多次的文件抽離打包成一個公用文件,從而減少代碼重復冗余

    entry: {
        main: "./src/main.js",
        user: "./src/user.js"
    },
    ......
    new webpack.optimize.CommonsChunkPlugin({
        name: "commons",
        filename: "common.js",
        minChunks: 2,
    })
    
    // 打包生成一個文件common.js ,包含main.js 和 user.js 中引用兩次及以上的模塊代碼

那么問題來了,當使用了類似 vue-router 的代碼分割+懶加載功能的時候,每個路由對應的.vue文件中,共同引用了多次的模塊,要怎么抽離出代碼分割模塊的公用模塊代碼出來呢?

問題實際場景

舉個栗子

// 懶加載路由文件 routes.js
const
    Index = () => import(/* webpackChunkName: "index" */ "page/index/Index.vue"),
    User = () => import(/* webpackChunkName: "userIndex" */ "page/user/Index.vue"),
    UserDetail = () => import(/* webpackChunkName: "userDetail" */ "page/user/Detail.vue"),
    ...
// page/index/Index.vue 首頁路由文件

// page/index/Index.vue 用戶頁路由文件

上述使用了vue-router懶加載打包出來的 首頁路由文件index.js 和 用戶頁文件userIndex.js 都會包含一份 public.js的代碼,重復了。

那么問題就是,在代碼分割的代碼中,怎么自動抽離公共代碼? 就像CommonsChunkPlugin的效果一樣,CommonsChunkPlugin怎么在 code-splitting 的場景上使用呢 ?

解決方案

如問題所示,存在兩個使用了webpack code-splitting 和 懶加載的路由文件,路由文件都使用了公用的public.js模塊。

// page/index/Index.vue 首頁路由文件

// 用戶頁
// page/index/Index.vue 用戶頁路由文件

要將 public.js公用模塊抽離,有三種解決方案

方案一,CommonsChunkPlugin 具名模塊

手動將所有共用的模塊抽離在一個文件。
創(chuàng)建文件commons.js

// commons.js
import pub from "public"

webpack.config.jsCommonsChunkPlugin插件指定commons 的entry

// webpack.config.js
entry:{
    main: "src/main.js",
    commons: "src/commons.js"
},
...
    new webpack.optimize.CommonsChunkPlugin({
        name: "commons",   // 和 entry的commons對應,
        filename: "common.bundle.js", // 抽離公共文件
        minChunks: Infinity,
    })

這樣,如果路由文件或其他模塊使用到了 commons.js中的模塊,都不會重復加載代碼,而是在common.bundle.js中獲取。

方案二,CommonsChunkPlugin 設(shè)置 children 屬性

官方文檔CommonsChunkPlugin 中 children屬性解釋

Move common modules into the parent chunk

With Code Splitting, multiple child chunks of an entry chunk can have common dependencies. To prevent duplication these can be moved into the parent. This reduces overall size, but does have a negative effect on the initial load time. If it is expected that users will need to download many sibling chunks, i.e. children of the entry chunk, then this should improve load time overall.

可知,設(shè)置 children 為 true 可以將code-splitting的模塊的依賴模塊抽離到父模塊,這樣做的后果就是,確實抽離公用模塊,降低了代碼重復,減少了代碼體積。但是同時,抽離到父模塊,也意味著如果有一個懶加載的路由 ShopList.vue 沒有用到public.js 模塊,但是實際上引入了父模塊,也為這ShopList.vue也引入了public.js的代碼。

這就需要CommonsChunkPluginasync 屬性。

方案三(最佳實踐),childrenasync 雙管齊下
Extra async commons chunk

Similar to the above one, but instead of moving common modules into the parent (which increases initial load time) a new async-loaded additional commons chunk is used. This is automatically downloaded in parallel when the additional chunk is downloaded.

設(shè)置了async, 會將上述懶加載的路由文件公用的模塊代碼,抽離打包成一個多帶帶的文件,并且該文件是按需加載的,如果某個路由沒有使用到這些公用模塊,是不會加載進來的。

舉個例子:
首頁路由模塊(訪問路徑/index),引用了 public模塊
用戶路由模塊(訪問路徑/user),引用了 public模塊
購物車模塊(訪問路徑/shop),沒有引用 public模塊

那么,打包生成的文件大概是

main.js - 根入口文件
index.js - 首頁路由文件
user.js - 用戶路由文件
shop.js - 購物車路由文件
0.js - 抽離路由的公用模塊文件

訪問url/index,加載的依賴文件是main.js + index.js + 0.js
訪問url/user,加載的依賴文件是main.js + user.js + 0.js
訪問url/shop,加載的依賴文件是main.js + shop.js
基本解決了 lazy load + code-splitting 情況下的公用模塊抽離。

以下附上簡單的webpack.config.js配置代碼

entry: {
    main: "./src/main.js"
},
...
plugins: [
    ...
    new webpack.optimize.CommonsChunkPlugin({
        name: "main",
        minChunks: 2,
        children: true,
        // deepChildren: true,
        async: true,
    })
]
The CommonsChunkPlugin has been removed in webpack v4 legato. To learn how chunks are treated in the latest version, check out the SplitChunksPlugin.

PS: webpack 4 已經(jīng)將CommonsChunkPlugin廢棄,解決方案僅能在webpack 3 以下使用。

參考資料

commons-chunk-plugin
CommonChunkPlugin: Feature - Select statically imported modules from chunks that were created from a dynamic import (require.ensure / System.import / import(".."))

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

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

相關(guān)文章

  • 前端筆記(二) 對象深淺拷貝,函數(shù)防抖與節(jié)流,函數(shù)柯里化 ,圖片加載與懶加載

    摘要:對象是無法通過這種方式深拷貝。這就是函數(shù)防抖和節(jié)流要做的事情。函數(shù)防抖當觸發(fā)頻率過高時函數(shù)基本停止執(zhí)行而函數(shù)節(jié)流則是按照一定的頻率執(zhí)行事件。 對象的深淺拷貝 對象的深拷貝與淺拷貝的區(qū)別: 淺拷貝:僅僅復制對象的引用, 而不是對象本身。 深拷貝:把復制的對象所引用的全部對象都復制一遍 淺拷貝的實現(xiàn): var obj = { age : 18, person : { ...

    dongxiawu 評論0 收藏0
  • webpack4 SplitChunks實現(xiàn)代碼分隔詳解

    摘要:代碼均放在倉庫給我們帶來了一些改變。插件以前使用允許我們將公共依賴項提取到現(xiàn)有的或全新的代碼塊中。代碼詳情見文章開頭倉庫。這才是配置的關(guān)鍵緩存組會繼承的配置,但是和只能用于配置緩存組。可以通過禁用緩存組。代碼均放在git倉庫 Webpack 4給我們帶來了一些改變。包括更快的打包速度,引入了SplitChunksPlugin插件來取代(之前版本里的)CommonsChunksPlugin插件...

    Zachary 評論0 收藏0
  • 如何優(yōu)化你超大型React應用 【原創(chuàng)精讀】

    摘要:往往純的單頁面應用一般不會太復雜,所以這里不引入和等等,在后面復雜的跨平臺應用中我會將那些技術(shù)一擁而上。構(gòu)建極度復雜,超大數(shù)據(jù)的應用。 showImg(https://segmentfault.com/img/bVbvphv?w=1328&h=768); React為了大型應用而生,Electron和React-native賦予了它構(gòu)建移動端跨平臺App和桌面應用的能力,Taro則賦...

    cfanr 評論0 收藏0
  • 如何優(yōu)化你超大型React應用 【原創(chuàng)精讀】

    摘要:往往純的單頁面應用一般不會太復雜,所以這里不引入和等等,在后面復雜的跨平臺應用中我會將那些技術(shù)一擁而上。構(gòu)建極度復雜,超大數(shù)據(jù)的應用。 showImg(https://segmentfault.com/img/bVbvphv?w=1328&h=768); React為了大型應用而生,Electron和React-native賦予了它構(gòu)建移動端跨平臺App和桌面應用的能力,Taro則賦...

    codecook 評論0 收藏0
  • 如何優(yōu)化你超大型React應用 【原創(chuàng)精讀】

    摘要:往往純的單頁面應用一般不會太復雜,所以這里不引入和等等,在后面復雜的跨平臺應用中我會將那些技術(shù)一擁而上。構(gòu)建極度復雜,超大數(shù)據(jù)的應用。 showImg(https://segmentfault.com/img/bVbvphv?w=1328&h=768); React為了大型應用而生,Electron和React-native賦予了它構(gòu)建移動端跨平臺App和桌面應用的能力,Taro則賦...

    xiguadada 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<