web faq
# node.js 是多线程的吗?
在 Node.js 中, JavaScript 代码是运行在单线程的事件循环(event loop)中的, 因此在这个意义上来说, Node.js 是单线程的。这意味着 JavaScript 代码在任何给定的时刻只能在一个线程上执行, 并且事件循环保证了代码的执行顺序和不会出现并发问题
然而, Node.js 在执行异步操作时(例如文件 I/O、网络请求、定时器等), 会利用底层操作系统提供的多线程机制来实现并发执行。这意味着虽然 JavaScript 代码是单线程执行的, 但 Node.js 底层的操作系统线程池会处理并发执行异步操作, 以提高性能和吞吐量
因此, 尽管 Node.js 的 JavaScript 代码是单线程的, 但它可以利用多线程来执行异步操作, 从而实现了非阻塞的 I/O 操作和高效的并发处理
# EMS 与 CommonJS 的区别
ECMAScript Module(ESM) 与 CommonJS 是两套不同的模块化规范, 主要差异体现在语法、加载时机以及运行环境:
- 语法差异: ESM 使用
import/export关键字, 并且是静态分析的; CommonJS 则通过require()和module.exports进行导入导出, 支持在运行时动态决定依赖 - 加载方式: ESM 模块在构建阶段就能确定依赖关系, 浏览器与打包器可以进行 Tree Shaking; CommonJS 模块在代码运行时才执行
require, 因此依赖关系是动态的 - 执行时机: ESM 的
import会在文件顶部提升并先于模块主体执行, 而 CommonJS 的require按照代码顺序执行 - 运行环境: 浏览器原生只支持 ESM, Node.js 从 v12 起逐步支持 ESM(需以
.mjs扩展名或package.json中声明type: "module"); CommonJS 在 Node.js 中长期作为默认模块系统 - 导出内容: ESM 导出的是只读的实时绑定(live binding), 更新值会同步给导入方; CommonJS 导出的是对象的拷贝引用, 修改需要手动同步
- 兼容策略: 在 ESM 中导入 CommonJS 需要使用
createRequire或访问模块的default属性; 在 CommonJS 中导入 ESM 则需使用动态import()或把目标模块打包为 CommonJS
在老项目迁移到 ESM 时, 常见的步骤包括: 将 require 改写为 import, 将 module.exports 改写为 export default/export, 同时调整打包配置与运行环境(例如 Node.js 中在 package.json 声明 type: "module" 设置)。如果项目依赖仍使用 CommonJS, 需要保留部分 require 或借助打包工具进行兼容处理。
上次更新: 2025/11/11, 20:57:04