<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          webpack之編譯原理

          共 2985字,需瀏覽 6分鐘

           ·

          2021-03-04 11:46

          820680ec7509a4cb6f335bc89c69c29d.webp



          前端獵手
          ?鏈接每一位開發(fā)者,讓編程更有趣兒!關(guān)注


          webpack 的作用是根據(jù)入口文件將源代碼編譯(構(gòu)建、打包)成最終代碼。中間經(jīng)過webpack打包,打包的過程就是編譯d37b88b59e0832c6b1deb8e4829ace39.webp

          整個(gè)過程大致分為三個(gè)步驟:初始化編譯(最重要)輸出ed766cb6d2cbff67122aa9567d8fbd0e.webp

          「初始化」

          在初始化這個(gè)階段webpack會(huì)將CLI參數(shù)配置文件默認(rèn)配置進(jìn)行融合,形成一個(gè)最終的配置對(duì)象。

          CLI參數(shù):使用命令行工具,可能會(huì)加一些參數(shù)進(jìn)去,比如:

          npx?webpack?--mode=development?--config?xxx

          配置文件:webpack.config.js文件里面的配置

          默認(rèn)配置:比如入口entry,默認(rèn)為 ./src/index.js

          對(duì)配置的處理過程是依托一個(gè)第三方庫yargs完成的,yargs庫就是融合配置的。初始化階段相對(duì)比較簡(jiǎn)單,主要是為接下來的編譯階段做必要的準(zhǔn)備。目前,可以簡(jiǎn)單的理解為:初始化階段主要用于產(chǎn)生一個(gè)最終的配置

          「編譯」

          1. 創(chuàng)建chunk

          chunk是webpack在內(nèi)部構(gòu)建過程中的一個(gè)概念,譯為,它表示通過某個(gè)入口找到的所有依賴的統(tǒng)稱,比方說:入口模塊(./src/index.js)依賴a模塊(./src/a.js),a模塊又依賴b模塊(./src/b.js),通過一個(gè)入口模塊分析依賴關(guān)系,可以找到三個(gè)模塊,那么index.jsa.jsb.js這三個(gè)統(tǒng)稱為一個(gè)chunk

          根據(jù)入口模塊(默認(rèn)為./src/index.js)創(chuàng)建一個(gè)chunk,每一個(gè)chunk是有名字的,意味著chunk有可能也會(huì)有多個(gè),入口文件是可以有多個(gè)的。a572ba112d529f4c0f70da1530ffb819.webp

          默認(rèn)情況下只有一個(gè)chunk,每個(gè)chunk都有至少兩個(gè)屬性:

          name:默認(rèn)為main

          id:唯一編號(hào),如果是開發(fā)環(huán)境,那么id和name相同,如果是生產(chǎn)環(huán)境,則是一個(gè)數(shù)字,從0開始。

          2. 構(gòu)建所有依賴模塊1ea36a353ac73e0ce76d8a1bff15fde4.webp我們先通過下面代碼來簡(jiǎn)單過一遍這個(gè)圖:

          代碼:

          //模塊名:
          ./src/index.js?(未加載狀態(tài))

          //模塊內(nèi)容:
          console.log("index");
          require("./a");
          require("./b");
          • 第1步:根據(jù)入口模塊文件(./src/index.js)進(jìn)行構(gòu)建,模塊文件它是有一個(gè)路徑的,入口模塊文件路徑就是./src/index.js,它會(huì)通過這個(gè)路徑檢查當(dāng)前這個(gè)模塊是否已經(jīng)加載過,注意哦:它不是運(yùn)行模塊,而是瞅一眼,看看模塊記錄表(上圖右邊藍(lán)色表格)中該模塊是不是被加載過,首次檢查表格是沒有內(nèi)容的,空的。
          • 第2步:如果說模塊記錄表中有記錄,說明模塊已經(jīng)加載過了。如果沒有記錄,那么會(huì)繼續(xù)走下一步,說明該模塊需要加載
          檢查 ./src/index.js 模塊,發(fā)現(xiàn)該模塊并未加載過
          • 第3步:讀取該模塊中的內(nèi)容,內(nèi)容其實(shí)是個(gè)字符串
          //讀取內(nèi)容(字符串)
          console.log("index");
          require("./a");
          require("./b");
          • 第4步:對(duì)模塊的內(nèi)容進(jìn)行語法分析,樹形結(jié)構(gòu)遍歷,找到所有依賴,最后生成AST抽象語法樹
          require("./a");
          require("./b");

          AST在線測(cè)試工具:https://astexplorer.net/

          • 第5步:將分析出來的依賴記錄到dependencies數(shù)組中
          //記錄依賴
          ["./src/a.js","./src/b.js"]
          • 第6步:替換依賴函數(shù),什么意思呢?就是說把有依賴的地方變一種代碼格式,將require改為_webpack_require,將依賴的模塊改為模塊id
          console.log("index");
          _webpack_require("./src/a.js");
          _webpack_require("./src/b.js");
          • 第7步:我們將替換后的代碼稱為轉(zhuǎn)換后的模塊代碼,并且把它保存到模塊記錄表中
          • 第8步:index.js模塊處理完成,由于index.js依賴其它模塊,所以遞歸循環(huán)保存在dependencies數(shù)組中的依賴,開始分析./src/a.js模塊,從頭再走一遍這個(gè)流程就可以了,假設(shè)a模塊依賴./src/b.js模塊,那么它會(huì)等a模塊處理完成后,再處理a模塊所依賴的b模塊,再最后處理index模塊所依賴的b模塊,此時(shí)它會(huì)發(fā)現(xiàn)b模塊在處理a模塊所依賴的b模塊已經(jīng)加載過了,那么index模塊所依賴的b模塊是不會(huì)進(jìn)行下一步處理,直接結(jié)束。

          以上就是webpack編譯過程,做這一切最終的目的就是形成一個(gè)模塊記錄表。

          下面有個(gè)簡(jiǎn)圖,經(jīng)過上述編譯過程之后會(huì)在chunk中通過入口文件加載形成多個(gè)模塊,每個(gè)模塊記錄了轉(zhuǎn)換之后的代碼。ffbc8f0d79e0fbc4a29874e19823c4ec.webp

          3. 產(chǎn)生 chunk assets

          在第二步完成后,chunk中會(huì)產(chǎn)生一個(gè)模塊列表,列表中包含了模塊id模塊轉(zhuǎn)換后的代碼。接下來,webpack會(huì)根據(jù)配置為chunk生成一個(gè)資源列表,即chunk assets,資源列表可以理解為是生成到最終文件的文件名和文件內(nèi)容。7342d5124c7f0b9845ce5d2d9ac2c7a6.webp

          chunk hash是根據(jù)所有chunk assets的內(nèi)容生成的一個(gè)hash字符串

          hash:一種算法,具體有很多分類,特點(diǎn)是將一個(gè)任意長(zhǎng)度的字符串轉(zhuǎn)換為一個(gè)固定長(zhǎng)度的字符串,而且可以保證原始內(nèi)容不變,產(chǎn)生的hash字符串就不變。

          簡(jiǎn)圖:42597993fd47bd63b642370ecc636c78.webp

          4. 合并 chunk assets

          將多個(gè)chunk的assets合并到一起,并產(chǎn)生一個(gè)總的hash1f5d880d0c64f581f60da994346cea27.webp

          「輸出 emit」

          webpack將利用node中的fs模塊(文件處理模塊),根據(jù)編譯產(chǎn)生的總的assets,生成相應(yīng)的文件。85f32a7f18ab42ffe4aade375615a636.webp

          「總過程」3541dedd14e1ebc3e0f468460a946d29.webp

          當(dāng)敲下webpack打包命令之后,文件開始初始化,各個(gè)參數(shù)進(jìn)行融合,形成一個(gè)最終的配置對(duì)象,然后把配置對(duì)象交給編譯器進(jìn)行編譯, 通過入口模塊找到互相依賴模塊形成模塊列表,接下來webpack會(huì)根據(jù)配置,為chunk生成一個(gè)資源列表,然后將每一個(gè)chunk生成的資源合并成一個(gè)完整的資源,并且生成一個(gè)完整的hash值,最終根據(jù)完整的資源列表輸出到文件。

          涉及術(shù)語

          1. module:模塊,分割的代碼單元,webpack中的模塊可以是任何內(nèi)容的文件,不僅限于JS
          2. chunk:webpack內(nèi)部構(gòu)建模塊的塊,一個(gè)chunk中包含多個(gè)模塊,這些模塊是從入口模塊通過依賴分析得來的
          3. bundle:chunk構(gòu)建好模塊后會(huì)生成chunk的資源清單,清單中的每一項(xiàng)就是一個(gè)bundle,可以認(rèn)為bundle就是最終生成的文件
          4. hash:最終的資源清單所有內(nèi)容聯(lián)合生成的hash值
          5. chunkhash:chunk生成的資源清單內(nèi)容聯(lián)合生成的hash值
          6. chunkname:chunk的名稱,如果沒有配置則使用main
          7. id:通常指chunk的唯一編號(hào),如果在開發(fā)環(huán)境下構(gòu)建,和chunkname相同;如果是生產(chǎn)環(huán)境下構(gòu)建,則使用一個(gè)從0開始的數(shù)字進(jìn)行編號(hào)

          ?? 最后

          若本文對(duì)于 webpack編譯原理 閱讀有任何錯(cuò)誤的地方,歡迎大家給我提意見,一定虛心聽取你們的指正,若覺得不錯(cuò)的,也可以點(diǎn)個(gè)??「star」 ?? 支持一下我。

          最后,也可以關(guān)注我的公眾號(hào):「前端獵手」,或是添加我的微信(wKavin)私底下進(jìn)行交流。

          「歡迎各位大佬關(guān)注我,掃二維碼即可」


          熱文導(dǎo)讀




          瀏覽 52
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  肏屄网视频 | 日逼性爱视频A级片 | 成人中文在线视频 | 国产性情网站在线看 | 香蕉视频三级片 |