commonJS、AMD、es6模块化 区别(表格比较):node
区别项 | es模块化 | commonJS | AMD |
---|---|---|---|
可用于服务端仍是浏览器 | 服务端和浏览器 | 服务端 | 浏览器 |
模块依赖关系什么时候肯定(即:什么时候加载模块) | 编译时 | 运行时 | 运行时 |
设计思想 | 尽可能的静态化 | ||
模块是否是对象 | 不是 | 是 | |
是否总体加载模块(即加载的全部方法) | 否 | 是 | |
是不是动态更新(即经过接口,能够取到模块内部实时的值) | 是。es module输出的是值的引用 | 不是。commonJS模块输出的是值的拷贝,不存在动态更新 | |
模块变量是不是只读的 | 是。缘由:ES6 输入的模块变量,只是一个“符号链接”,因此这个变量是只读的,对它进行从新赋值会报错。 |
commonJS模块就是对象,总体加载模块(即加载的全部方法)es6
ES6 模块不是对象,而是经过export命令显式指定输出的代码,再经过import命令输入。json
// 报错 export 1; // 报错 var m = 1; export m;
上面两种写法都会报错,由于没有提供对外的接口。第一种写法直接输出1,第二种写法经过变量m,仍是直接输出1。1只是一个值,不是接口。正确的写法是下面这样。promise
// 写法一 export var m = 1; // 写法二 var m = 1; export {m}; // 写法三 var n = 1; export {n as m};
一样的,function和class的输出,也必须遵照这样的写法。浏览器
// 报错 function f() {} export f; // 正确 export function f() {}; // 正确 function f() {} export {f};
export var foo = 'bar'; setTimeout(() => foo = 'baz', 500);
上面代码输出变量foo,值为bar,500毫秒以后变成baz。
这一点与 CommonJS 规范彻底不一样。CommonJS 模块输出的是值的缓存,不存在动态更新。缓存
export命令和import命令能够出如今模块的任何位置,只要处于模块顶层就能够。
若是处于块级做用域内,就会报错,这是由于处于条件代码块之中,就无法作静态优化了,违背了ES6模块的设计初衷。app
foo();= import { foo } from 'my_module';
上面的代码不会报错,由于import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行以前。模块化
require('core-js/modules/es6.symbol'); require('core-js/modules/es6.promise'); import React from 'React';
import 'lodash';
上面代码仅仅执行lodash模块,可是不输入任何值。优化
import 'baz'; import 'abc/123';
若是模块名包含路径,那么import命令会按照路径去寻找这个名字的脚本文件。ui
import 'file:///etc/config/app.json'; import './foo'; import './foo?search'; import '../bar'; import '/baz';