對于一個高質(zhì)量的web應(yīng)用程序來說,選擇一個重要的模塊加載器是非常重要的。你可能不想在html頁面中手動的添加script標(biāo)簽,因為這樣很不靈活(你必須手動的對script標(biāo)簽排序、不能在部署的時候壓縮代碼...)。
最終的解決方案是Webpack,并遵循它的基本原理的文檔。
模塊加載器最主要的需求就是允許你寫不同環(huán)境下的代碼。這就意味著同樣的一份代碼能運行在node.js環(huán)境,也能運行在瀏覽器環(huán)境。每一個模塊加載器對服務(wù)器端的支持不同:
- Require.js和WebPack:可以在服務(wù)器端使用
- Browserify:沒有開箱即用的方法
模塊代碼風(fēng)格
Require.js的模塊看起來像這樣:
define(['a', 'b'], function(a, b){return {myModule: 1}})
或者你需要很多的依賴,你可能會感到混亂,你將這么做:
define(function(require, exports, module){
var a = require('a');
var b = require('b');
module.exports = {myModule: 1};
})
這兩種方式都不是最優(yōu)的,因為會增加額外的代碼。
使用WebPack和Browserify看起來像這樣:
var a = require('a');
var b = require('b');
module.exports = {myModule: 1};
這看起來非常像原生的node.js模塊。
投票結(jié)果:
- WebPack: +1;
- Require.js: -1;
- Browserify: +1;
遷移
你可以從任何風(fēng)格遷移到Webpack。舉個例子,我以前用Require.js風(fēng)格的模塊,然后無縫遷移到了Webpack。這非常的快,我不需要對我的源代碼做任何的改變(構(gòu)建過程的配置例外),后來慢慢的我升級到Webpack的方式。這一個點我們不進行投票,但是Webpack再一次閃耀,如果你有一個大項目要處理的話(超過1000個文件)。
別名
別名是非常重要的,因為讓你的代碼組織良好、整潔、健壯且便于維護。
Webpack和Require.js在服務(wù)器端和客戶端都有別名,而Browserify沒有因為它不支持node.js。
為什么別名非常重要,我們看下面的代碼結(jié)構(gòu):
src
client/someFolderA/a.js
shared/logic/complexLogic.js
server/someFolderB/b.js
現(xiàn)在你在服務(wù)器上的server/someFolderB/b.js文件中寫了一些代碼,你將怎么樣去加載complexLogic.js這個文件呢?沒有別名的話會很混亂:
// From file "server/someFolderB/b.js"
require('../../shared/complexLogic');
這不是理想的情況,有很多真實的例子: ghost1, ghost2, ghost3 with 3 levels, material-ui, strider1, strider2。
現(xiàn)在假設(shè)你要把server/someFolderB/b.js這個文件移動到其他的目錄,你將不得不更新所有的相對路徑(有時候相對路徑是好的,但你需要知道什么時候使用它們)。
如果有別名的話,你可能這么做:
// From file "server/someFolderB/b.js"
require('shared/complexLogic');
你需要添加一個名為shared的別名指向src/shared,這讓代碼非常的整潔且更加健壯。
Browserify的用戶也能做類似的事情,但不是最優(yōu)的做法。他們能添加一個命名為node_modules的root項目文件夾。
app
node_modules
client
shared
server
如果你只需要3個root別名且你不介意你的app中多一個node_modules文件的話,這也是不錯的。但是這對新加入的開發(fā)者來說是不直觀的,他們可能會把node模塊放到node_modules文件夾中。
投票結(jié)果:
- WebPack: +1;
- Require.js: +1;
- Browserify: -1;
速度
在開發(fā)的模式中,這是沒有統(tǒng)一標(biāo)準(zhǔn)的。但是從個人經(jīng)驗而言這3者中Require.js是最快的,因為它在運行前不需要任何預(yù)處理的任務(wù)。
構(gòu)建過程的速度取決于2個變量:
- 運行任務(wù)的工具(gulp或者grunt);
- 運行的任務(wù)(Webpack、Require.js、Browserify)
Gulp遠(yuǎn)遠(yuǎn)比grunt要快,沒有做統(tǒng)計比較所有的選項。
投票結(jié)果:
- WebPack: 0;
- Require.js: +1;
- Browserify: 0;
內(nèi)存使用
WebPack和Browserify都需要使用大量的內(nèi)存,因為它們必須把所有的代碼都保存在內(nèi)存中。Require.js是最輕的,因為沒有代碼必須保存在內(nèi)存中。
投票結(jié)果:
- WebPack: 0;
- Require.js: +1;
- Browserify: 0;
集成其他模塊
在Require.js中加載其他模塊需要在配置中去填充,而WebPack做這些幾乎都是自動的。
投票結(jié)果:
- WebPack: +1;
- Require.js: -1;
- Browserify: 0;
Webpack警告
使用增強的require(讓W(xué)ebpack工作在node.js中),你可能會遇到一些問題,比如:加載java的模塊因為它是二進制的(很容易修復(fù),通過原生的node.js的require方法)。
投票結(jié)果:
- WebPack: -1;
- Require.js: 0;
- Browserify: 0;
結(jié)論
通過回顧Webpack、Require.js和Browserify,你能夠很好的理解每一個工具有什么優(yōu)點和缺點。
最后的投票結(jié)果:
- WebPack: 2;
- Require.js: 1;
- Browserify: 0;
在所有的選擇中,強烈建議WebPack結(jié)合gulp一起使用。