2.3 核心模块

35 阅读2分钟

这一小节紧接模块实现,重点解释Node.js的核心模块(built-in modules)是什么、怎么分类、为什么特殊,以及它们在require时的优先级和实现方式。核心模块是Node区别于浏览器JS的关键之一,提供底层能力(如文件系统、网络、进程等),让Node能做服务器端开发。

原书这一小节不长,但信息密度高,朴灵作者强调:核心模块在require时优先级最高,并且部分是预编译成二进制的,加载速度极快。

详细讲解

核心模块的引入背景

在CommonJS规范下,模块分为用户模块(我们写的文件)和核心模块。Node为了提供标准库(如Java、Python有),实现了大量核心模块。require('fs')、require('http') 等就是核心模块。

核心模块的分类

朴灵作者将核心模块分为两类(书中有图示):

  1. 用JavaScript实现的(纯JS核心模块):

    • 源码在Node项目的 lib目录 下(如 lib/fs.js、lib/http.js、lib/util.js)。
    • 这些模块加载时像普通JS模块一样编译,但因为是内置的,优先从内存加载。
    • 例子:util、events、path、stream 等。
  2. 用C/C++实现的(绑定模块,或内置模块):

    • 源码在Node项目的 src目录 下(如 src/fs.cc、src/node_http.cc)。
    • 这些涉及底层系统调用(如文件I/O、网络),用C++绑定V8和libuv。
    • 编译Node二进制时,这些C++代码被编译进node.exe,启动时直接可用。
    • 例子:fs(文件系统)、net(TCP)、http(解析器部分)、buffer、crypto 等。

此外,还有一种混合型:入口是JS,但内部调用C++绑定(如http模块的lib/http.js 调用 src/node_http.cc)。

核心模块的加载过程

  • 在路径分析阶段,如果标识符是核心模块名(如'fs'),直接从内置列表加载。
  • 预编译:C++部分在Node编译时已转为二进制,JS部分在Node启动时转为V8字节码(或直接执行)。
  • 优势:加载极快、无需磁盘I/O、跨平台一致。

书里提到一个关键点:核心模块的JS部分也经过“模块编译”包裹,但它们在Node源码中用 NativeModule 机制管理(源码中的 node.cc 和 module.cc)。

为什么区分核心模块?

  • 性能:底层操作用C++更快。
  • 稳定性:核心API统一。
  • 生态:用户模块和npm包构建在其上。

这一小节结尾过渡到下一节:有些性能瓶颈,核心模块不够时,可以自己写C++扩展模块。