国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Webpack 的 Bundle Split 和 Code Split 區(qū)別和應(yīng)用

jimhs / 2693人閱讀

摘要:當(dāng)然,上面的定時(shí)器完全可以換成其他諸如按鈕點(diǎn)擊之類的事件來觸發(fā)。

Webpack Bundle Split 和 Code Split
話說之前也是對(duì) chunk 這個(gè)概念有些模糊,并且很多時(shí)候網(wǎng)上的文章大部分在將代碼分離動(dòng)態(tài)加載之類的。寫這篇文章的目的也是想讓其他那些跟我一樣曾經(jīng)對(duì)這個(gè)概念不是很清楚的童鞋有個(gè)清晰的認(rèn)識(shí)。廢話不多說,擼起袖子直接干!

Let"s Dive in!

Webpack 文件分離包括兩個(gè)部分,一個(gè)是 Bundle 的分離,一個(gè)是 Code 代碼的分離:

Bundle splitting: 實(shí)際上就是創(chuàng)建多個(gè)更小的文件,并行加載,以獲得更好的緩存效果;主要的作用就是使瀏覽器并行下載,提高下載速度。并且運(yùn)用瀏覽器緩存,只有代碼被修改,文件名中的哈希值改變了才會(huì)去再次加載。

Code splitting: 只加載用戶最需要的部分,其余的代碼都遵從懶加載的策略;主要的作用就是加快頁(yè)面加載速度,不加載不必要加載的東西。

準(zhǔn)備工作

在進(jìn)行文件分離之前的準(zhǔn)備工作,我們先寫一些代碼:

入口文件 src/index.js:

const { getData } = require("./main")
const { findMaxIndex } = require("./math")

let arr = [1,2,123,21,3,21,321,1]

findMaxIndex(arr)
getData("./index.html")

兩個(gè)依賴模塊:

src/main.js:

const axios = require("axios")

const getData = url => {
    axios.get(url).then(d => {
        console.log(d.status)
        console.log(d.data.length)
    })
}

module.exports = {
    getData
}

src/math.js:

const _ = require("lodash")

const findMaxIndex = arr => {
    let x = _.max(arr)
    let r = Array.prototype.indexOf.call(arr, x)
    console.log(r);
}

module.exports = {
    findMaxIndex
}

增加一個(gè) webpack 配置文件 webpack.config.js:

const path = require("path")

module.exports = {
    mode: "development",
    entry: path.resolve(__dirname, "src/index.js"),
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].[contenthash].js"
    },
}
文件分離之前打包效果

在 bundle split 和 code split 操作之前,我們先看一下當(dāng)前默認(rèn)打包的效果:

全部依賴都被打包到 main.xxx.js 中去,大小是 609k
開始分離操作 Bundle Split

Bundle Split 的主要任務(wù)是將多個(gè)引用的包和模塊進(jìn)行分離,避免全部依賴打包到一個(gè)文件下

基本用法

Webpack 4 中需要使用到 optimization.splitChunks 的配置:

const path = require("path")

module.exports = {
    mode: "development",
    entry: path.resolve(__dirname, "src/index.js"),
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].[contenthash].js"
    },
    optimization: {
        splitChunks: {
            chunks: "all"
        }
    }
}
optimization.splitChunks 的意思是將所有來自 node_modules 中的依賴全部打包分離出來,這個(gè)時(shí)候我們?cè)倏创虬奈募莻€(gè)什么樣子:

增加了 splitChunks 的配置,我們第三方模塊都被打包到了 vendors~main.xxx.js 中去了,這個(gè)文件大小有 604k,而入口文件 main.xxx.js 則只有 7k

雖然說這樣將第三方模塊多帶帶打包出去能夠減小入口文件的大小,但這樣仍然是個(gè)不小的文件;這個(gè)小的測(cè)試項(xiàng)目中我們使用到了 axios 和 lodash 這兩個(gè)第三方模塊,因此我們希望的應(yīng)該是將這兩個(gè)模塊多帶帶分離出來兩個(gè)文件,而不是全部放到一個(gè) vendors 中去,那么我們繼續(xù)配置 webpack.config.js:

將每個(gè) npm 包多帶帶分離出來

這里我們需要使用到 webpack.HashedModuleIdsPlugin 這個(gè)插件

參考官方文檔

直接上代碼:

const path = require("path")
const webpack = require("webpack")

