复习webpack4之实现简易的webpack
之前學(xué)習(xí)過webpack3的知識,但是webpack4升級后還是有很多變動的,所以這次重新整理一下webpack4的知識點(diǎn),方便以后復(fù)習(xí)。
這次學(xué)習(xí)webpack4不僅僅要會配置,記住核心API,最好還要理解一下webpack更深層次的知識,比如打包原理等等,所以可能會省略一些比較基礎(chǔ)的內(nèi)容,但是希望我可以通過此次學(xué)習(xí)掌握webpack,更好地應(yīng)對以后的工作。
這一節(jié)會深入理解webpack原理
1.模塊分析
我們這一次會實(shí)現(xiàn)一個類似webpack的工具,首先來寫模塊分析部分。
代碼地址:
代碼倉庫
先把目錄搭好,src下有三個js文件,每個文件里面對應(yīng)以下內(nèi)容:
word.js
message.js
index.js
現(xiàn)在這個代碼在瀏覽器中是沒有辦法運(yùn)行的,需要借助類似webpack這種工具才可以,所以我們需要借助node.js實(shí)現(xiàn)一個打包工具。
和src同級,我們新建一個bundler.js。
創(chuàng)建一個函數(shù),用來分析打包入口文件,支持傳入一個參數(shù)(文件路徑),然后利用node讀取文件內(nèi)容。
而index中引用了message.js,我們需要把引用的文件名提取出來,要借助@babel/parser分析我們的源代碼。
cnpm install @babel/parser --save 復(fù)制代碼@babel/parser提供了一個parse方法,第一個參數(shù)傳入文件內(nèi)容,第二個參數(shù)傳一個對象。
方法返回的對象是一個抽象語法樹(AST)。
對象里面有一個program.body,內(nèi)容是這樣的:
第一個Node的type是ImportDeclaration,意思是引入聲明語句,我們index.js中第一行確實(shí)是引入語句。第二個Node的type是ExpressionStatement,意思是表達(dá)式語句,我們第二行寫的console.log(),確實(shí)是表達(dá)式語句。所以借助這個工具,我們就可以分析文件之間的依賴關(guān)系。
為了找出所有的依賴關(guān)系,我們要遍歷所有type是ImportDeclaration的語句,自己寫會比較麻煩,還可以借助@babel/traverse
cnpm install --save @babel/traverse 復(fù)制代碼traverse是一個函數(shù),第一個參數(shù)接受抽象語法樹,第二個參數(shù)是一個對象。
抽象語法樹中有元素的type是ImportDeclaration時,就會執(zhí)行ImportDeclaration函數(shù),它接受的參數(shù)可以解構(gòu)出一個node,它就是所有type是ImportDeclaration的元素,就是我們所有的依賴,里面喲一個source,value值就是文件名,所以我們就可以把所有文件名都存起來
聲明一個數(shù)組,把所有node中的soure.value都push到數(shù)組中。
這樣入口分析就已經(jīng)分析好了,但是這時候分析的依賴都是相對路徑,我們要把它改為絕對路徑,或者是相對于根路徑的相對路徑,這樣才不會有問題,所以要借助node中的path。
但是我們?yōu)榱朔奖阋院箝_發(fā),現(xiàn)在應(yīng)該把絕對路徑和相對路徑都存好,所以把原先的數(shù)組變成對象,用以下方法存起來。
對象的key是相對路徑,value是絕對路徑。
然后就返回入口文件名,和文件所有依賴的內(nèi)容。
但是我們用的ES Module引入文件,瀏覽器無法識別這個語法,就要依賴@babel/core。
cnpm install --save @babel/core 復(fù)制代碼@babel/core提供了一個方法,transformFromAst,可以把抽象語法樹轉(zhuǎn)化成瀏覽器可以運(yùn)行的代碼。
傳入的參數(shù)中還可以配置ES6轉(zhuǎn)ES5的插件,所以要先安裝一下@babel/preset-env。
cnpm install --save @babel/preset-env 復(fù)制代碼函數(shù)會返回一個對象,里面有一個code屬性,code屬性中就是我們?yōu)g覽器可以運(yùn)行的代碼。
最后返回我們分析的結(jié)果。
返回的結(jié)果意思是:入口文件是index.js;引用的依賴是message.js,地址是src/message.js;瀏覽器中可以運(yùn)行的代碼是code中的內(nèi)容。
2.依賴圖譜
我們現(xiàn)在只分析了入口文件的依賴,接下來我們要開始分析其他依賴,從message開始,一層一層把所有依賴都分析完。
我們再創(chuàng)建一個函數(shù),用來制作依賴圖譜,利用類似遞歸的方式,調(diào)用moduleAnalyser逐層分析依賴內(nèi)容,并把它們都放到一個數(shù)組中。
最后生成的數(shù)組。
然后我們把它整合成一個對象,用路徑作為key,依賴和代碼作為value,并且返回這個對象。
對象的內(nèi)容。
3.生成代碼
拿到依賴圖譜,現(xiàn)在要開始生成瀏覽器可以運(yùn)行的代碼了。
先看生成的代碼中,存在require和exports兩個方法,但是瀏覽器中沒有這兩個方法,所以我們要先定義這兩個方法,然后把生成的代碼片段利用閉包的形式執(zhí)行。
require函數(shù)中,通過傳入路徑拿到對應(yīng)的代碼,利用eval()執(zhí)行,如果require中有依賴,繼續(xù)執(zhí)行require時拿到的就是相對路徑,需要轉(zhuǎn)成絕對路徑,直接去我們之前創(chuàng)建的對象中取就可以。
exports是一個空對象即可,這樣導(dǎo)出的內(nèi)容會被存到exports中。
然后把生成的代碼格式化一下,復(fù)制到瀏覽器中執(zhí)行。
就打印出say hello了。
這樣,我們就已經(jīng)實(shí)現(xiàn)了一個簡易的webpack打包工具了,具體代碼可以去我的github倉庫里面看。
參考
從基礎(chǔ)到實(shí)戰(zhàn) 手把手帶你掌握新版Webpack4.0 ----DellLee轉(zhuǎn)載于:https://juejin.im/post/5d00fbbb5188255e780b64b1
總結(jié)
以上是生活随笔為你收集整理的复习webpack4之实现简易的webpack的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL 时间处理
- 下一篇: 剑指Offer 56 数组中数字出现的次