what 🔗
Node.js 是基于 V8 引擎的 JavaScript 运行时,让你可以用 JavaScript 写后端服务、命令行工具、爬虫、中间件等等。 特点:Node.js 上手快,社区生态非常强大(npm)。
核心模块 🔗
node.js 内置的模块,无依赖即可用。
| 模块 | 用途 |
|---|---|
fs |
文件读写 |
path |
路径处理 |
http/https |
创建 Web 服务 |
url |
处理 URL 路径 |
events |
事件系统(重要) |
child_process |
启动子进程 |
os |
获取系统信息 |
模块机制 + 异步模型 🔗
| 知识点 | 说明 |
|---|---|
| CommonJS 模块机制 | require 和 module.exports |
| 异步编程模型 | 回调、Promise、async/await |
| 事件循环(Event Loop) | Node 的核心运行机制 |
建议多写几个异步 I/O 实验,如定时器、读文件、异步请求等
node.js 的源码学习 🔗
从 Node 核心模块开始,了解事件驱动模型,理解架构组成,再深入 libuv、V8 和 C++ 层源码,边读边调试、边做实验。
- 熟练掌握 JavaScript(包含 ES6+)
- 理解 Node 核心模块(fs、http、events、stream、buffer、process...)
- 掌握异步编程模型(Promise、Event Loop、async/await)
- 熟悉一点 C/C++ 语法(建议)
- 会使用 Git 和 GDB / lldb 调试器(进阶时用)
┌──────────────┐
│ 用户 JS │ JavaScript 层
└─────▲────────┘
│
┌─────┴────────┐
│ Node Bindings│ C++/JS 交互层(如 fs, net)
└─────▲────────┘
│
┌─────┴────┐ ┌───────────────┐
│ libuv │◄──┤ 操作系统 API │ 异步 I/O、多线程抽象层
└─────▲────┘ └───────────────┘
│
┌─────┴────┐
│ V8 │ JS 引擎:执行 JS,管理内存
└──────────┘
搭建源码阅读环境 🔗
git clone https://github.com/nodejs/node.git
cd node
./configure
make -j4
./node # 编译成功
核心概念 🔗
运行时环境 v8
事件循环, 实现非阻塞 io,处理异步操作
六个阶段(按顺序执行)
- timer, 执行 setTimeout, setInterval
- pending,
- idle, prepare
- poll
- check, 执行 setImmediate
- close callback,
非阻塞 io 与 libuv。
单线程模型: js 主线程执行同步代码,异步操作有 libuv 交给线程池处理,完成后通过事件循环通知主线程。
模块化机制 CommonJS 🔗
module.exports 和 require 具体在做什么吗?
node.js 中的 require 是 CommonJS 模块规范的实现。
当调用 require 时,node 会按优先级顺序进行模块位置的搜索。模块的查找
- 内置模块(fs, path)
- 路径模块
- 以
./,../直接按路径查找文件 - 是模块名时,从当前目录的
node_modules开始,逐级查找 node_modules 时直到根目录。
- 以
- 文件后缀补全
- 会按.js, .json, .node(c++扩展模块)的顺序补全后去查找
- 目录模块处理
- 优先读取 package.json 的 main 字段指定的入口文件
模块编译。模块里的代码会包裹在一个函数中。
(function (exports, require, module, __filename, __dirname) {
const a = 1;
module.exports = a;
})(exports, require, module, filename, dirname);
模块缓存。
require.cache = {
'/path/to/module.js': {
id: '/path/to/module.js',
exports: {},
loaded: true,
},
{...}
}
module 是每个模块自带的对象。 module.exports 是模块的默认导出接口, exports 是 module.exports 的引用。 如果直接给 exports 赋值,如 exports={a: 1},则会切断与 module.exports 的关联。
require 和 package.json 配置的密切关系 🔗
package.json 中的 main 字段定义了当前包(模块)被 require 时的默认入口文件。
若 node_modules/foo/package.json 中配置:{ "main": "lib/foo.js" }。 则 require('foo') 等价于 require('./node_modules/foo/lib/foo.js')。
export字段是比 main 更强大的配置,用于限制模块的可访问路径。
{
"exports": {
".": "./index.js", // require('foo') 加载 index.js
"./util": "./lib/util.js", // require('foo/util') 加载 lib/util.js
"./feature": {
"node": "./feature/node.js", // Node.js 环境加载此文件
"default": "./feature/browser.js"
}
}
}
除了 main 字段和 exports 字段,package.json 还有哪些字段会影响 require 的行为?
type 字段:影响 .js 文件的解析方式,决定模块系统类型 common js or es module。
module 字段:工具链的 ESM 入口。被 Webpack、Rollup 等构建工具广泛使用,用于指定 ES 模块的入口文件。 browser 字段:浏览器环境的模块映射(工具链使用)。
常见的框架 🔗
express(Web)、axios(请求)、moment(时间)
配合使用的数据库 🔗
Mysql, Progres, mongodb。
《深入浅出 Node.js》(进阶必读)