Node模块查找与入口配置
模块查找规则决定require/import如何定位文件,入口字段决定包被引用时加载哪个文件。
Node模块查找规则
核心查找流程
- 内置模块:fs、path等Node内置模块,优先级最高
- 文件模块:以
/、./、../开头的相对/绝对路径 - 包模块:非路径前缀,沿node_modules逐级向上查找
包模块查找路径
JavaScript
// require('my-lib') 的查找顺序
/project/node_modules/my-lib
/node_modules/my-lib
/home/node_modules/my-lib
/node_modules/my-lib
从当前目录的node_modules开始,逐级向上直到根目录。
文件扩展名补全
JavaScript
require('./utils')
// 查找顺序:
// 1. ./utils(精确匹配)
// 2. ./utils.js
// 3. ./utils.json
// 4. ./utils.node
// 5. ./utils/index.js
// 6. ./utils/index.json
目录查找
当路径指向目录时,查找该目录下的index文件:
text
utils/
index.js ← 命中
index.json
index.node
require时省略扩展名会按.js → .json → .node顺序补全,ESM模式不支持扩展名省略。
main/module/browser入口
main字段
指定包的CommonJS入口:
JSON
{
"name": "my-lib",
"main": "lib/index.js"
}
JavaScript
const myLib = require('my-lib');
// 加载 node_modules/my-lib/lib/index.js
未指定main时,默认查找包根目录的index.js。
module字段
指定ES Module入口(非官方标准,但广泛支持):
JSON
{
"main": "lib/index.cjs",
"module": "lib/index.mjs"
}
打包工具(Webpack、Rollup、Vite)优先使用module字段,以支持Tree Shaking。
browser字段
指定浏览器环境入口:
JSON
{
"main": "lib/index.js",
"browser": "lib/browser.js"
}
或指定字段级替换:
JSON
{
"browser": {
"./lib/fs.js": "./lib/fs-browser.js",
"net": false
}
}
优先级
| 环境 | 字段优先级 |
|---|---|
| Node.js(CJS) | main |
| 打包工具 | module > main |
| 浏览器(打包工具) | browser > module > main |
| Node.js(ESM) | exports > module > main |
module字段不是Node.js的官方规范,是打包工具的约定。Node.js ESM模式使用exports字段,不识别module字段。
要点总结
- Node查找包模块时沿node_modules逐级向上直到根目录
- 扩展名省略时按.js → .json → .node补全(仅CJS)
- main是CJS标准入口,未指定则默认index.js
- module是打包工具约定的ESM入口,支持Tree Shaking
- browser指定浏览器环境入口或字段级替换
- Node.js ESM模式优先使用exports字段