一、CommonJS

1、导出方式(exports)

1
2
3
4
5
6
7
8
9
const a = 1
console.log('a:',a);

exports.a = a
exports.b = () => {
return 'hi, girls^^'
}

console.log('exports:', exports);

2、导入方式 require

require 命令第一次加载该脚本时就会执行整个脚本,然后在内存中生成一个对象。需要用到这个模块时,就会到 exports 属性上取值。即使再次执行require命令,也不会再次执行该模块,而是到缓存中取值。

1
2
3
4
5
6
7
8
const b = require('./a').a
console.log('b:',b);

const c = require('./a').b();
console.log('c:', c);

const d = require('./a').a;
console.log('d:', d);

3、加载方式

同步

4、谁在用这个规范

nodeJS

二、AMD、RequireJS

1、导出方式:define(id?, dependencies?, factory)

1
2
3
4
5
6
7
8
9
define(function () {
var add = function (x, y) {
return x + y;
};

return {
add: add,
};
});
  • id:模块的名字,如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字;

  • dependencies:模块的依赖,已被模块定义的模块标识的数组字面量。依赖参数是可选的,如果忽略此参数,它应该默认为 [“require”, “exports”, “module”]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。

  • factory:模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。

  • 依赖前置,所有依赖写到模块前面的数组

    1
    2
    3
    4
    define(['a', 'b'], function(a, b) {
    a.doSomething();
    b.doSomething();
    })

2、导入方式:require([module], callback)

第一个参数[module],是一个数组,里面的成员是要加载的模块,callback是加载完成后的回调函数。

1
2
3
require(['a'], function (a) {
console.log(a.doSomething());
});

3、加载方式

异步

4、谁在用这个规范

RequireJs

三、CMD

1、导出方式:define(factory)

依赖就近,延迟执行,依赖的模块可以在任意一个地方写,

1
2
3
4
5
6
define(function(require, exports, module) {
var a = require('./a');
a.doSomething();
var b = require('./b');
b.doSomething();
})

2、导入方式:use

1
seajs.use(id, callback?)

3、谁在用该规范

sea.js

四、ES6

1、导出方式:export

1
2
3
4
5
6
7
export function test() {
return 'hello world!'
}
const name = 'Amy'
export {name}
const age = 19
export default age

2、导入方式: import

1
import age, {test,name} from './a'

3、谁在用该规范:nodeJS、JavaScript

4、与 commonJS 的区别:

  • 模块加载方式:commonJS,运行时加载模块,ES6,编译时加载模块

  • 导出方式:commonJS 导出的是一个新的对象,输出的是值的拷贝,ES6 输出的是值的引用

  • ES6 模块导入写在脚本中的任意位置都会被提升到头部,优先执行

由于 ES6 是静态编译的,为了使 ES6 可以动态引入可以,可以基于 promise 引入模块

参考资料: