likes
comments
collection
share

聊聊 js 模块化(CommonJS, AMD, CMD, ES6)

作者站长头像
站长
· 阅读数 51

前言

文中笔者将介绍几种 js 模块化的规范,以及它们各自的优缺点和差异......

1. CommonJS 规范

CommonJS 主要用在 node 开发上,每个文件就是一个模块,每个文件都有自己的一个作用域。通过module.exports 暴露 public 成员。

此外,CommonJS 通过 require 引入模块依赖,require 函数可以引入 node 的内置模块、自定义模块和 npm 等第三方模块。

var math = require('math');
math.add(2, 3);

优点:

  1. 简单并容易使用

  2. 服务器端模块便于重用

缺点:

  1. 同步的模块加载方式不适合在浏览器环境中

  2. 不能非阻塞的并行加载多个模块

2. AMD 规范

AMD 是 (Asynchronous Module Definition) 的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

AMD 也采用 require() 语句加载模块,但是不同于 CommonJS,它要求两个参数:

require([module], callback);

第一个参数 module,是一个数组,里面的成员就是要加载的模块;第二个参数 callback,则是加载成功之后的回调函数。如果将前面的 CommonJS 改写成 AMD 形式,就是下面这样:

require(['math'], function (math) {
  math.add(2, 3);
});

优点:

  1. 适合在浏览器环境中异步加载模块

  2. 可以并行加载多个模块

缺点:

  1. 提高了开发成本

  2. 不符合通用的模块化思维方式

3. CMD 规范

CMD 是 (Common Module Definition) 公共模块定义 的缩写。CMD 可能是在 CommonJS 之后抽象出来的一套模块化语法定义和使用的标准。

CMD 规范中,一个模块就是一个文件。

示例:

define(function (require, exports, module) {
  var clock = require("clock");
  clock.start();
});

优点:可以很容易在 node 中运行

缺点:依赖 SPM 打包,模块的加载逻辑偏重

4. ES6 模块化

ES6 模块的设计思想是尽量的 静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJSAMD 模块,都只能在运行时确定这些东西。

ES6 中,我们使用 export 关键字来导出模块,使用 import 关键字来引入模块。

示例:

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

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

var firstName = 'Zhou';
var lastName = 'ShuYi';
var year = 1994;

export { firstName, lastName, year };

上面代码在 export 后面,使用大括号指定所要输出的一组变量。export 除了输出变量,还可以输出函数或类。

优点:容易进行静态分析

缺点:原生浏览器端还没有实现该标准

AMD 和 CMD 的区别

  1. 对于依赖的模块,AMD提前执行CMD延迟执行

  2. AMD 推崇 依赖前置CMD 推崇 依赖就近

  3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。

ES6 模块与 CommonJS 模块的差异

  1. CommonJS 模块输出的是一个 值的拷贝ES6 模块输出的是 值的引用

  2. CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

  3. CommonJS 模块的 require()同步加载 模块,ES6 模块的 import 命令是 异步加载,有一个独立的模块依赖的解析阶段。

最后

以上就是笔者对于 js 模块化的一些理解,如有不足欢迎大家在评论区指出......

转载自:https://juejin.cn/post/7203968787325960229
评论
请登录