1. 程式人生 > >js模塊化/js模塊加載器/js模塊打包器

js模塊化/js模塊加載器/js模塊打包器

相關 自己 ejs 詳細 異步 bpa 復制 commonjs 渲染

之前對這幾個概念一直記得很模糊,也無法用自己的語言表達出來,今天看了大神的文章,嘗試根據自己的理解總結一下,算是一篇讀後感。

大神的文章:http://www.css88.com/archives/7628
(大神的文章寫的很詳細,建議先看完大神的文章)

一.js模塊化

什麽是js模塊化,我們從歷史說起。

1.一開始我們怎麽寫腳本?就是在html文件中用<script></script>寫代碼

這種方式的缺點:代碼復用靠復制,基本是全局變量。

2.後來我們用js文件寫代碼,用<script></script>的src引入html,html/css/js分離

這種方式的缺點:

代碼雖然可復用,但是<script></script>越來越多,一個html文件加載了好多js(http請求過多,影響性能),

全局變量也多,依賴關系也越來越復制,比如b依賴a,則a文件一定要在b文件之前加載

(這種方式的問題就是全局變量過多和依賴關系復雜)

3.為了解決全局對象的問題,我們進化到第三個階段,用模塊對象和IIFE(立即執行函數)

這種方式的缺點:

雖然暴露的全局變量少了,只有這一個模塊對象,可以說解決了汙染全局變量的問題,但是依賴關系還沒解決,因為IIFE依賴這個模塊對象進行各個文件的操作,就是說導入導出都靠這個模塊對象。

(這個時候已經實現了js模塊化,每個文件都包在匿名函數中,所以說每個文件都是一個模塊,模塊與模塊之間的調用通過這個全局模塊對象,這個時候的問題是,全局變量少了,但是依賴模塊沒解決,所有的js文件都依賴全局模塊對象,就是說這個全局模塊對象要在其他js文件之前引入,所以說我們下個方案就是解決依賴關系)

二.js模塊加載器

新的模塊化方案提出:解決了全局變量和依賴關系的問題,但是性能方面還可以優化。

commonJS規範的提出,讓人們有了新的方案來解決全局變量汙染和依賴關系復雜這兩個問題。(一開始是運行在服務器端)。先讓我們了解下什麽是commonJS。

commonJS是一個規範,不是一個庫,他提出了模塊化方案,定義了一個模塊化的API,讓我們寫出模塊化的js更容易,不再需要借助IIFE。

用法:在一個js文件中,用export導出變量,用require導入

//a.js

var a=1;
module.exports=a;

//b.js
var a=require(/a.js);

這種方式在服務器端運行良好

但是有個問題,這種方式是同步運行的,俗稱CMD(同步模塊定義),(當然服務器端去讀取文件特別快,沒這個問題,不像瀏覽器端還要發請求去獲取),就是說當b.js在require(a.js)時,這個時候js代碼不會去往下執行,他必須等到a.js加載完才可以,如果a.js文件特別大,那麽頁面就會卡死,為什麽?(因為commonJS是同步運行的,而js又是單線程的,會阻塞js文件的渲染),所以說瀏覽器端不能用這種方案,,所以commonJS提出了AMD(異步模塊定義),就是獲取文件是異步的,規範提出來了,但是在瀏覽器怎麽實現?業內大神造出了輪子,用的多的就是require.js和sea.js

RequireJS 和 SeaJS 是模塊加載器

利用模塊加載器,我們只有一個入口文件,然後根據依賴關系去加載對應的js文件,依賴關系在入口文件寫好,(只有一個入口文件,但是解析依賴關系的時候會去加載對應的依賴模塊,加載的js文件就不止一個了)

兩者的區別:

1.兩者都是異步加載js,只不過一個寫法遵循amd,一個寫法遵循cmd,其實都是讓瀏覽器支持模塊化寫法的庫。

2.requirejs是無論模塊需不需要都去加載完全部的依賴文件,seajs是某個模塊需要用到才去加載,所以說AMD體驗好,因為依賴模塊一開始全都加載好了,cmd性能好,因為需要才去加載對應的模塊

這樣我們就可以在瀏覽器端實現模塊化開發了,解決了全局變量的問題,也解決了依賴關系的問題,但是卻也帶來了新的問題,頁面依賴的文件多(瀏覽器解析的時候就會去加載對應的依賴模塊,一個模塊就是一個文件),發起的http請求也多,隨之而來的就是加載性能的影響(HTTP1,並行的http請求有限制個數).這個時候模塊打包器就應運而生了.

三.模塊打包器

在模塊化加載器處理的基礎上,為了減少解析時加載依賴模塊而增加的http請求,我們可以把入口文件打包,在打包的過程中,讓它去加載對應的依賴模塊,最終生成的那份文件就是包含依賴模塊的文件,那樣就可以減少http請求,這樣的打包操作我們交給構建工具或者說打包工具去實現,比如webpack/Browserify/rollup等等,這樣,我們可以只專註怎麽寫出模塊化的,可維護的,高聚合,低耦合的代碼

隨著es6的出現,js原生也出現了模塊開發定義,也有對應的規範,用export導出,用import導入,讓我們可以不用使用requirejs和seajs就能進行模塊化開發,不過目前瀏覽器兼容性有限,不過我們可以用webpack來實現兼容,webpack不只可以幫我們把相關依賴的文件打成一個包,也能幫我們打成一個能夠兼容的包(借助一些loader).

歡迎交流~

js模塊化/js模塊加載器/js模塊打包器