前端模塊化實現現狀
1. <script> 標簽
<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>
<script src="module3.js"></script>
這個是通過把接口暴露到window全局變量上,其他部分通過閉包來進行封裝。
缺點
- 全局變量容易出現沖突
- 只能按script的順序進行加載
- 開發人員主觀來解決依賴關系
- 難管理
- 瀏覽器一般只能并行load 3-5 個script文件,所以多余6個一般加載會慢
2. CommonJS
服務器端nodejs所遵循的CommonJS規范,通過require和exports來加載和暴露模塊,以文件為模塊。
在后臺中,這和我們大部分時候對nodejs異步處理的印象是不同的,require永遠的同步的。
優點
- 便于重用
- 規范
- 易用
- 可用package非常多
缺點
- 同步,不適合瀏覽器
- 不可以并行的非阻塞的加載多個模塊。
實現方式
我經常用的是browserify
AMD
這個主要是為了瀏覽器端定義的。asynchronous module definition 規范其實只有一個主要接口 define(id?, dependencies?, factory),它要在聲明模塊的時候指定所有的依賴 dependencies,并且還要當做形參傳到 factory 中,對于依賴的模塊提前執行,依賴前置。
define("module", ["dep1", "dep2"], function(d1, d2) {
return someExportedValue;
});
require(["module", "../file"], function(module, file) { /* ... */ });
優點
- 優點是適合瀏覽器異步加載
- 可以多個模塊并行加載
缺點
不優雅
實現方式
requrejs
CMD
common module definition 這個規范和 amd相似,同時保持了和nodejs的commonjs規范的兼容性。
define(function(require, exports, module){
var $ = require('jquery');
exports.something = 'hello';
});
優點
- 并行異步加載
- 和nodejs兼容
缺點
需要SPM打包, 邏輯偏重
ES6的模塊加載
實現在編譯時確認依賴關系,而不是在執行的時候。
import jquery from 'jquery'
export default (n) => {n*3}
優點
- 容易進行靜態分析
- 面向未來的es標準
缺點
- 原生的瀏覽器還沒有支持
- 新版的nodejs才支持
實現方式
babel
前端模塊加載
前端模塊運行在客戶的瀏覽器中,所以需要增量加載到瀏覽器中。
模塊的加載和傳輸我們首先想到了兩種方式 1.每一模塊一個請求 2.所有模塊一個請求,前者請求連接數太多影響速度,后者第一次加載文件過大,比較慢,初始化時間慢,都比較簡單粗暴。
我們想要實現的分塊傳輸,按需進行依賴加載,在實際應用中用到某個模塊在增量更新,才是比較合理的。
要實現按需加載,就需要對整個代碼進行靜態分析和編譯打包。
所有的資源都是模塊
圖片,html模塊,css/scss, js 等等其實都是模塊,那么我們的實現就非常優雅:
require('./css/custom.scss')
require('./template.jade')
require('./image.png')
這個就是webpack所實現的。