Commonjs,AMD,CMD和ES6module的實現及差別

爲何要模塊化

1. 下降複雜度,下降耦合度
2. 部署方便,功能點明確

 

模塊化的好處

1. 避免命名衝突
2. 更好的分離,按需加載
3. 提升複用性
4. 高可維護性

 

CommonJS

規範:

1. 每一個文件均可以當作一個模塊
2. 在服務器端:模塊的加載是運行時同步加載的
3. 在瀏覽器端:模塊須要提早編譯打包處理

 

基本語法:

1. 暴露模塊,暴露的本質是exports這個對象
module.exports = value
exports.xxx =value

 

2. 引入模塊
require()

 

實現

1. 服務器端實現 Node.js

//module1.js
module.exports = {
msg : 'module1',
foo(){
console.log(this.msg);
}
}

  

//module2.js
module.exports = function(){
console.log('module2');
}
//至關於給exports對象賦值

 

//module3.js
exports.foo = function(){
console.log('foo() module3');
}
exports.boo = function(){
console.log('boo() module3');
}
exports.arr = [1,2,3,4,4,6,6,5,2,1]
//至關於給exports對象屬性賦值

 

let uniq = require('uniq') //數組去重排序第三方包,是一個函數
let module1 = require('./modules/modules1')
let module2 = require('./modules/modules2')
let module3 = require('./modules/modules3')


module1.foo() //module1
module2() //module2
module3.foo() //foo() module3
module3.boo() //boo() module3
console.log(uniq(module3.arr))

  

 

2. 瀏覽器端實現 Browserify

1. 建立好文件目錄結構

 

 

2. 下載browserify

全局安裝: npm install browserify -g
局部安裝: npm install browserify --save-dev
 

3. 模塊實現

//module1.js
module.exports = {
msg : 'module1',
foo(){
console.log(this.msg);
}
}
//module2.js
module.exports = function(){
console.log('module2');
}
//至關於給exports對象賦值
 

//module3.js
exports.foo = function(){
console.log('foo() module3');
}
exports.boo = function(){
console.log('boo() module3');
}



//app.js
let module1 = require('./module1')
let module2 = require('./module2')
let module3 = require('./module3')
 

module1.foo()
module2()
module3.boo()
module3.foo()

  

 

4. 此時運行app.js在瀏覽器會報錯,須要打包處理js

browserify js/src/app.js -o js/dist/bundle.js

 

5. 頁面使用引入

<script src="./js/dist/build.js"></script>

  

AMD(異步模塊定義)

專門用於瀏覽器端,模塊的加載是異步的

 

基本語法:

1. 定義暴露模塊

//1.定義沒有依賴的模塊
define(function(){
return 模塊
})
 

//2.定義有依賴的模塊
define(['module1','module2'],function(m1,m2){
return 模塊
})

  

 

2. 引入使用模塊

require(['module1','module2'],function(m1,m2){
使用m1 m2
})

  

 

使用教程:

1. 下載require.js而且引入

2. 建立項目結構

 

 

3. 定義模塊

//定義沒有依賴的模塊
define(function(){
let name = 'module1.js',
function getName(){
return name
}
//暴露模塊
return {getName}
})
 

//定義有依賴的模塊
define(['module1','jquery'],function(module1,$){
let msg = 'module2.js',
function show(){
console.log(msg,module1.getName())
}
$('body').css('backgroundColor','red')
//暴露模塊
return {show}
})
 

//引入模塊
(function(){
requirejs.config({
//baseUrl: 'js/lib', //基本的路徑,和paths裏面的路徑要拼接
paths:{ //配置路徑
module1:'./modules/module1',
module2:'./modules/module2',
jquery:'./libs/jquery-1.10.1'
}
})
requirejs(['module2'],function(module2){
module2.show()
})
})()
 

//html
<script data-main="js/main.js" src="js/lib/require.js"></script>

 

 

CMD

專門用於瀏覽器端,模塊的加載是異步的,使用時纔會加載執行

 

基本語法

1. 定義暴露模塊

//定義沒有依賴的模塊
define(function(reqiuire,exports,module){
exports.xxx = value
module.exports = value
})
 

//定義有依賴的模塊
define(function(require,exports,module){
//同步引入依賴模塊
let module2 = require('./module2')
//異步引入依賴模塊
require.async('./module3',function(module3){
 

})
//暴露模塊
exports.xxx = value
})

  

2. 引入使用模塊

define(function(require){
let m1 = require('./module1')
let m4 = require('./module4')
m1.show()
m4.show()
})

  

 

使用教程:

1. 下載安裝

2. 建立項目結構

js
  lib
    sea.js
  modules
    module1.js
    module2.js
    module3.js
    module4.js
  main.js
