麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 網站 > WEB開發 > 正文

webpack打包-模塊分布解析

2024-04-27 15:13:01
字體:
來源:轉載
供稿:網友

webpack打包-模塊分布解析 發布于 1 個月前 作者 yongningfu 385 次瀏覽 來自 分享 webpack打包原理解析

一開始,對webpack打包原理很不熟悉,看了不少資料,但是講的都不是很清楚,現在來梳理一遍。

所有資源統一入口

這個是什么意思呢?就是webpack是通過js來獲取和操作其他文件資源的,比如webpack想處理less, 但是它并不會直接從本地的文件夾中直接通過路徑去讀取CSS文件,而且通過執行入口js文件,如果入口 文件中,或者入口文件相關聯的js文件中含有 require(xx.less) 這個less文件,那么它就會通過 對應的loader去處理這個less文件

打包中的文件管理

重點來了: webpack是如何進行資源的打包的呢?

總結:

每個文件都是一個資源,可以用require導入js 每個入口文件會把自己所依賴(即require)的資源全部打包在一起,一個資源多次引用的話,只會打包一份 對于多個入口的情況,其實就是分別獨立的執行單個入口情況,每個入口文件不相干(可用CommonsChunkPlugin優化) js單文件入口的情況

img1.gif

比如整個應用的入口為 entry.js

entry.js引用 util1.js util2.js, 同時util1.js又引用了util2.js

關鍵問題是: 它打包的會不會將 util2.js打包兩份?

其實不會的,webpack打包的原理為,在入口文件中,對每個require資源文件進行配置一個id, 也 就是說,對于同一個資源,就算是require多次的話,它的id也是一樣的,所以無論在多少個文件中 require,它都只會打包一分

對于和上面一致拓撲圖,打包后的js代碼為 img2.gif

注: /* 1 */ 代碼打包模塊為 id 為 1

通過上面的圖片我們看到,

entry.js 入口文件對應的id為 1 util1.js的id為 2 util2.js的id為 3 entry.js引用了 2 和 3, util1.js引用了 3,說明了entry和util1引用的是同一份,util2.js不會重復打包

css單文件入口的情況

上面分析了js的情況,其實css也是一個道理。它同樣也會為每個css資源分配一個id, 每個資源同樣也只會導入一次。

img3.gif

可以看到, entry.js 和 util1.js共同引用了 style2.less,那么它們作用的結果是怎么樣的呢?

img4.gif

可以看到 entry.js 和 util1.js使用的是同一個 css資源

注意: /* 1 */ 注釋表示id為1的模塊

聽說 ExtractTextPlugin 導出css的插件比較火, 讓我們來看看它到底幫我們干了啥?配置好相關引用后

newExtractTextPlugin(‘[name].[chunkhash].css’) 運行,在static下面生成了 一個.css 一個.js

生成的css代碼為

.style2 { color: green; } .style3 { color: blue; } .style1 { color: red; } 實際就是把三個css導出到一個css文件,而且同一個入口中,多次引用同一個css,實際只會打包一份

生成的.js為

img5.gif

可以看到 /* 2 */ 實際就是 util1.js模塊,還是引用 id為3的模塊 即css2, 但是我們看 3 模塊 的定義,為空函數, 它給出的解釋是 removed by extract-text-webpack-plugin 實際 就是newExtractTextPlugin把相關的css全部移出去了

多文件入口的情況

講完了單入口,還需講講多入口,很多時候我們項目是需要多入口

img6.gif

修改webpack config

img7.gif

可以看到 輸出為兩個js文件

先對 entry.js 對應的輸出文件進行分析

img8.gif

其實可以看到, util1.js util2.js的內容都打包進 對應的js里面去了

在對 entry2.js 輸出的文件進行分析

img9.gif

可以看到,把entry2.js依賴的 util2.js也打包進去了

所以多 入口 實際就是 分別執行多個單入口,彼此之間不影響

問題來了,多入口對應的css呢? 還是上面的原則,css也是分別打包的,對于每個入口所依賴的css全部打包, 輸出就是這個入口對應的css

最后討論 CommonsChunkPlugin

之前提到過,每個入口文件,都會獨立打包自己依賴的模塊,那就會造成很多重復打包的模塊,有沒有一種方法 能把多個入口文件中,共同依賴的部分給獨立出來呢? 肯定是有的 CommonsChunkPlugin

這個插件使用非常簡單,它原理就是把多個入口共同的依賴都給定義成 一個新入口

為何我這里說是定義成新入口呢,因為這個名字不僅僅對應著js 而且對于著和它相關的css等,比如 HtmlWebpackPlugin 中 就能體現出來,可以它的 chunks中 加入 common 新入口,它會自動把common 的css也導入html

img10.gif

可以看到, 不僅僅js公共模塊獨立出來,連css同樣也是,感受到了 webpack強大了吧

我們可以大概對 common.js index.xxxxx.js(entry.js對應的代碼) index2.xxxx.js(entry2.js對應的代碼) 打包出來的代碼分析一下

提前知識:

webpack的id 有兩種 一種為 chunkid 一種為moduleId

每個chunkid 對應的是一個js文件 每個moduleid對應的是一個個js文件的內容的模塊(一個js文件里面可以require多個資源,每 個資源分配一個moduleid) 為何要出來一個chunkid呢? 這個chunkid的作用就是,標記這個js文件是否已經加載過了

/**/ // object to store loaded and loading chunks /**/ // “0” means “already loaded” /**/ // Array means “loading”, array contains callbacks /**/ var installedChunks = { /**/ 2:0 /**/ }; installedChunks 是記錄一個chunkid是否已經加載過了

