这一小节是第二章的重头戏,也是Node生态的灵魂所在。朴灵作者在这里详细解释了包(package)的结构、package.json的字段含义,以及NPM作为CommonJS包管理器的作用。2013年书出版时,NPM刚兴起几年,但作者预见性地强调:NPM是Node成功的关键,推动了模块复用和生态爆炸式增长。即使现在(2025年),package.json的核心字段基本没变,这一节的内容依然超级实用。
详细讲解
包的背景
- CommonJS规范定义了模块(单个文件),但实际项目往往由多个模块组成,需要包来组织。
- 一个包就是一个目录,包含多个模块 + package.json描述文件。
- 包让模块可以复用、版本管理、依赖声明。
包结构
一个标准的包目录结构(书中有示例):
my-package/
├── package.json // 必备
├── index.js // main字段指向的入口
├── lib/ // 其他模块
│ ├── a.js
│ └── b.js
├── README.md
└── test/ // 测试
package.json 字段详解
这是这一节的核心!作者逐一解释了关键字段(书时NPM版本较早,但这些字段至今核心):
- name:包名,全小写、无空格、唯一(NPM仓库检查)。
- version:版本号,遵循SemVer(语义化版本):主版本.次版本.补丁版本(如1.2.3)。 breaking change 升主版本、新功能升次版本、bugfix升补丁。
- description:描述,便于搜索。
- main:入口文件,require('my-package') 时加载这个文件(默认index.js)。
- bin:可执行命令,安装后全局可用(如"bin": {"my-cli": "cli.js"})。
- dependencies:生产依赖,对象形式 {"express": "^4.18.0"}。
- devDependencies:开发依赖(如测试工具),npm install 时 --production 不装。
- scripts:脚本命令,如"test": "mocha"。
- repository、author、license 等元信息。
- engines:指定Node版本范围。
示例package.json(书中有类似):
{
"name": "my-awesome-package",
"version": "1.0.0",
"description": "一个牛逼的包",
"main": "index.js",
"scripts": {
"test": "node test.js"
},
"dependencies": {
"lodash": "^4.17.0"
},
"author": "朴灵",
"license": "MIT"
}
NPM的作用
- NPM(Node Package Manager)是CommonJS的官方实现,提供仓库(registry)、命令行工具。
- 核心命令:npm install、npm publish、npm search 等。
- 依赖管理:扁平化(早期有嵌套,现在hoisting避免重复)。
- 包加载:require时在node_modules逐级向上找。
注意点
- 包名冲突:NPM仓库唯一。
- 版本冲突:SemVer + ^ ~ 符号控制范围。
- 私有包:不publish,用scope(如@myorg/pkg)。