Js 模块规范对比 CommonJs AMD ES6

JavaScript 中的模块,本质上都是为了解决 Js 的作用域问题而定义的模块形式

AMD 浏览器环境 异步

AMD (The Asynchronous Module Definition) 规范的格式和栗子如下

define(id?, dependencies?, factory); //格式

//example 
 define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
       exports.verb = function() {
           return beta.verb();
           //Or:
           return require("beta").verb();
       }
   });

CommonJs 同步加载模块 服务器环境  浏览器也可以变相实现

特点:

  • 运行时加载,取出的是一个对象。
  • CommonJS 模块输出的是值的缓存,不存在动态更新。
// foobar.js

function foobar(){
        this.foo = function(){
                console.log('Hello foo');
        }
 
        this.bar = function(){
                console.log('Hello bar');
        }
}
 
exports.foobar = foobar; /**导出写法1**/

module.exports = function () { /**导出写法2**/
  console.log("hello world")
}



//调用
var foobar = require('./foobar').foobar,
    test   = new foobar();
 
test.bar(); // 'Hello bar'

ES6 的模块化

ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。

// ES6模块
import { stat, exists, readFile } from 'fs';

上面代码的实质是从fs模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。

特点:

  • 自动采用严格模式
  • export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
  • import命令是编译阶段执行的,在代码运行之前。
/**写法1**/
// export-default.js
export default function () {
  console.log('foo');
}

//导入时可以指定任意名字(仅限用 export default 导出的前提下)
// import-default.js
import customName from './export-default';
customName(); // 'foo'

// 导入时指定和导出一样的命名
// main.js
import {firstName, lastName, year} from './profile';
/** 写法2 **/
//整体输出
export * from 'my_module';

// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

//单个导出
export {firstName, lastName, year};


function v1() { ... }
function v2() { ... }

//别名导出
export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

关于ES6 模块的用法可以参照 阮一峰的 es6 入门,很详细。

参考 :

https://github.com/amdjs/amdjs-api/blob/master/AMD.md

http://es6.ruanyifeng.com/#docs/module