关乎 package.json 的详细介绍
npm 是前端开发广泛使用的包管理工具,它让 JavaScript 开发者分享、复用代码更方便。而管理本地安装 npm 包的最好方式就是创建 package.json
文件。 package.json
文件具有:作为一个描述文件,描述了你的项目依赖哪些包;允许我们使用 “语义化版本规则”(后面介绍)指明你项目依赖包的版本;让你的构建更好地与其他开发者分享,便于重复使用。通过本篇对 package.json 的介绍,你或能对它有更深层了解。
生成 package.json
package.json,是一个 JSON 文件,你可以手动常见;但更推荐使用 npm 或 yarn,互动式创建 package.json 文件:
npm init
# OR
yarn init
重要字段
你的 package.json
中最重要的两个字段是 name
和 version
,如果没有它们,您的包将无法安装。 name
和version
字段一起用于创建唯一 ID。
name
{
"name": "my-awesome-package"
}
这是您的 包
的名称。 它在 URL 中使用,作为参数命令行,以及 node_modules
中的目录名。
yarn add [包名]
# or
npm install [包名]
规则
- 必须小于或等于 214 个字符(包括
@scope/
for 范围包)。 - 不能以点(
.
)或下划线(_
)开头。 - 名称中不得包含大写字母。
- 必须仅使用 URL 安全字符。
Tips
- 不要使用和
Node.js
核心模块相同的名字。 - 不要在名字里包含
js
或者node
单词。 - 短小精悍,让人看到名字就大概了解包的功能,记住它也会被用在
require()
调用里。 - 保证名字在 npm registry 里是唯一的。
version
包的当前版本,严格遵循 Semantic Versioning 2.0.0 语义化版本规范。
{
"version": "1.0.0"
}
信息类字段
description
Description 是帮助使用者了解包的功能的字符串,包管理器也会把这个字符串作为搜索关键词。
{
"description": "我的包的概要简短描述"
}
keywords
关键字是一个字符串数组,当在包管理器里搜索包时很有用。
{
"keywords": ["short", "relevant", "keywords", "for", "searching"]
}
license
所有包都应该指定许可证,以便让用户了解他们是在什么授权下使用此包,以及此包还有哪些附加限制。
{
"license": "MIT",
"license": "(MIT or GPL-3.0)",
"license": "SEE LICENSE IN LICENSE_FILENAME.txt",
"license": "UNLICENSED"
}
鼓励使用开源 (OSI-approved) 许可证,除非你有特别的原因不用它。 如果你开发的包是你工作的一部分,最好和公司讨论后再做决定。
license 字段必须是以下之一:
- 如果你使用标准的许可证,需要一个有效地 SPDX 许可证标识。
- 如果你用多种标准许可证,需要有效的 SPDX 许可证表达式2.0语法表达式。
- 如果你使用非标准的许可证,一个
SEE LICENSE IN <文件名>
字符串指向你的包里顶级目录的一个 < 文件名 >。 - 如果你不想在任何条款下授权其他人使用你的私有或未公开的包,一个
UNLICENSED
字符串。
链接类字段
各种指向项目文档、issues 上报,以及代码托管网站的链接字段。
homepage
是包的项目主页或者文档首页。
{
"homepage": "https://your-package.org"
}
bugs
问题反馈系统的 URL,或者是 email 地址之类的链接。用户通过该途径向你反馈问题。
{
"bugs": "https://github.com/user/repo/issues"
}
repository
是代码托管的位置。存储库是您的程序包实际代码所在的位置。
{
"repository": {
"type": "git",
"url": "https://github.com/user/repo.git"
},
"repository": "github:user/repo",
"repository": "gitlab:user/repo",
"repository": "bitbucket:user/repo",
"repository": "gist:a1b2c3d4e5f"
}
项目维护类字段
项目的维护者。
author
作者信息,一个人。
{
"author": { "name": "Your Name", "email": "you@example.com", "url": "http://your-website.com" },
"author": "Your Name <you@example.com> (http://your-website.com)"
}
contributors
贡献者信息,可能很多人。
{
"contributors": [
{ "name": "Your Friend", "email": "friend@example.com", "url": "http://friends-website.com" }
{ "name": "Other Friend", "email": "other@example.com", "url": "http://other-website.com" }
],
"contributors": [
"Your Friend <friend@example.com> (http://friends-website.com)",
"Other Friend <other@example.com> (http://other-website.com)"
]
}
文件类信息
指定包含在项目中的文件,以及项目的入口文件。
files
{
"files": [
"filename.js",
"directory/",
"glob/*.{js,json}"
]
}
项目包含的文件,可以是单独的文件、整个文件夹,或者通配符匹配到的文件。
main
项目的入口文件。
{
"main": "filename.js"
}
bin
随着项目一起被安装的可执行文件。
{
"bin": "bin.js",
"bin": {
"命令名称": "bin/命令路径/命令名称.js",
"other-command": "bin/other-command"
}
}
main
项目的入口文件。
{
"main": "./home/index.js",
"main": ["./home/index.js", "./home/entry.js"]
}
directories
{
"directories": {
"lib": "path/to/lib/",
"bin": "path/to/bin/",
"man": "path/to/man/",
"doc": "path/to/doc/",
"example": "path/to/example/"
}
}
当你的包安装时,你可以指定确切的位置来放二进制文件、man pages、文档、例子等。
types
这是一个只在 TypeScript 中生效的字段,如果您的包有一个 main.js
文件,您还需要在 package.json
文件中指明主声明文件。 将 types
属性设置为指向 bundled 的声明文件。 例如:
{
"types": "./lib/main.d.ts",
}
如果您的主声明文件名为 index.d.ts
并且位于包的根目录(index.js
旁边),则不需要标记 types
属性,建议这样做。
打包包字段
module
pkg.module
将指向具有 ES2015
模块语法的模块,但仅指向目标环境支持的语法功能。 完整的描述在这里。
browser
字段由模块作者提供,作为 JavaScript
包或组件工具的提示,用于打包模块以供客户端使用。 提案就在这里。
esnext
完整的提案在这里。 简短说明:
esnext
:ES 模块中使用阶段 4 功能(或更旧版本)的源代码,未编译。main
:指向一个 CommonJS 模块(或 UMD 模块),其JavaScript
与Node.js
当前可以处理的一样现代。- 大多数
module
用例应该可以通过esnext
处理。 browser
可以通过esnext
的扩展版本来处理
{
"main": "main.js",
"esnext": {
"main": "main-esnext.js",
"browser": "browser-specific-main-esnext.js"
}
}
另请参阅:Delivering untranspiled source code via npm
任务类字段
包里还可以包含一些可执行脚本或者其他配置信息。
scripts
{
"scripts": {
"build-project": "node build-project.js"
}
}
脚本是定义自动化开发相关任务的好方法,比如使用一些简单的构建过程或开发工具。 在 scripts
字段里定义的脚本,可以通过 yarn run <script>
命令来执行。 例如,上述 build-project
脚本可以通过 yarn run build-project
调用,并执行 node build-project.js
。
有一些特殊的脚本名称。 如果定义了 preinstall
脚本,它会在包安装前被调用。 出于兼容性考虑,install
、postinstall
和 prepublish
脚本会在包完成安装后被调用。
start
脚本的默认值为 node server.js
。
参考文档:npm docs。
scripts
对于以下脚本,npm
支持 package.json
文件的 scripts
默认命令字段:
prepublish
: 在打包并发布包之前运行,以及在没有任何参数的本地npm
安装之前运行。 (见下文)prepare
: 在打包和发布包之前运行,在没有任何参数的本地npm install
上运行,以及安装 Git 依赖项时(见下文)。 这是在preublish
之后运行,但是在preublishOnly
之前运行。prepublishOnly
: 在包准备和打包之前运行,仅限于 npm 发布。 (见下文。)prepack
: 在打包tarball
之前运行(在npm pack
,npm publish
,以及安装 Git 依赖项时)postpack
: 在生成tarball
之后运行并移动到其最终目标。publish
,postpublish
: 在包发布后运行。preinstall
: 在安装软件包之前运行。install
,postinstall
: 安装包后运行。preuninstall
,uninstall
: 在卸载软件包之前运行。postuninstall
: 在卸载软件包之后运行。preversion
: 在改变包版本之前运行。version
: 改变包版本后运行,但提交之前。postversion
: 改变包版本后运行,然后提交。pretest
,test
,posttest
: 由npm test
命令运行。prestop
,stop
,poststop
: 由npm stop
命令运行。prestart
,start
,poststart
: 由npm start
命令运行。prerestart
,restart
,postrestart
: 由npm restart
命令运行。 注意:如果没有提供重启脚本,npm restart
将运行stop
和start
脚本。preshrinkwrap
,shrinkwrap
,postshrinkwrap
: 由npm shrinkwrap
命令运行。
参考文档:npm docs.
config
{
"config": {
"port": "8888"
}
}
配置你的脚本的选项或参数。
依赖描述类字段
你的包很可能依赖其他包。你可以在你的 package.json
文件里指定那些依赖。
dependencies
这些是你的包的开发版和发布版都需要的依赖。
{
"dependencies": {
"package-1": "^3.1.4",
"package-2": "file:./path/to/dir"
}
}
你可以指定一个确切的版本、一个最小的版本 (比如
>=
) 或者一个版本范围 (比如>= ... <
)。
包也可以指向本地的一个目录文件夹。
devDependencies
这些是只在你的包开发期间需要,但是生产环境不会被安装的包。
{
"devDependencies": {
"package-2": "^0.4.2"
}
}
peerDependencies
平行依赖允许你说明你的包和其他包版本的兼容性。
{
"peerDependencies": {
"package-3": "^2.7.18"
}
}
In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a require of this host. This is usually referred to as a plugin. Notably, your module may be exposing a specific interface, expected and specified by the host documentation.
其大致意就是:通常是在插件开发的场景下,你的插件需要某些依赖的支持,但是你又没必要去安装,因为插件的宿主会去安装这些依赖,你就可以用 peerDependencies
去声明一下需要依赖的插件和版本,如果出问题,npm
就会有警告,来提醒使用者去解决版本冲突问题。
peerDependenciesMeta
添加可选设置以消除丢失的对等依赖性警告,#6671 。
{
"peerDependenciesMeta": {
"node-sass": {
"optional": true
},
"sass": {
"optional": true
},
"fibers": {
"optional": true
}
}
}
optionalDependencies
可选依赖可以用于你的包,但不是必需的。如果可选包没有找到,安装还可以继续。
{
"optionalDependencies": {
"package-5": "^1.6.1"
}
}
bundledDependencies
打包依赖是发布你的包时将会一起打包的一个包名数组。
{
"bundledDependencies": [
"package-4"
]
}
系统
你可以提供和你的包关联的系统级的信息,比如操作系统兼容性之类。
engines
指定使用你的包客户必须使用的版本,这将检查 process.versions
以及当前 yarn
版本。
{
"engines": {
"node": ">=4.4.7 <7.0.0",
"zlib": "^1.2.8",
"yarn": "^0.14.0"
}
}
此检查遵守正常的 semver 规则,但有一个例外。 它允许预发布版本匹配未明确指定预发布的 semver。 例如,1.4.0-rc.0
匹配 >=1.3.0
,但它与典型的 semver
检查不匹配。
os
此选项指定你的包的操作系统兼容性,它会检查 process.platform
。
{
"os": ["darwin", "linux"],
"os": ["!win32"]
}
cpu
使用这个选项指定你的包将只能在某些 CPU 体系架构上运行,这会检查 process.arch
。
{
"cpu": ["x64", "ia32"],
"cpu": ["!arm", "!mips"]
}
发布
private
{
"private": true
}
如果你不想你的包发布到包管理器(npm 或者 私有包管理),设置为 true
。
publishConfig
这些配置值将在你的包发布时使用。比如,你可以给包打标签。
{
"publishConfig": {
"registry": "https://registry.npm.taobao.org"
}
}
这是一组将在发布时使用的配置值。 如果要设置标记,注册表或访问权限,则特别方便,以便确保给定的包未标记为 latest
,发布到全局公共 registry
或默认情况下,作用域模块(@scoped)是私有的。
可以覆盖任何配置值,但只有 tag
,registry
和 access
可能对于发布而言很重要,npm-config。
Yarn
flat
如果你的包只允许给定依赖的一个版本,你想强制和命令行上 yarn install --flat
相同的行为,把这个值设为 true
。
{
"flat": true
}
请注意,如果你的 package.json
包含 "flat": true
并且其它包依赖你的包 (比如你在构建一个库,而不是应用), 其它那些包也需要在它们的 package.json
加上 "flat": true
,或者在命令行上用 yarn install --flat
安装。
resolutions
{
"resolutions": {
"transitive-package-1": "0.0.29",
"transitive-package-2": "file:./local-forks/transitive-package-2",
"dependencies-package-1/transitive-package-3": "^2.1.1"
}
}
允许您覆盖特定嵌套依赖项的版本。 有关完整规范,请参见选择性版本解析 RFC。
注意,yarn install --flat
命令将会自动在 package.json
文件里加入 resolutions
字段。