一覽js模組化:從CommonJS到ES6
> 本文由雲 + 社群發表
模組化是指把一個複雜的系統分解到一個一個的模組。
模組化開發的優點:
(1) 程式碼複用,讓我們更方便地進行程式碼管理、同時也便於後面程式碼的修改和維護。
(2) 一個單獨的檔案就是一個模組,是一個單獨的作用域,只向外暴露特定的變數和函式。這樣可以避免汙染全域性變數,減少變數命名衝突。
js 模組化規範有:CommonJS、AMD、CMD、ES6 的模組系統。本文將依次介紹下每個規範。
0.早期:用 script 來引入 js 模組
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="c.js"></script>
<script type="text/javascript" src="d.js"></script>
缺點:
(1) 載入的時候會停止渲染網頁,引入的 js 檔案越多,網頁失去響應的時間越長;
(2) 會汙染全域性變數;
(3) js 檔案之間存在依賴關係,載入是有順序的,依賴性最大的要放到最後去載入;當專案規模較大時,依賴關係變得錯綜複雜。
(4) 要引入的 js 檔案太多,不美觀,程式碼難以管理。
1.CommonJS 規範
是伺服器端模組的規範,由 nodejs 推廣使用。該規範的核心思想是:允許模組通過 require 方法來同步載入所要依賴的其他模組,然後通過 exports 或 module.exports 來匯出需要暴露的介面。
> CommonJS 還可以細分為 CommonJS1 和 CommonJS2,區別在於 CommonJS1 只能通過 exports.xx = xx 的方式匯出,CommonJS2 在 CommonJS1 的基礎上加入了 module.exports = xx 的匯出方式。 CommonJS 通常指 CommonJS2。
採用 CommonJS 規範匯入匯出:
// 匯出
module.exports = moduleA.someFunc;
// 匯入
const moduleA = require('./moduleA');
例項:
//math.js
var num = 0;
function add(a, b) {
return a + b;
}
module.exports = {
//需要向外暴露的變數、函式
num: num,
add: add
}
可以這樣載入:
//引入自定義的模組時,引數包含路徑,可省略.js
//引入核心模組時,不需要帶路徑,如var http = require("http");
var math = require('./math');
math.add(1, 2)//3
實際上,從上面的例子就可以看出,math.add(1,2) 必須要等待 math.js 載入完成,即 require 是同步的。
在伺服器端,模組檔案儲存在本地磁碟,等待時間就是磁碟的讀取時間。但對於瀏覽器而言,由於模組都放在伺服器端,等待時間取決於網上的快慢。因此更合理的方案是非同步載入模組。
缺點:
(1) 不能並行載入模組,會阻塞瀏覽器載入;
(2) 程式碼無法直接執行在瀏覽器環境下,必須通過工具轉換成標準的 ES5;
2.AMD 和 require.js
AMD:非同步模組定義。上面已經介紹過,CommonJS 是伺服器端模組的規範,主要是為了 JS 在後端的表現制定的,不太適合前端。而 AMD 就是要為前端 JS 的表現制定規範。由於不是 JavaScript 原生支援,使用 AMD 規範進行頁面開發需要用到對應的庫函式,也就是 require.js(還有個 js 庫:curl.js)。實際上 AMD 是 require.js 在推廣過程中對模組定義的規範化的產出。
AMD 採用非同步方式載入模組,模組的載入不影響它後面語句的執行。所有依賴這個模組的語句,都定義在一個回撥函式中,等到載入完成之後,這個回撥函式才會執行。
require.js 也採用 require() 語句載入模組,但是不同於 CommonJS:
// 定義一個模組
define('module', ['dep'], function (dep) {
return exports;
});
// 匯入和使用
require(['module'], function (module) {
});
上面示例中的程式碼改寫成 AMD 形式:
math.js 定義一個模組:
define('math', ['jquery'], function (jquery) {//引入jQuery模組
return {
add: function (x, y) {
return x + y;
}
};
});
匯入和使用:
require(['math'], function (math) {
math.add(1, 2)
})
math.add() 與載入 math 模組不是同步的,不會阻塞瀏覽器的載入。
3.CMD 和 sea.js
CMD:通用模組定義。
國內的玉伯大佬寫了 sea.js,實際上 CMD 就是 sea.js 在推廣過程中對模組定義的規範化的產出。
define(function (require, exports, module) {
// 模組程式碼
});
說明:
require:可以把其他模組匯入進來的一個引數;
exports:可以把模組內的一些屬性和方法匯出的;
module: 是一個物件,上面儲存了與當前模組相關聯的一些屬性和方法。
上面示例中的程式碼改寫成 AMD 形式:
define(function (require, exports, module) {
var add = function (a, b) {
return a + b;
}
exports.add = add;
})
//匯入和使用
seajs.use(['math.js'], function (math) {
var sum = math.add(1, 2);
});
CMD 與 AMD 的不同的在於:
(1) AMD 推崇依賴前置;CMD 推崇依賴就近,只有在用到某個模組的時候再去 require:
//AMD推崇的依賴關係前置:在定義模組時就要宣告要依賴的模組
define(['a', 'b', 'c', 'd'], function (a, b, c, d) { // 依賴必須一開始就寫好
a.doSomething()
// 此處省略100行
...
b.doSomething()
...
})
//CMD推崇依賴就近,按需載入,只有在用到某個模組時再去require
define(function (require, exports, modules) {
var a = require('a');
a.doSomething();
// 此處省略100行
...
var b = require("b");//按需載入
b.doSomething();
...
})
(2) AMD 的 API 預設是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。
對於依賴的模組,AMD 是提前執行,CMD 是延遲執行。
具體細節可點選參考
4.ES6 模組化
ES6 在語言的層面上實現了模組化。瀏覽器廠商和 Node.js 都宣佈要原生支援該規範。它將逐漸取代 CommonJS 和 AMD 規範,成為瀏覽器和伺服器通用的模組解決方案。
在 ES6 中,使用 export 關鍵字來匯出模組,使用 import 關鍵字引用模組。但是瀏覽器還沒有完全相容,需要使用 babel 轉換成 ES5。
// 匯出
export function hello() { };
export default {
// ...
};
// 匯入
import { readFile } from 'fs';
import React from 'react';
使用 import 匯入模組時,需要知道要載入的變數名或函式名。
在 ES6 中還提供了 export default,為模組指定預設輸出.對應匯入模組 import 時,不需要使用大括號。
上面示例中的程式碼改寫成 ES6 形式:
//math.js
var num = 0;
var add = function (a, b) {
return a + b;
};
export { num, add };
//匯入
import { num, add } from './math';
function test(ele) {
ele.textContent = add(1 + num);
}
缺點
瀏覽器還沒有完全相容,必須通過工具轉換成標準的 ES5 後才能正常執行。
5.小結
本文從 script 引入 js 檔案講起,到伺服器端模組的規範 CommonJs,再到推崇依賴前置的瀏覽器端模組的規範 AMD、推崇依賴就近的瀏覽器端模組的規範 CMD,最後介紹了 ES6 的模組化。每個介紹中都有各規範基本的用法和一個示例。如有問題,歡迎指正。
此文已由作者授權騰訊雲 + 社群釋出
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- ES6 模組化與 CommonJS 模組化區別JS
- 【譯】JavaScript 模組:從立即執行函式 ( IIFEs ) 到 CommonJS 再到 ES6 模組JavaScript函式JS
- 前端模組化:CommonJS,AMD,CMD,ES6前端JS
- 03_Node js 模組化 CommonJSJS
- 前端模組化:CommonJS,AMD,CMD,ES6(轉載)前端JS
- ES6模組與commonJS模組的差異JS
- 關於前端模組化 CommonJS、AMD、CMD、ES6中模組載入前端JS
- 前端模組化之CommonJS前端JS
- js模組 - amd cmd commonjs esm umdJS
- web系列之模組化——AMD、CMD、CommonJS、ES6 整理&&比較WebJS
- ES6與CommonJS中的模組處理JS
- Commonjs規範與模組化JS
- 模組化之AMD、CMD、UMD、commonJSJS
- CommonJS模組 和 ECMAScript模組JS
- 深度閱讀<Javascript Modules 從IIFEs 到CommonJS 到 ES6 Modules>JavaScriptJS
- 前端進階課程之模組化(一)CommonJS規範前端JS
- 面試- JS Web API - ES6模組化面試JSWebAPI
- ES6 - 模組化
- ES6模組化
- 前端模組化IIFE,commonjs,AMD,UMD,ES6 Module規範超詳細講解前端JS
- 前端模組化AMD、CMD、CommonJS&ES6前端JS
- JS模組化JS
- 你真的懂模組化嗎?教你CommonJS實現JS
- CommonJS和ES6模組迴圈載入處理的區別JS
- 從模組化到NPM私有倉庫搭建NPM
- 前端ES6模組化,Webpack,前端Web
- 前端開發之ES6模組化和node.js,2020.12.09前端Node.js
- 從module的簡單實現到模組化
- 讀懂CommonJS的模組載入JS
- 基於CommonJS規範,簡單實現NodeJs模組化NodeJS
- 從A到Z,26個實用Python模組/函式速覽Python函式
- ES6的模組化語法
- Node.js 如何處理 ES6 模組Node.js
- JS模組化系統JS
- JS模組化規範JS
- 從 java 8到 java 11變化一覽Java
- 從Nest到Nesk -- 模組化Node框架的實踐框架
- ES Module,commonjs和Typescript模組系統JSTypeScript