當前位置:
首頁 > 知識 > 打包工具的配置教程見的多了,但它們的運行原理你知道嗎?

打包工具的配置教程見的多了,但它們的運行原理你知道嗎?

前端模塊化成為了主流的今天,離不開各種打包工具的貢獻。社區裡面對於webpack,rollup以及後起之秀parcel的介紹層出不窮,對於它們各自的使用配置分析也是汗牛充棟。為了避免成為一位「配置工程師」,我們需要來了解一下打包工具的運行原理,只有把核心原理搞明白了,在工具的使用上才能更加得心應手。

本文基於parcel核心開發者@ronami的開源項目minipack而來,在其非常詳盡的注釋之上加入更多的理解和說明,方便讀者更好地理解。


1、打包工具核心原理

顧名思義,打包工具就是負責把一些分散的小模塊,按照一定的規則整合成一個大模塊的工具。與此同時,打包工具也會處理好模塊之間的依賴關係,最終這個大模塊將可以被運行在合適的平台中。

打包工具會從一個入口文件開始,分析它裡面的依賴,並且再進一步地分析依賴中的依賴,不斷重複這個過程,直到把這些依賴關係理清挑明為止。

從上面的描述可以看到,打包工具最核心的部分,其實就是處理好模塊之間的依賴關係,而minipack以及本文所要討論的,也是集中在模塊依賴關係的知識點當中。

為了簡單起見,minipack項目直接使用ES modules規範,接下來我們新建三個文件,並且為它們之間建立依賴:

它們的依賴關係非常簡單: ,其中 將會成為打包工具的入口文件。

但是,這裡面的依賴關係只是我們人類所理解的,如果要讓機器也能夠理解當中的依賴關係,就需要藉助一定的手段了。


2、依賴關係解析

新建一個js文件,命名為 ,首先引入必要的工具。

接下來,我們會撰寫一個函數,這個函數接收一個文件作為模塊,然後讀取它裡面的內容,分析出其所有的依賴項。當然,我們可以通過正則匹配模塊文件裡面的 關鍵字,但這樣做非常不優雅,所以我們可以使用 這個js解析器把文件內容轉化成抽象語法樹(AST),直接從AST裡面獲取我們需要的信息。

得到了AST之後,就可以使用 去遍歷這棵AST,獲取當中關鍵的「依賴聲明」,然後把這些依賴都保存在一個數組當中。

最後使用 的 方法搭配 插件,把ES6語法轉化成瀏覽器可以識別的ES5語法,並且為該js模塊分配一個ID。

運行 ,輸出如下:

可見 文件已經變成了一個典型的模塊,且依賴已經被分析出來了。接下來我們就要遞歸這個過程,把「依賴中的依賴」也都分析出來,也就是下一節要討論的建立依賴關係圖集。


3、建立依賴關係圖集

新建一個名為 的函數,傳入一個入口文件的路徑作為參數,然後通過 解析這個文件使之定義成一個模塊。

接下來,為了能夠挨個挨個地對模塊進行依賴分析,所以我們維護一個數組,首先把第一個模塊傳進去並進行分析。當這個模塊被分析出還有其他依賴模塊的時候,就把這些依賴模塊也放進數組中,然後繼續分析這些新加進去的模塊,直到把所有的依賴以及「依賴中的依賴」都完全分析出來。

與此同時,我們有必要為模塊新建一個 屬性,用來儲存模塊、依賴、依賴ID之間的依賴關係,例如「ID為0的A模塊依賴於ID為2的B模塊和ID為3的C模塊」就可以表示成下面這個樣子:

搞清楚了個中道理,就可以開始編寫函數了。

可能有讀者對其中的 循環當中的 有點迷,但是只要嘗試過下面這段代碼就能搞明白了:

嘗試運行一下 ,就能夠看到如下的輸出:

現在依賴關係圖集已經構建完成了,接下來就是把它們打包成一個單獨的,可直接運行的文件啦!

4、進行打包

上一步生成的依賴關係圖集,接下來將通過 規範來實現載入。由於篇幅關係,本文不對 規範進行擴展,有興趣的讀者可以參考@阮一峰 老師的一篇文章《瀏覽器載入 CommonJS 模塊的原理與實現》,說得非常清晰。簡單來說,就是通過構造一個立即執行函數 ,手動定義 , 和 變數,最後實現代碼在瀏覽器運行的目的。

接下來就是依據這個規範,通過字元串拼接去構建代碼塊。

最後運行 ,輸出如下:

這段代碼將能夠直接在瀏覽器運行,輸出「Hello world!」。

至此,整一個打包工具已經完成。


5、歸納總結

經過上面幾個步驟,我們可以知道一個模塊打包工具,第一步會從入口文件開始,對其進行依賴分析,第二步對其所有依賴再次遞歸進行依賴分析,第三步構建出模塊的依賴圖集,最後一步根據依賴圖集使用 規範構建出最終的代碼。明白了當中每一步的目的,便能夠明白一個打包工具的運行原理。

最後再次感謝@ronami的開源項目minipack,其源碼有著更為詳細的注釋,非常值得大家閱讀。

作者:jrainlau

https://segmentfault.com/a/1190000015291911


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 JavaScript 的精彩文章:

用 npm script 打造超溜的前端工作流
React 走紅前端,最強技能圖快速 Get!

TAG:JavaScript |