关于模块引用
CommonJS
输出的是值的拷贝(浅拷贝),A模块引入B模块之后,B模块之后的变化不会影响A模块中的值。而ESM
是对一个值的引用(类似于读取的是值的地址),同样以A、B模块为例,A模块中永远使用的是B模块中最新的值。所以ESM
是动态引用,不会缓存值。
代码示例ESM
- 模块A:
export let a = 1; setTimeout(() => { a = 100; }, 500);
- 模块B使用A:
import { a } from 'A'; console.log(a); // 1 setTimeout(() => { console.log(a); // 100 }, 600);
修改引用值
CommonJS
可以修改以及重新赋值(改变指针指向)引用的值。ESM
的接口是只读的,不可以修改值(改变指针指向),只存只读,和const
类似。
加载方式
CommonJS
运行时加载,引用的时候先加载整个模块,生成一个对象,然后再从这个生成的对象上读取方法。ESM
编译时加载,不是对象,通过export
显示的指定输出的代码,import
时采用静态命令的形式,加载指定的输出值而不是整个模块。
动态加载
目前来讲ESM
还不支持,只能在文件头部import
,但是已经在提案中了。而CommonJS
则是支持的。
其他
commonJs
是会缓存的,会将引入结果缓存再require.cache
中,如果不需要缓存可以先删除再引入,如下代码:
export function requireUncached(path: string): any {
delete require.cache[require.resolve(path)];
return require(path);
}