目前主流的 JavaScript
模塊化規範有 CommonJS,AMD,CMD,ES6 Module 四種規範html
CommonJS 主要應用於服務端 (node),其主要內容爲:一個單獨的文件就是一個模塊,每個模塊都是一個單獨的做用域,模塊必須經過 module.exports
導出對外的變量或接口,經過 require()
來導入其餘模塊的輸出到當前的模塊的做用域中node
//node環境編譯
//a.js
let b = 0
exports.a = () => {
console.log('a')
b+=1
}
exports.b = () => {
console.log(b)
}
//b.js
const {a, b} = require('./a');
a() //a
module.exports.b = () => {
console.log('b')
a() //a
}
//c.js
const bf = require('./b').b;
var {a, b} = require('./a');
a() //a
b() //2
bf() //b
b() // 3
var {a, b} = require('./a');
b() // 3 讀取的是緩存
複製代碼
模塊加載的順序,按照其在代碼中出現的順序,同步加載的方式加載。瀏覽器
NodeJs 對引入過的模塊都會進行緩存,以減小二次引入時的開銷。不一樣的是,瀏覽器僅緩存文件,而在 NodeJs 中緩存的是編譯和執行後的對象。緩存
輸入的是被輸出的值的拷貝。一旦輸出一個值,模塊內部的變化就影響不到這個值。異步
異步模塊加載機制,它採用異步方式加載模塊,模塊的加載不影響它後面語句的運行。全部依賴這個模塊的語句都定義在一個回調函數中,等到依賴加載完成以後,這個回調函數纔會運行。模塊化
AMD 的誕生,就是爲了解決函數
經過 define(id?: String, dependencies?: String[], factory: Function|Object)
來定義模塊ui
require([module], callback)
來引入模塊<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./require.js" data-main="main.js"></script>
</body>
</html>
複製代碼
//a.js
define(function() {
var sayHi = () => {
console.log("Hi-a")
}
return {
//返回接口
sayHi:sayHi,
a:1
}
})
//b.js
define(function() {
var sayHi = () => {
console.log("Hi-b")
}
return {
sayHi:sayHi,
b:2
}
})
//c.js
define([
//依賴模塊
'./a.js',
'./b.js'
], function(a, b) {
console.log(a,b)
a.a++
b.b++
return {
c: a.a + b.b
}
});
//main.js
require(["./a","./b","./c.js"], function(a,b,c) {
console.log(a,b,c)
a.sayHi() //Hi-a
b.sayHi() //Hi-b
console.log(c.c) //5
})
複製代碼
CMD (Common Module Definition) 通用模塊定義,瀏覽器端的實現有 SeaJS,跟RequireJS同樣動態建立異步的 script 標籤。區別在於AMD 推崇一開始就加載全部的依賴,CMD推崇有須要的地方纔進行依賴加載spa
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./sea.js"></script>
<script> seajs.config({ alias:{ 'main':'./main.js' }, }); seajs.use(['main'],function(main) { main.sayHi()//a-b-c }); </script>
</body>
</html>
複製代碼
//a.js
define(function(require, exports) {
var a = 'a'
exports.a = a
});
//b.js
//SeaJS 會首先用正則匹配出代碼裏面全部的 require 語句,拿到依賴,而後依次加載,加載完成再執行回調函數
define(function(require, exports) {
var a = require('./a.js').a
var b = a + '-b'
exports.b = b
});
//c.js
define(function(require, exports) {
var b = require('./b.js').b
var c = b + '-c'
exports.c = c
});
//main.js
define(function(require, exports) {
var c = require('./c.js').c
exports.sayHi = function(){
console.log(c)
}
});
複製代碼
ES Module 是 ES6 引入的模塊化功能,主要由 export 和 import 兩個命令構成,export 用於規定模塊對外接口,import 用於輸入其餘模塊提供的功能。code
//a.js
//導出變量
export var a = 1
//導出函數
export function b(){
}
//導出類
export class C {
constructor(){
}
}
var d = 100
//導出對象
export {
d
}
//重命名導出
export { d as e}
//默認導出,一個模塊只能有一個默認導出
export default d
//b.js
import { a } from "./a.js";
複製代碼