module.exports = {
    mode: "development",
    entry: path.resolve(__dirname, "src/index.js"),
    plugins: [
        new webpack.HashedModuleIdsPlugin() // 根據(jù)模塊的相對(duì)路徑生成 HASH 作為模塊 ID
    ],
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "[name].[contenthash].js"
    },
    optimization: {
        runtimeChunk: "single",
        splitChunks: {
            chunks: "all", // 默認(rèn) async 可選值 all 和 initial
            maxInitialRequests: Infinity, // 一個(gè)入口最大的并行請(qǐng)求數(shù)
            minSize: 0, // 避免模塊體積過小而被忽略
            minChunks: 1, // 默認(rèn)也是一表示最小引用次數(shù)
            cacheGroups: {
                vendor: {
                    test: /[/]node_modules[/]/, // 如果需要的依賴特別小,可以直接設(shè)置成需要打包的依賴名稱
                    name(module, chunks, chcheGroupKey) { // 可提供布爾值、字符串和函數(shù),如果是函數(shù),可編寫自定義返回值
                        const packageName = module.context.match(/[/]node_modules[/](.*?)([/]|$)/)[1] // 獲取模塊名稱
                        return `npm.${packageName.replace("@", "")}` // 可選,一般情況下不需要將模塊名稱 @ 符號(hào)去除
                    }
                }
            }
        }
    }
}

這里我們主要做了幾件事:

為了避免每次打包的文件哈希變化,我們可以使用 webpack 內(nèi)置的 HashedModuleIdsPlugin,這樣可以避免每次打包的文件哈希值變化

首先增加 maxInitialRequests 并設(shè)置成 Infinity,指定這個(gè)入口文件最大并行請(qǐng)求數(shù)

然后將 minSize 和 minChunks 分別設(shè)置成 0 和 1,即使模塊非常小也將其提取出來,并且這個(gè)模塊的引用次數(shù)只有 1 也要提取

最后配置匹配的依賴以及分離出的文件名格式

另外,我們還將運(yùn)行時(shí)代碼分離出來,這塊代碼還可以配合 InlineManifestWebpackPlugin 直接插入到 HTML 文件中。這里我們將這個(gè)配置設(shè)置成 single,即將所有chunk的運(yùn)行代碼打包到一個(gè)文件中

這樣 Bundle Split 的操作基本就完成了,讓我們看看效果如何:

所依賴的幾個(gè)模塊都被分離出去了

使用 HtmlWebpackPlugin 這個(gè)插件將 js 代碼注入 html 文件中

npm i -D html-webpack-plugin

修改 webpack.config.js 文件:

// 配置文件引入這個(gè)插件

var HtmlWebpackPlugin = require("html-webpack-plugin");
// ...
module.exports = {
    // ...
    plugins: [
        new HtmlWebpackPlugin(),
        new webpack.HashedModuleIdsPlugin() // 根據(jù)模塊的相對(duì)路徑生成 HASH 作為模塊 ID
    ],
    // ...
}

安裝 http-server 或使用 vscode 的插件 Live Server 將代碼放入一個(gè)本地服務(wù)器中,打開瀏覽器的調(diào)試窗口進(jìn)入到 Network 面板:

可以看到我們將模塊多帶帶分離出來并行加載,這樣比多帶帶加載一個(gè)龐大的包要快不少,接下來我們還要進(jìn)行代碼分離,將不必要加載的模塊延遲加載
Code Split

代碼分離實(shí)際上就是只加載用戶需要使用到的部分代碼,不是必須的就暫時(shí)不加載。

這里我們要用到 require.ensure 這個(gè)方法去獲取依賴,這樣 webpack 打包之后將會(huì)增加運(yùn)行時(shí)代碼,在設(shè)定好的條件下才會(huì)觸發(fā)獲取這個(gè)依賴。

在 ES6 中我們可以用 Dynamic Imports 來替代上述方案,如果使用 ES6 語法那么需要使用到 babel 以及 babel 的插件 plugin-syntax-dynamic-import,在瀏覽器中為了保證兼容性,還需要安裝 promise 的 polyfill,用法大同小異,可直接觀摩 webpack 的官方文檔

修改我們的代碼:

const { getData } = require("./main")

let arr = [1,2,123,21,3,21,321,1]

getData("./index.html")

setTimeout(() => {
    require.ensure(["./math"], function(require) {
        const { findMaxIndex } = require("./math")
        console.log(findMaxIndex(arr))
    })
}, 3000)
我們?cè)O(shè)定了一個(gè)定時(shí)器,只有在 3000 毫秒以后,瀏覽器才會(huì)去請(qǐng)求這個(gè) math 模塊

編譯之后,打開調(diào)試面板刷新瀏覽器:

在頁(yè)面剛加載完畢后,瀏覽器會(huì)嘗試獲取上述這么幾個(gè)模塊,因?yàn)槟K都很小很快就加載完成了

