温故而知新, 复习下这个
1 语法差异:ESM使用
import来引入模块,使用export来导出模块。而CJS使用require来引入模块,使用module.exports或exports来导出模块
加载方式:CJS是运行时加载,即模块的加载是在代码执行阶段进行的,而ESM是编译时输出接口,即模块的加载是在代码解析阶段进行的
同步与异步:CJS是同步加载,因为它主要用于服务器端,需要加载的模块都在本地,所以采用同步加载不会出问题。而ESM是异步加载,因为它用于浏览器端,可能涉及到一些异步请求,所以需要采用异步加载
输出方式:ESM输出的是值的引用,而CJS输出的是值的拷贝。这意味着在ESM中,如果模块内部的值发生变化,那么导入这个值的地方也会随着改变。而在CJS中,如果模块内部的值发生变化,导入这个值的地方并不会改变
导入和导出方式:ESM支持命名导入和导出,可以导入和导出具体的变量、函数或对象。而CJS模块的导入和导出是整个模块对象的引用
具名导入导出
- 导出
// module.js
// 1.声明后立即导出值
export const something ;
// 2.导出先前声明的值
const something = true;
export { something };
// 3. 导出时重新命名
export { something as somethingElse };
- 导入
使用源模块中的原始名称进行导入。
// 1.使用源模块中的原始名称进行导入。
import { something } from './module.js';
// 2.从源模块导入特定项目,并在导入时分配自定义名称。
import { something as somethingElse } from './module.js';
名称空间导入
将源模块中的所有内容作为一个对象导入,该对象将所有源模块的 named exports 公开为属性和方法。
import * as module from './module.js';
从上面的示例中,something 将作为属性附加到导入的对象上,例如 module.something。如果存在默认导出,则可以通过 module.default 访问它。
默认导入导出
- 导出
// module.js
export default something;
- 导入
import something from './module.js';
无命名导入
加载模块代码,但不要使任何新对象可用。
import './module.js';
这对于 polyfill 很有用,或者当导入代码的主要目的是处理 prototypes 时。
动态导入
使用 动态导入 API 导入模块。
// 导入, 注意导出如果是默认的话, 则需要通过default访问
import('./modules.js').then(({ default: DefaultExport, NamedExport }) => {
// 用这个模块做点什么...
});
// module.js 默认导出
const hello = () => {
console.log('hello');
};
export default hello;
import('./module.js').then((res) => {
const hello = res.default;
hello();
});
// module.js 具名导出
export const hello = () => {
console.log('hello');
};
export default hello;
import('./module.js').then((res) => {
const hello = res.hello;
hello();
});
这对于代码分解应用程序和动态使用模块非常有用。