es6 模块化与 node 的模块化
在平常的工作中,我们经常使用到模块化开发,那么具体这两者之间有什么区别呢?我们接下来一起探索一下。
# 概述
在 ES6 之前,主要的模块化方案是 CommonJS(服务器) 和 AMD 规范(浏览器),ES6 模块化的出现成为了浏览器和服务器通用的模块解决方案。
ES6 的设计思想是尽量的静态化,这样在编译的时候就能够确定模块间的依赖关系,并进行优化。而 CommonJS 和 AMD 都只能在运行时确定这些东西。
# 差异
模块的加载方式
// CommonJS 是将整个模块加载进来 const { a, b, c } = require('./m.js'); // 相当于 const _m = require('./m.js'); const a = _m.a; const b = _m.b; const c = _m.c; // ES6 是静态加载,在编译时已经完成了模块的加载,也就是说它只加载了这三个变量,其他的都没有加载 const { a, b, c } = require('./m.js');
1
2
3
4
5
6
7
8
9
10模块的加载结果
// CommonJS 输出的是值的拷贝,也就是说,一旦输入一个值,模块再变化也不会影响 // ES6 模块输出的是值的引用
1
2
# ES6 模块化
import
命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行,比如我们这样写就会报错。
if (flag) {
import X from './x.js';
}
1
2
3
2
3
报错的原因就是,import
执行是在编译时,这时候不会去执行 if
,所以把 import
放在里面毫无意义。这样做虽然看起来效率高,但是我们不能够做到按需加载,这就是一个很大的问题,但是 require
就能够做到。
if (path) {
const module = require('./m.js');
}
1
2
3
2
3
所以说如果 ES6 模块化要替代 CommonJS,就需要提供这么一种机制,因为这是一种非常常见的需求。
所以,在后来的标准中有一个提案,import()
函数,他就能做到动态加载,他返回的是一个 Promise
对象。