跳到主要内容

commonJS

2009 年提出的包含模块、文件、 IO 、控制台在哪的一系列标准。在 Node.js 中实现了采用 CommonJS 标准的一部分。

每一个模块有自己单独的作用域。

导出

通过 module.exports 导出模块中的内容:

module.exports = {
a: '',
b: function () {
console.log(this.a);
},
};

require

通过 require 模块进行模块导入, require 模块仅被执行一次。

ES6 Module

在 2015 年提出了 Module ,将 import 和 export 作为保留字加入。 ES6 Modules 会自动采用严格模式。

ES6 导出

导出分为命名导出和默认导出。

在声明时导出:

export const Pai = 3.1415926; // 命名导出
export default 'i am a string of this module default export'; // 默认导出;

先声明后导出:

const Pai = 3.1415926;
const Str = 'i am a nonsense';
export { Pai, Str };

与命名导出不一样,默认导出只有一个。

导入

使用 import 进行导入。

  • 导入命名导出模块时, import 后面要跟一个 将导入的变量名抱起来; import {a ,b } from 'model';
  • 还可以通过 as 关键字对导入的变量重命名 import {a ,b as c } from 'model';
  • 在导入多个变量可以使用批量导入 import \* as allModel from 'model';
  • 对于默认导出, import 后直接跟变量名,并且该名可以自由指定: import {default as a, b} from 'modelA'; import c ,{d} from 'modelC';

复合写法

在将一个模块导入后立即导出:

export { a, b } from 'modelA';

复合写法只针对命名导出,默认导出需要先导入后导出。

CommonJS 和 ES6 的区别

动态与静态

CommonJS 与 ES6 Module 最本质的区别在于前者对模块依赖的解决是“动态的”,而后者是“静态的”。在这里“动态”的含义是,模块依赖关系的建立发生在代码运行阶段;而“静态”则是模块依赖关系的建立发生在代码编译阶段。

require 的模块路径可以动态指定,支持传入一个表达式,我们甚至可以通过 if 语句判断是否加载某个模块。因此,在 CommonJS 模块被执行前,并没有办法确定明确的依赖关系,模块的导入、导出发生在代码的运行阶段。

ES6 Module 的导入、导出语句都是声明式的,它不支持导入的路径是一个表达式,并且导入、导出语句必须位于模块的顶层作用域(比如不能放在 if 语句中)。

  • 死代码检测和排除。我们可以用静态分析工具检测出哪些模块没有被调用过。比如,在引入工具类库时,工程中往往只用到了其中一部分组件或接口,但有可能会将其代码完整地加载进来。未被调用到的模块代码永远不会被执行,也就成为了死代码。通过静态分析可以在打包时去掉这些未曾使用过的模块,以减小打包资源体积

  • 模块变量类型检查。 JavaScript 属于动态类型语言,不会在代码执行前检查类型错误(比如对一个字符串类型的值进行函数调用)。 ES6 Module 的静态模块结构有助于确保模块之间传递的值或接口类型是正确的

  • 编译器优化。在 CommonJS 等动态模块系统中,无论采用哪种方式,本质上导入的都是一个对象,而 ES6 Module 支持直接导入变量,减少了引用层级,程序效率更高

值拷贝与动态映射

在导入一个模块时,对于 CommonJS 来说获取的是一份导出值的拷贝;而在 ES6 Module 中则是值的动态映射,并且这个映射是只读的。

简单说,就像简单值和引用值的关系。

非模块化文件

直接导入即可。

AMD

AMD (异步模块)采用 define 函数来定义模块:

define('ID', ['modelA'], function (a) {
return function (b, c) {
console.log(`sum: ${modelA.add(b + c)}`);
};
});

在 AMD 中使用 define 函数来定义模块,它可以接受3个参数。第1个参数是当前模块的 id ,相当于模块名;第2个参数是当前模块的依赖,比如上面我们定义的 getSum 模块需要引入 calculator 模块作为依赖;第3个参数用来描述模块的导出值,可以是函数或对象。如果是函数则导出的是函数的返回值;如果是对象则直接导出对象本身。

导入:

require(['ID'], function (ID) {
ID(2, 3);
});

npm 模块

使用 npm 导入方法导入:

npm i -s {model name};