Node.js 模块类型
在 Node.js 中,模块主要可以分为以下几种类型:
-
核心模块:包含在 Node.js 源码中,被编译进 Node.js 可执行二进制文件 JavaScript 模块,也叫 native 模块,比如常用的 http, fs 等等
-
C/C++ 模块,也叫 built-in 模块,一般我们不直接调用,而是在 native module 中调用,然后我们再 require
-
native 模块,比如我们在 Node.js 中常用的 buffer,fs,os 等 native 模块,其底层都有调用 built-in 模块。
-
-
第三方模块:非 Node.js 源码自带的模块都可以统称第三方模块,比如 express,webpack 等等。
-
JavaScript 模块,这是最常见的,我们开发的时候一般都写的是 JavaScript 模块
-
JSON 模块,这个很简单,就是一个 JSON 文件
-
C/C++ 扩展模块,使用 C/C++ 编写,编译之后后缀名为 .node
-
Node.js 源码结构一览
这里使用 Node.js 6.x 版本源码为例子来做分析。去 github 上下载相应版本的 Node.js 源码,可以看到代码大体结构如下:
├── AUTHORS
├── BSDmakefile
├── BUILDING.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── COLLABORATOR_GUIDE.md
├── CONTRIBUTING.md
├── GOVERNANCE.md
├── LICENSE
├── Makefile
├── README.md
├── android-configure
├── benchmark
├── common.gypi
├── configure
├── deps
├── doc
├── lib
├── node.gyp
├── node.gypi
├── src
├── test
├── tools
└── vcbuild.bat
其中:
./lib文件夹主要包含了各种 JavaScript 文件,我们常用的 JavaScript native 模块都在这里。
./src文件夹主要包含了 Node.js 的 C/C++ 源码文件,其中很多 built-in 模块都在这里。
./deps文件夹包含了 Node.js 依赖的各种库,典型的如 v8,libuv,zlib 等。
模块引入原理
路径分析
路径分析的优先级如下:
缓存加载 核心模块加载 文件模块加载
如果引入的是核心模块,就直接填写模块名字符串就可以了
var http = require(‘http’);
如果引入的是文件模块,就会根据填入的路径来定位文件
var tool = require(’./tool’);
我们下载的第三方模块会存在于node_modules的文件夹 在分析它的时候 就会查找当前目录下的node_modules中有没有该文件 如果没找到,就会查找父级目录下有没有node_modules并查找 以此类推 引用第三方模块同样不必输入路径
var react = require(‘react’);
文件定位
require()分析标识符的时候,可能会出现省略文件扩展名的情况 此时,Node会按照 .js / .json / .node 的顺序依次尝试 很显然这有一点儿性能问题,尝试也需要时间 所以我们最好给 .json 和 .node 形式的文件添加扩展名
如果我们定位到的是一个文件夹 Node会把它当做一个包来处理 根据包内部的package.json文件的main属性继续定位入口文件
关于包的概念,这里不讲 可以暂时把它理解为拥有package.json配置文件的一个文件夹
模块编译
文件格式不同,载入方法也不同
.js文件:通过fs核心模块同步读取后编译执行 .node文件:C/C++扩展文件,通过dlopen()加载最后编译生成的文件 .json文件:通过fs核心模块同步读取后利用JSON.parse()解析 其他:均当做.js文件处理
参考http://www.knowsky.com/978797.html
https://efe.baidu.com/blog/nodejs-module-analyze/