概述
Nodejs 模块化规范遵循两套规范:
- Common JS
- ES Module
Common JS
引入模块(require)支持四种格式
- 支持引入内置模块例如 http os fs child_process 等
const fs = require('fs')
,高版本也可以使用const fs = require('node:fs')
便于区分 - 支持引入第三方模块express md5 koa 等
const md5 = rquire('md5')
- 支持引入自己编写的模块
require('./test.js')
- 支持引入addon, napi 等 C++扩展模块 (编译后为.node文件)
- 支持引入 json 文件
const data = require('./data.json')
导出模块exports 和 module.exports
module.exports = {code: 200,hello: function() {console.log('Hello, world!');}
};
如果不想导出对象直接导出值: module.exports = 123
导入: const myTest = require('./MyTest.js')
,类似解构赋值导入也可以。
ESM
引入模块 import 必须写在头部
使用ESM模块的时候必须开启一个选项
打开package.json 设置 type:module
import fs from 'node:fs'
如果要引入json文件需要特殊处理,需要增加断言并且指定类型 json,而且要注意node低版本不支持。import data from './data.json' assert { type: "json" }; console.log(data);
加载模块的整体对象 import * as all from 'xxx.js'
动态导入模块,import静态加载不支持掺杂在逻辑中。如果想动态加载使用import函数模式
if(true){import('./test.js').then()
}
模块导出
导出一个默认对象 default只能有一个不可重复export default
// export default 只能有一个
export default {name: 'test',
}
导出变量
export const a = 1
cjs 和 esm 的区别
- cjs 基于运行时的同步加载,esm 基于编译时的异步加载(也就是为什么import需要写在顶端,就是因为需要编译时就要引入,而非在运行时才会加载)
- cjs 可以修改值,esm 不可以修改(只读)
- cjs 不支持 tree shaking ,esm 支持 tree shaking
- cjs 顶层的 this 指向这个模块本身, esm 顶层的 this 指向 undefined