如果您覺得該文檔對您有幫助莽红,請打賞妥畏,五毛十毛均可。另外安吁,轉(zhuǎn)載請注明作者及出處醉蚁。
Web 應用程序已經(jīng)變得非常復雜,我們需要用項目構(gòu)建工具來應對這種復雜性柳畔,處理各種可能遇到的問題
模塊系統(tǒng)的標準問題
目前模塊系統(tǒng)有幾種不同的標準:
-
<script>
標簽 (沒有模塊系統(tǒng)) CommonJS
AMD
-
ES6
模塊 - 其他
<script>
標簽
使用 <script>
標簽馍管,可以在沒有模塊系的情況下,對代碼進行簡單的管理薪韩,之前我們都是這樣做的:
<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>
<script src="module3.js"></script>
各個模塊中的接口都會被導入到全局對象中确沸,比如 window
對象;這樣就可以在任何地方通過全局對象訪問這些接口
問題:
- 可會能引發(fā)沖突
- 加載順序難以管理
- 依賴問題難以管理
- 引入的腳本會非常多俘陷,難以閱讀和理解
CommonJs 標準:同步 require
創(chuàng)建模塊的時候罗捎,通過給 exports
對象添加屬性和方法,或者通過給 module.exports
設置值來定義模塊的接口拉盾。
引用的時候桨菜,使用同步 require
方法導入模塊的接口。
//導入模塊
require("module");
require("../file.js");
//創(chuàng)建模塊接口
exports.doStuff = function() {};
module.exports = someValue;
這種方法常常被用在服務端的 node.js
程序中捉偏。
優(yōu)點
- 在服務端倒得,模塊可以被重用
- 已經(jīng)有大量這樣的模塊,通過
npm
管理 - 簡單
缺點
- 因為是同步導入模塊夭禽,會導致程序掛起霞掺,不適用于網(wǎng)絡應用
- 不能并行導入多個模塊
實現(xiàn)
-
node.js
用在服務端 browserify
-
modules-webmake
編譯成一個包 -
wreq
用在客戶端
AMD 標準:異步 require
AMD 標準中,定義模塊和導入模塊的方式與 CommonJs 是不一樣的
//導入模塊
require(["module", "../file"], function(module, file) { /* ... */ });
//定義模塊
define("mymodule", ["dep1", "dep2"], function(d1, d2) {
return someExportedValue;
});
優(yōu)點:
- 適用于網(wǎng)絡應用
- 可以并行導入多個模塊
缺點:
- 編碼復雜讹躯,閱讀和書寫都很困難
- 有很多替代方法
實現(xiàn):
-
require.js
客戶端 -
curl
客戶端
ES6 模塊
EcmaScript6 從語言層面內(nèi)建了模塊系統(tǒng)
import "jquery";
export function doStuff() {}
module "localModule" {}
優(yōu)點:
- 行業(yè)標準
確定:
- 目前很多瀏覽器還不支持 ES6
- 目前很少有模塊使用這種方式
最佳方式
能夠讓開發(fā)者自己選擇模塊標準菩彬,即時可以使用已經(jīng)存在的代碼庫潮梯,也能容易的添加自己定義的模塊骗灶。
傳輸問題
如果想讓模塊在客戶端執(zhí)行,必須通過網(wǎng)絡從服務端將他們傳輸過來秉馏。極端情況下耙旦,會出現(xiàn)下面這兩種情況:
- 為每個模塊發(fā)送一個請求
- 所有模塊只用一個請求
通常,我們兩種情況都會遇到萝究,兩種情況都存在一些問題:
-
每個模塊一個請求
- 優(yōu)點:只請求需要的模塊
- 缺點:會有很多請求母廷,造成性能問題
-
所有模塊一個請求
- 優(yōu)點:請求少,不會造成性能問題
- 確定:會引入很多無用的模塊
折中方式
折中的方式是:將所有模塊編譯成幾個小的分塊糊肤,減少了請求數(shù)量琴昆,也減少了無效的引用
資源管理問題
當前的 Web 引用已經(jīng)很復雜,除了 Javascript
馆揉,還有其他各種資源需要引入:
-
stylesheets
樣式表 -
images
圖片 -
webfonts
字體 -
html
模板 - 其他
除此以外业舍,還有一些翻譯轉(zhuǎn)換工作
-
coffeescript
→javascript
-
elm
→javascript
-
less stylesheets
→css stylesheets
-
jade templates
→javascript which - generates html
-
i18n files
→something
- 其他
我們希望能像下面這樣引入資源
require("./style.css");
require("./style.less");
require("./template.jade");
require("./image.png");
依賴管理問題
現(xiàn)代 Web 應用會導入很多外部依賴,管理起來非常困難升酣,特別是某些依賴還是以表達式的形式出現(xiàn)舷暮,比如
require("./template/" + templateName + ".jade")
除此以外,還有很多其他稀奇古怪的形式噩茄。
策略
一個優(yōu)秀的解析器可以讓使用各種古怪依賴管理的代碼正常運行下面。