在 3500ms 左右,瀏覽器才會(huì)去獲取 requie.ensure 方法定義的 math 模塊,因 math 模塊又包含依賴 lodash,因此這個(gè) lodash 第三方模塊也會(huì)被按需加載。

這樣我們就完成了代碼分離的操作,這樣做的優(yōu)勢(shì)就是不需要第一時(shí)間加載的模塊,可以推遲加載,以頁(yè)面的加載速度。當(dāng)然,上面的 timeout 定時(shí)器完全可以換成其他諸如按鈕點(diǎn)擊之類的事件來觸發(fā)。

END

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/101027.html

相關(guān)文章

  • Webpack 構(gòu)建后文件變得很大?

    摘要:的和的是同步加載的,通過這些方式引入的依賴會(huì)被打包在一起,文件因而變大。而或的是按需加載異步的,對(duì)于一些可以延遲加載的模塊依賴,應(yīng)該用這種方式,從而避免文件太大。 上一篇回顧使用 Webpack 的動(dòng)機(jī),比較理論,本篇側(cè)重實(shí)用。 這幾篇文章的前提是 Webpack 已經(jīng)入門。若無,請(qǐng)自行到 Webpack 官方網(wǎng)站的 getting start 按指引一步步實(shí)操。 啃先生(MrKenn...

    Barry_Ng 評(píng)論0 收藏0
  • 深入理解 Webpack 打包分塊(上)

    摘要:而一個(gè)哈希字符串就是根據(jù)文件內(nèi)容產(chǎn)生的簽名,每當(dāng)文件內(nèi)容發(fā)生更改時(shí),哈希串也就發(fā)生了更改,文件名也就隨之更改。很顯然這不是我們需要的,如果文件內(nèi)容發(fā)生了更改,的打包文件的哈希應(yīng)該發(fā)生變化,但是不應(yīng)該。前言 隨著前端代碼需要處理的業(yè)務(wù)越來越繁重,我們不得不面臨的一個(gè)問題是前端的代碼體積也變得越來越龐大。這造成無論是在調(diào)式還是在上線時(shí)都需要花長(zhǎng)時(shí)間等待編譯完成,并且用戶也不得不花額外的時(shí)間和帶寬...

    Rocko 評(píng)論0 收藏0
  • webpack學(xué)習(xí)(四)— code splitting

    摘要:支持定義分割點(diǎn),通過進(jìn)行按需加載。若按照中做,則會(huì)造成通用模塊重復(fù)打包。下文將詳細(xì)說明。同樣是利用和來處理的。如下在中添加入口其中模塊為通用功能模塊在中對(duì)應(yīng)和這樣則會(huì)打包出和兩個(gè)文件。為通用功能模塊。希望有更好方案的同學(xué)能夠不吝賜教。 什么是code splitting 首先說,code splitting指什么。我們打包時(shí)通常會(huì)生成一個(gè)大的bundle.js(或者index,看你如...

    lsxiao 評(píng)論0 收藏0
  • webpack搭建多頁(yè)面系統(tǒng)(三) 理解webpack.config.js四個(gè)核心概念

    摘要:關(guān)于模板的有好幾種。一次安裝所有的大家可以了解一些的用法把編譯成。安裝參考文檔功能將源文件遷移到指定的目錄,返回新的文件路徑。安裝用法它會(huì)將所有的入口中引用的移動(dòng)到和頁(yè)面對(duì)應(yīng)的獨(dú)立分離的文件。 webpack是需要自己編寫自己需要的一個(gè)配置對(duì)象,取決你如何使用webpack,下面指定了所有的可用的配置選項(xiàng)。參考文檔:https://doc.webpack-china.org... we...

    鄒強(qiáng) 評(píng)論0 收藏0
  • webpack Code Splitting淺析

    摘要:不知大家是不是跟大雄一樣之前從未看過編譯產(chǎn)出的代碼。前文大雄給了一個(gè)粗陋的動(dòng)態(tài)加載的方法說白了就是動(dòng)態(tài)創(chuàng)建標(biāo)簽。大雄看完至少大概知道了原來編出來的代碼是那樣執(zhí)行的原來可以那么靈活的使用。 Code Splitting是webpack的一個(gè)重要特性,他允許你將代碼打包生成多個(gè)bundle。對(duì)多頁(yè)應(yīng)用來說,它是必須的,因?yàn)楸仨氁渲枚鄠€(gè)入口生成多個(gè)bundle;對(duì)于單頁(yè)應(yīng)用來說,如果只打包...

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

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

0條評(píng)論

jimhs

|高級(jí)講師

TA的文章

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