index.html

 

3. 定義模塊

define(function(require,exports,module){
let msg = 'module1'
function foo(){
return msg
}
//暴露模塊
module.exports = {foo}
})



define(function(require,exports,module){
let msg = 'module2'
function boo(){
console.log(msg)
}
module.exports = boo
})



define(function(require,exports,module){
let data = 'module3'
function fun(){
console.log(data)
}
exports.module3 = {fun}
})



define(function(require,exports,module){
let msg = 'module4'
//同步引入
let module2 = require('./module2')
module2() //module2
//異步引入
require.async('./module3',function(module3){
module3.module3.fun() //module3
})
function fun2(require,exports,module){
console.log(msg)
}
exports.fun2 = fun2
})



define(function(require){
let module1 = require('./module1')
module1.foo() //module1
let module4 = require('./module4')
module4.fun2() //module4
})
 

//html
<script src="js/lib/sea.js"></script>
<script>
seajs.use('./js/modules/main.js')
</script>

  

模塊3是異步引入的,回調函數先放到事件隊列,加載其餘主線程的模塊,主線程執行完後,才把隊列中的勾出來使用,因而輸出的順序是1243
 

由於CMD如今幾乎不用了,官網也打不開,所以不去實現



ES6模塊化規範

依賴模塊須要編譯打包處理

 

語法:

1. 導出模塊 export
2. 引入模塊 import

 

實現(瀏覽器端)

1. 使用Babel將ES6編譯爲ES5代碼
2. 使用Browserify編譯打包js

 

使用教程:

1. 文件目錄結構

 

2. 建立package.json文件

 

3. 安裝babel-cli,babel-preset-es2015和browserify(cli:command line interface 命令行接口)

1. npm insatll babel-cli browserify -g
2. npm install babel-preset-es2015 --save-dev
preset 預設(將es6轉換成es5的全部插件打包)

3. 定義.babelrc文件 (rc:run control 運行時控制文件)javascript

{
"presets" : ["es2015"]
}

 

4. 編碼

//module1.js
//暴露模塊 分別暴露
export function foo() {
console.log('foo() module1')
}
 

export function boo() {
console.log('boo() module1')
}
export let arr = [1,2,3,4,5]
 

//module2.js
//統一暴露
function fun(){
console.log('fun() module2');
 
}
 

function fun2(){
console.log('fun2() module2');
 
}
 

//module3.js
//默認暴露 能夠暴露任意數據類型 暴露什麼數據就是接受什麼數據
export default ()=>{
console.log('默認暴露的箭頭函數')
}
 

//默認暴露只能暴露一次,不然會報錯,暴露多個數據能夠放到一個對象中暴露
 

export {fun,fun2}
 

//main.js
//引入其餘的模塊
 

//import xxx from '路徑'
 

import $ from 'jquery'
 

import {foo,boo,arr} from './module1'
import {fun,fun2} from './module2'
import module3 from './module3'
 

$('body').css('backgroundColor','red')
console.log(foo,boo,arr)
console.log(fun,fun2)
module3()
 

//規定在使用分別暴露和統一暴露的時候,必需要用解構賦值的方法接受
 

//html
<script src="js/dist/bundle.js"></script>

  

5. 編譯

1. 使用Babel將es6編譯成es5代碼,包含CommonJS語法 babel js/src -d js/lib
2. 使用Browserify編譯js browserify js/lib/main.js -o js/dist/bundle.js

 

CommonJS模塊和ES6模塊的差別

1. Commonjs是值的複製,原來模塊的值改變了不會影響已經加載的該值。ES6是值是動態的,原來模塊的值改變會影響import加載的值
2. Commonjs是對模塊的淺拷貝,能夠對值進行修改,對複雜數據類型進行修改會影響應原來模塊。ES6是對模塊的引用,改變值會報錯
3. Commonjs重複使用require加載同一個模塊,都只會在第一次加載的時候運行一次,之後的就返回第一次加載的結果
4. Commonjs的this指向當前模塊,ES6的this指向undefined
5. Commonjs加載的是整個模塊,全部接口所有加載進來,ES6能夠單獨加載其中某個接口

 

 AMD和CMD的差別

1. AMD 是 RequireJS 在推廣過程當中對模塊定義的規範化產出。CMD 是 SeaJS 在推廣過程當中對模塊定義的規範化產出。
2. 對於依賴的模塊,AMD是提早執行,CMD是延遲執行,也稱爲延遲加載,即須要的時候才加載
3. AMD推崇依賴前置,CMD推崇依賴就近。AMD一開始依賴就必須寫好,CMD能夠在使用的時候才引入依賴
4. AMD的API默認一個當多個用,CMD的API嚴格區分
相關文章
相關標籤/搜索