Webpack按需加載打包chunk命名的方法
前言
最近,遇到復(fù)雜h5頁面開發(fā),為了優(yōu)化H5首屏加載速度,想到使用按需加載的方式,減少首次加載的JavaScript文件體積,于是將處理過程在這里記錄一下,涉及到的主要是以下三點:
- 使用Webpack如何做按需加載
- filename和chunkFilename的區(qū)別
- 如何命名chunk的名稱(webpackChunkName)
1 使用Webpack如何做按需加載
大家都知道Webpack是現(xiàn)在流行的前端打包編譯工具,通過模塊之間的依賴關(guān)系,將代碼打包組織到一起。Webpack目前已經(jīng)到v4.x,不同版本版支持按需加載的方式不同,主要有兩種:
- webpack1.x 中提供了 require.ensure()
- webpack2.x 中提供了 import()
require.ensure()
// 舉例 require.ensure([], function(require){ require('b'); });
webpack 在編譯時,會靜態(tài)地解析代碼中的 require.ensure(),同時將[模塊b] 添加到一個分開的 chunk 當中。這個新的 chunk 會被 webpack 通過 jsonp 來按需加載。
為什么說到是靜態(tài)分析,我們可以看到下面的require.ensure語法,第二個參數(shù)callback就是一個回調(diào)函數(shù)。其中需要注意的是,這個回調(diào)函數(shù)有一個參數(shù)require,通過這個require就可以在回調(diào)函數(shù)內(nèi)按需引入其他模塊。==值得注意的是,雖然這個require是回調(diào)函數(shù)的參數(shù)"module",理論上可以換其他名稱,但是實際上是不能換的,否則webpack就無法靜態(tài)分析的時候處理它。==
require.ensure( dependencies: String[], callback: function(require){ require('module'); }, errorCallback: function(error){}, chunkName: String )
import()
要注意的是import() 函數(shù)不同于import命令,import 是 ECMAScript 6 Module 的語法,import 是靜態(tài)執(zhí)行,這里不多說,可以去看import 命令。
import(specifier)
上面代碼中,import函數(shù)的參數(shù)specifier,指定所要加載的模塊的位置,而且==specifier可以是一個方法,動態(tài)的生成模塊路徑==。import命令能夠接受什么參數(shù),import()函數(shù)就能接受什么參數(shù),兩者區(qū)別主要是后者為動態(tài)加載。
import()函數(shù)是 ECMAScript Stage 3 草案階段的語法;用于完成動態(tài)加載即運行時加載,可以用在任何地方。import()函數(shù) 返回的是一個 Promise。類似于 CommonJs 的 require() ,區(qū)別主要是前者是異步加載,后者是同步加載。
import的應(yīng)用場景有以下三種 (參考自ECMAScript 6 入門):
- 按需加載。import()可以在需要的時候,再加載某個模塊
- 條件加載。import()可以放在if代碼塊,根據(jù)不同的情況,加載不同的模塊。
- 動態(tài)的模塊路徑。import()允許模塊路徑動態(tài)生成。
用法大致如下:
import('./myModule.js') .then(myModule => { console.log(myModule.default); });
小結(jié)
目前我們用的比較多的是import來做按需加載,模塊路徑可以動態(tài)生成,更適合現(xiàn)在的應(yīng)用場景。
filename和chunkFilename的區(qū)別
能夠打包之后,我們會發(fā)現(xiàn)打包出來的chunk的路徑和命名是極其簡單的1,2,3...這樣子的數(shù)字,對于我們要定制路徑和名字的話,就會涉及到filename和chunkFilename。
- output.filename 決定了每個入口(entry) 輸出 bundle 的名稱。
- output.chunkFilename 決定了非入口(non-entry) chunk 文件的名稱。
常用的Webpack配置如下
module.exports = { //... output: { filename: '[name].[hash].bundle.js', chunkFilename: '[name].[hash].chunk.js', } };
filename和chunkFilename對應(yīng)的結(jié)果可以由以下參數(shù)拼接或者返回:
模板 | 描述 |
---|---|
[hash] | 模塊標識符(module identifier)的 hash |
[chunkhash] | chunk 內(nèi)容的 hash |
[name] | 模塊名稱 |
[id] | 模塊標識符(module identifier) |
[query] | 模塊的 query,例如,文件名 ? 后面的字符串 |
[function] | 方法,可以返回一個filename字符串 |
不同的是chunkFilename我們不能想filename中的name那樣,可以在entry中定義。也就是說對于chunkFilename,默認[id]和[name]是一樣的,那么如何自定義name呢?
如何命名chunk的名稱
只能說哪里有壓迫,哪里就會有反抗,chunkFileName不能靈活自定義,這誰能忍,于是便有了/* webpackChunkName: "" */,號稱是Magic Comments(魔術(shù)注釋法)。
Webpack通過增加內(nèi)聯(lián)注釋來告訴運行時,該有怎樣的行為。通過向import中添加注釋,我們可以執(zhí)行諸如命名chunk或選擇不同模式之類的操作。
這里著重講一下webpackChunkName,它其實就是對chunkFilename定義時[name]值的改寫,/* webpackChunkName: "hello" */,意味著[name]等于hello。
于是上面的代碼就會按照下面的方式來寫,打包出來的chunk文件將會出現(xiàn)在plugins文件夾下,名字叫myModule.a2d1d5d8e7d5d4d4d4se.chunk.js。
import(/* webpackChunkName: "plugins/myModule" */ './myModule.js') .then(myModule => { console.log(myModule.default); });
更多的魔術(shù)注釋,請參考Webpack官方文檔。
結(jié)束了
到此為止,我們已經(jīng)可以將代碼打包到多個文件,每個chunk可以獨立命名,是的就是這樣。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
document.execCommand()的用法小結(jié)
本篇文章主要是對document.execCommand()的用法進行了詳細的介紹,需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01JS promise 的回調(diào)和 setTimeout 的回調(diào)到底誰先執(zhí)行
本文主要介紹了JS promise 的回調(diào)和 setTimeout 的回調(diào)到底誰先執(zhí)行,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01Qt利用布局widget和ScrollArea實現(xiàn)抽屜效果(實例代碼)
這篇文章主要介紹了Qt利用布局,widget和ScrollArea實現(xiàn)抽屜效果,本文通過實例代碼圖文展示給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-07-07JavaScript數(shù)組去重的方法總結(jié)【12種方法,號稱史上最全】
這篇文章主要介紹了JavaScript數(shù)組去重的方法,結(jié)合實例形式較為詳細的總結(jié)分析了12種方法數(shù)組去重的方法,需要的朋友可以參考下2019-02-02