思路#
1.模块加载不同:
2. 出处不同:
年份 | 出处 | |
require/exports | 2009 | CommonJS |
import/export | 2015 | ECMAScript2015(ES6) |
3. 实质不同:见代码👇
// CommonJS模块
let { stat, exists, readFile } = require('fs');
// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
#实质:“运行时加载”
整体加载fs模块(即:加载fs的所有方法),生成一个对象(_fs),然后在从这个对象上面读取3个方法。
因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。
// ES6模块
import { stat, exists, readFile } from 'fs';
#实质:"编译时加载"或者"静态加载"
从fs模块加载3个方法,其它方法不加载。
即 ES6可以在编译时就完成模块加载,效率要比CommonJS模块的加载方式高。
4. 自身结构不同
- CommoneJS模块是对象
- ES6模块不是对象,所以无法引用自身
#小结:
1⃣️ES6模块:编译时加载
- 使得静态分析成为可能;
- 可进一步扩宽JS语法,比如引入宏(macro)、类型检查(type system) 等只能靠静态分析实现的功能;
2⃣️require: 是个赋值过程
require的结果是对象,数字,字符串,函数等,再把它这些结果赋值给某个变量;
3⃣️import :是个解构过程
但目前所有的引擎都还没实现import, 比较常用的方式是使用babel支持ES6,如图:
require/exports | import/export | |
Node.js | 所有版本 | Node 9.0+(启动需加上 flag --experimental-modules)Node 13.2+(直接启动) |
Chrome | 不支持 | 61+ |
Firefox | 不支持 | 60+ |
Safari | 不支持 | 10.1+ |
Edge | 不支持 | 16+ |