<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        深入講解webpack模塊的基本原理

        來源:懂視網 責編:小采 時間:2020-11-27 19:43:23
        文檔

        深入講解webpack模塊的基本原理

        深入講解webpack模塊的基本原理:這篇文章主要介紹了淺談webpack組織模塊的原理,現在分享給大家,也給大家做個參考。現在前端用Webpack打包JS和其它文件已經是主流了,加上Node的流行,使得前端的工程方式和后端越來越像。所有的東西都模塊化,最后統一編譯。Webpack因為版本的不斷更新以
        推薦度:
        導讀深入講解webpack模塊的基本原理:這篇文章主要介紹了淺談webpack組織模塊的原理,現在分享給大家,也給大家做個參考。現在前端用Webpack打包JS和其它文件已經是主流了,加上Node的流行,使得前端的工程方式和后端越來越像。所有的東西都模塊化,最后統一編譯。Webpack因為版本的不斷更新以

        這篇文章主要介紹了淺談webpack組織模塊的原理,現在分享給大家,也給大家做個參考。

        現在前端用Webpack打包JS和其它文件已經是主流了,加上Node的流行,使得前端的工程方式和后端越來越像。所有的東西都模塊化,最后統一編譯。Webpack因為版本的不斷更新以及各種各樣紛繁復雜的配置選項,在使用中出現一些迷之錯誤常常讓人無所適從。所以了解一下Webpack究竟是怎么組織編譯模塊的,生成的代碼到底是怎么執行的,還是很有好處的,否則它就永遠是個黑箱。當然了我是前端小白,最近也是剛開始研究Webpack的原理,在這里做一點記錄。

        編譯模塊

        編譯兩個字聽起來就很黑科技,加上生成的代碼往往是一大坨不知所云的東西,所以常常會讓人卻步,但其實里面的核心原理并沒有什么難。所謂的Webpack的編譯,其實只是Webpack在分析了你的源代碼后,對其作出一定的修改,然后把所有源代碼統一組織在一個文件里而已。最后生成一個大的bundle JS文件,被瀏覽器或者其它Javascript引擎執行并返回結果。

        在這里用一個簡單的案例來說明Webpack打包模塊的原理。例如我們有一個模塊mA.js

        我隨便定義了一個變量aa和一個函數getDate,然后export出來,這里是用CommonJS的寫法。

        然后再定義一個app.js,作為main文件,仍然是CommonJS風格:

        現在我們有了兩個模塊,使用Webpack來打包,入口文件是app.js,依賴于模塊mA.js,Webpack要做幾件事情:

        1. 從入口模塊app.js開始,分析所有模塊的依賴關系,把所有用到的模塊都讀取進來。

        2. 每一個模塊的源代碼都會被組織在一個立即執行的函數里。

        3. 改寫模塊代碼中和require和export相關的語法,以及它們對應的引用變量。

        4. 在最后生成的bundle文件里建立一套模塊管理系統,能夠在runtime動態加載用到的模塊。

        我們可以看一下上面這個例子,Webpack打包出來的結果。最后的bundle文件總的來說是一個大的立即執行的函數,組織層次比較復雜,大量的命名也比較晦澀,所以我在這里做了一定改寫和修飾,把它整理得盡量簡單易懂。

        首先是把所有用到的模塊都羅列出來,以它們的文件名(一般是完整路徑)為ID,建立一張表:

        關鍵是上面的generated_xxx是什么?它是一個函數,它把每個模塊的源代碼包裹在里面,使之成為一個局部的作用域,從而不會暴露內部的變量,實際上就把每個模塊都變成一個執行函數。它的定義一般是這樣:

        在這里模塊的具體代碼是指生成代碼,Webpack稱之為generated code。例如mA,經過改寫得到這樣的結果:

        乍一看似乎和源代碼一模一樣。的確,mA沒有require或者import其它模塊,export用的也是傳統的CommonJS風格,所以生成代碼沒有任何改動。不過值得注意的是最后的module.exports = ...,這里的module就是外面傳進來的參數module,這實際上是在告訴我們,運行這個函數,模塊mA的源代碼就會被執行,并且最后需要export的內容就會被保存到外部,到這里就標志著mA加載完成,而那個外部的東西實際上就后面要說的模塊管理系統。

        接下來看app.js的生成代碼:

        可以看到,app.js的源代碼中關于引入的模塊mA的部分做了修改,因為無論是require/exports,或是ES6風格的import/export,都無法被JavaScript解釋器直接執行,它需要依賴模塊管理系統,把這些抽象的關鍵詞具體化。也就是說,webpack_require就是require的具體實現,它能夠動態地載入模塊mA,并且將結果返回給app。

        到這里你腦海里可能已經初步逐漸構建出了一個模塊管理系統的想法,我們來看一下webpack_require的實現:

        注意倒數第二句里的modules就是我們之前定義過的所有模塊的generated code:

        webpack_require的邏輯寫得很清楚,首先檢查模塊是否已經加載,如果是則直接從Cache中返回模塊的exports結果。如果是全新的模塊,那么就建立相應的數據結構module,并且運行這個模塊的generated code,這個函數傳入的正是我們建立的module對象,以及它的exports域,這實際上就是CommonJS里exports和module的由來。當運行完這個函數,模塊就被加載完成了,需要export的結果保存到了module對象中。

        所以我們看到所謂的模塊管理系統,原理其實非常簡單,只要耐心將它們抽絲剝繭理清楚了,根本沒有什么深奧的東西,就是由這三個部分組成:

        當然以上一切代碼,在整個編譯后的bundle文件中,都被包在一個大的立即執行的匿名函數中,最后返回的就是這么一句話:

        即加載入口模塊app.js,后面所有的依賴都會動態地、遞歸地在runtime加載。當然Webpack真正生成的代碼略有不同,它在結構上大致是這樣:

        可以看到它是直接把modules作為立即執行函數的參數傳進去的而不是另外定義的,當然這和上面的寫法沒什么本質不同,我做這樣的改寫是為了解釋起來更清楚。

        ES6的import和export

        以上的例子里都是用傳統的CommonJS的寫法,現在更通用的ES6風格是用import和export關鍵詞,在使用上也略有一些不同。不過對于Webpack或者其它模塊管理系統而言,這些新特性應該只被視為語法糖,它們本質上還是和require/exports一樣的,例如export:

        而對于import:

        比較特殊的是這樣的:

        情況會稍微復雜一點,它需要載入模塊m的default export,而模塊m可能并非是由ES6的export來寫的,也可能根本沒有export default,所以Webpack在為模塊生成generated code的時候,會判斷它是不是ES6風格的export,例如我們定義模塊mB.js:

        它使用了ES6的export,那么Webpack在mB的generated code就會加上一句話:

        也就是說,它給mB的export標注了一個__esModule,說明它是ES6風格的export。這樣在其它模塊中,當一個依賴模塊以類似import m from './m.js'這樣的方式加載時,會首先判斷得到的是不是一個ES6 export出來的模塊。如果是,則返回它的default,如果不是,則返回整個export對象。例如上面的mA是傳統CommonJS的,mB是ES6風格的:

        我們定義get_export_default函數:

        這樣generated code運行后在mA和mB上會得到不同的結果:

        這就是在ES6的import上,Webpack需要做一些特殊處理的地方。不過總體而言,ES6的import/export在本質上和CommonJS沒有區別,而且Webpack最后生成的generated code也還是基于CommonJS的module/exports這一套機制來實現模塊的加載的。

        模塊管理系統

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        深入講解webpack模塊的基本原理

        深入講解webpack模塊的基本原理:這篇文章主要介紹了淺談webpack組織模塊的原理,現在分享給大家,也給大家做個參考。現在前端用Webpack打包JS和其它文件已經是主流了,加上Node的流行,使得前端的工程方式和后端越來越像。所有的東西都模塊化,最后統一編譯。Webpack因為版本的不斷更新以
        推薦度:
        標簽: 原理 的主要 講解
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲AⅤ无码一区二区三区在线| 久久99国产乱子伦精品免费| 91精品免费久久久久久久久| 亚洲一本大道无码av天堂| 色欲aⅴ亚洲情无码AV蜜桃| 久九九精品免费视频| 激情内射亚洲一区二区三区| A片在线免费观看| 国产啪亚洲国产精品无码| 欧洲乱码伦视频免费国产| 国产一精品一aⅴ一免费| 亚洲中文字幕乱码AV波多JI| 可以免费看黄视频的网站| 亚洲国产精品成人精品软件| 久久免费看黄a级毛片| 亚洲色图古典武侠| 日韩欧毛片免费视频| 亚洲一区二区三区精品视频| 欧美好看的免费电影在线观看| 亚洲伊人久久大香线蕉影院| 美女视频黄的全免费视频网站| www.亚洲日本| 日韩免费观看视频| 无人视频免费观看免费视频 | 亚洲成av人片天堂网无码】| 在线观看免费大黄网站| 亚洲大尺度无码无码专线一区| 国产免费av片在线无码免费看| 日韩在线视频线视频免费网站| 国产亚洲精品影视在线产品| a成人毛片免费观看| 美女网站在线观看视频免费的| 中文字幕亚洲不卡在线亚瑟| 中文日本免费高清| 亚洲日本精品一区二区| 亚洲精品在线免费观看视频| 亚洲色无码国产精品网站可下载| 国产又黄又爽又猛的免费视频播放 | 日韩电影免费在线观看| 好吊妞视频免费视频| 亚洲av无码片vr一区二区三区|