我們先從 common.js分析

common.js是公共分離出來的模塊,所以按理來說,它應該是一個頂層的模塊,實際上,確實如此

看 common.js代碼

/**/ (function(modules) { // webpackBootstrap /**/ // install a JSONP callback for chunk loading

/**/ var parentJsonpFunction = window[“webpackJsonp”]; /**/ window[“webpackJsonp”] = function webpackJsonpCallback(chunkIds, moreModules) { /**/ // add “moreModules” to the modules object, /**/ // then flag all “chunkIds” as loaded and fire callback 定義了一個 webpackJsonp 函數

看 index.xxxx.js代碼

webpackJsonp([0],[ /* 0 */ /*/ function(module, exports, webpack_require) {

module.exports = __webpack_require__(1);

/*/ }, 使用 common.js中定義的函數 webpackJsonp, 所以在瀏覽器中加載的話,必須先加載 common.js

這個 webpackJsonp([0],[]) 第一個參數 [0] 是什么意思呢? 它就是 chunkid ,我們知道一個chunkid id對應一個 js 文件,它對應的js文件就是它的入口文件 entry.js, 那為何這里還要是一個數組

因為一個入口文件的話,可以依賴多個js文件,其他的 id 就是它所依賴的, 其實就是配置webpack的時候

那個入口js對應的 數組

index: [‘./src/js/entry.js’], [0] 和 現在的id數組一一對應

在 index2.xxx.js中,

webpackJsonp([1],{

/*/ 0: /*/ function(module, exports, webpack_require) {

module.exports = __webpack_require__(8);

[1] 就是 webpack.config配置的數組 js 對應的 thunkid

index2: [‘./src/js/entry2.js’]

即 entry2.js 就是 thunkid 1

上面說完了thunkid, 下面就說 moduleid了, common.js為頂層js文件,通過調用webpackJsonp 對其他文件進行處理,

common.js中

/**/ var parentJsonpFunction = window[“webpackJsonp”]; /**/ window[“webpackJsonp”] = function webpackJsonpCallback(chunkIds, moreModules) { /**/ // add “moreModules” to the modules object, /**/ // then flag all “chunkIds” as loaded and fire callback

/**/ for(moduleId in moreModules) {

/**/ modules[moduleId] = moreModules[moduleId]; /**/ } webpackJsonpCallback(chunkIds, moreModules)定義為 chunkIds, moreModules,chunkIds 說了, 就是入口文件對應的 js 文件的 thunkid, 那么這個moreModules是什么呢? 就是一個js文件中,一個個依賴的 和 導出本身的 module

可以看index2.xxxx.js

webpackJsonp([1],{

/*/ 0: /*/ function(module, exports, webpack_require) {

module.exports = __webpack_require__(8);

/*/ },

/*/ 8: /*/ function(module, exports, webpack_require) {

var util2 = __webpack_require__(3)var css1 = __webpack_require__(4)

/*/ }

}); 這里 moreModules 為一個對象,key 為 moduleid, value 就是一個個 module定義

比如 function(module, exports, webpack_require) { module.exports = webpack_require(8);}

最重要的來了, 這里的話, utils2 是公共的module,它被定義在commong.js中,

common.js

/* 0 */, /* 1 */, /* 2 */, /* 3 */ /*/ function(module, exports) {

module.exports = {"name": "util2.js"}

/*/ }, /* 4 */ 可以看到, index.xxx.js 的 調用 和 index2.xxx.js的調用都是一樣的,都是下面這句

var util2 = webpack_require(3)

它會尋找 moduleid 為3的模塊,然后返回

如何尋找呢 看看 webpack_require 定義

/**/ function webpack_require(moduleId) {

/**/ // Check if module is in cache /**/ if(installedModules[moduleId]) /**/ return installedModules[moduleId].exports;

/**/ // Create a new module (and put it into the cache) /**/ var module = installedModules[moduleId] = { /**/ exports: {}, /**/ id: moduleId, /**/ loaded: false /**/ }; if(installedModules[moduleId]) 如果緩存中存在的話,就直接返回。

由于 index.xxx.js 和 index2.xxx.js都是返回的同一個 id 的模塊,所以實際上 它們使用的是同一個對象

這和nodejs里面的require是一樣的,所以整個項目中,require公共模塊中的資源的話,實際返回的都是同一個對象

源碼

歡迎討論和star


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 毛片免费试看 | 日韩一级精品 | 成人在线视频一区 | 狠狠干天天操 | 黄色网络免费看 | 男女一边摸一边做羞羞视频免费 | 鲁丝一区二区二区四区 | 久国久产久精永久网页 | 伦一区二区三区中文字幕v亚洲 | h色网站在线观看 | 国产99久久久久 | 久久国产精品系列 | 天天操天天骑 | 色猫av | av视屏 | 色七七亚洲 | 国产精品视频一区二区三区综合 | jizzyouxxxx| 黄色男女视频 | 欧美亚洲国产一区二区三区 | 中国美女一级黄色大片 | 久久精品欧美一区二区 | 亚洲第一综合色 | 天天躁狠狠躁夜躁2020挡不住 | 日本精品久久久一区二区三区 | 夜间福利视频 | 亚洲情视频| 在线免费小视频 | 国产成人综合在线视频 | 欧美日韩高清在线观看 | 欧洲精品色 | 少妇av片 | 少妇一级淫片免费放4p | 精品一区二区三区不卡 | 视频一区二区三区视频 | 99视频有精品 | 少妇一级淫片免费放4p | 国产欧美日韩在线不卡第一页 | 久久人人做 | 99视频有精品视频高清 | 成年免费大片黄在线观看岛国 |