npm package.json 文件的详细说明。
Version:9.8.1
本文档包含了关于 package.json 文件中所需内容的所有信息。它必须是有效的 JSON 格式,而不仅仅是 JavaScript 对象字面量。
如果您计划发布您的包,那么 package.json 文件中最重要的字段是 name
和 version
,它们是必需的。name
和 version
共同形成一个被认为是完全唯一的标识符。对包的更改应该伴随着版本的更改。如果您不打算发布您的包,name
和 version
字段是可选的。
name
字段表示您项目的名称。
一些规则:
一些建议:
engines
字段来指定引擎(请参阅下文)。require()
函数的参数传递,因此它应该是简短的,但也要有一定的描述性。@myorg/mypackage
。有关更多详细信息,请参阅作用域。如果您计划发布您的包,那么 package.json 文件中最重要的字段是 name
和 version
,它们是必需的。name
和 version
共同形成一个被认为是完全唯一的标识符。对包的更改应该伴随着版本的更改。如果您不打算发布您的包,name
和 version
字段是可选的。
版本号必须符合 node-semver 的解析规则,npm 默认包含了 node-semver (您可以使用npm install semver
自行使用它)。
对于您的包的描述,这将帮助开发者发现您的软件包,在 npm search
时,它将一同显示。
项目的首页地址。
例如:
"homepage": "https://github.com/owner/project#readme"
指向项目的 issue 报告网址和或电子邮件地址。当使用您的包的开发者发现问题时,他可以及时地提交 issue。
例如:
{
"url" : "https://github.com/owner/project/issues",
"email" : "[email protected]"
}
您可以指定一个或两个值。如果您只想提供一个网址,您可以将 bugs
的值指定为简单的字符串,而不是对象。
如果提供了网址,它将用于 npm bugs
命令。
为了让用户知道如何使用您的包以及您对其使用的任何限制,请为您的软件包指定一个许可证。
如果您使用的是常见的许可证,如 BSD-2-Clause 或 MIT,请添加一个当前的SPDX许可证标识符,示例如下:
{
"license" : "BSD-3-Clause"
}
您可以查看完整的 SPDX 许可证标识符列表。最好选择一个经过 OSI 批准的标识符。
如果您的软件包使用多个常见的许可证,请使用 SPDX 许可证表达式语法版本 2.0 的字符串,示例如下:
{
"license" : "(ISC OR GPL-3.0)"
}
如果您使用的是尚未分配 SPDX 标识符的许可证,或者您使用的是自定义许可证,请使用以下字符串值:
{
"license" : "SEE LICENSE IN "
}
然后,在软件包的顶级目录中包含一个名为
的文件。
一些旧的软件包使用许可证对象或包含许可证对象数组的 “licenses” 属性:
// Not valid metadata
{
"license" : {
"type" : "ISC",
"url" : "https://opensource.org/licenses/ISC"
}
}
// Not valid metadata
{
"licenses" : [
{
"type": "MIT",
"url": "https://www.opensource.org/licenses/mit-license.php"
},
{
"type": "Apache-2.0",
"url": "https://opensource.org/licenses/apache2.0.php"
}
]
}
这种方式现在已被弃用。请改用SPDX表达式,示例如下:
{
"license": "ISC"
}
{
"license": "(MIT OR Apache-2.0)"
}
最后,如果您不希望以任何条件授予他人使用私有或未发布的软件包的权利,请使用以下方式:
{
"license": "UNLICENSED"
}
考虑将 private
设置为 true,以防止意外发布。
作者和贡献者信息。
在 package.json 文件中,author
用于表示作者,contributors
用于表示贡献者,是一个包含多个人的数组。可用一个对象来记录人的信息,包含一个 name
字段,还可以添加 url
和 name
字段(这两个字段为可选),示例如下:
{
"name" : "Barney Rubble",
"email" : "[email protected]",
"url" : "http://barnyrubble.tumblr.com/"
}
或者您可以将所有信息缩写为一个字符串,npm 将为您解析它:
{
"author": "Barney Rubble (http://barnyrubble.tumblr.com/)"
}
无论哪种方式,email
和 url
都是可选的。
此外,npm 还会在顶级的 maintainers
字段中设置您的 npm 用户信息。
资助开发信息。
您可以指定一个包含提供关于如何资助您的软件包开发的最新信息的 URL 的对象,或者一个 URL 字符串,或者这些的数组形式组合:
{
"funding": {
"type" : "individual",
"url" : "http://example.com/donate"
},
"funding": {
"type" : "patreon",
"url" : "https://www.patreon.com/my-account"
},
"funding": "http://example.com/donate",
"funding": [
{
"type" : "individual",
"url" : "http://example.com/donate"
},
"http://example.com/donateAlso",
{
"type" : "patreon",
"url" : "https://www.patreon.com/my-account"
}
]
}
用户可以使用 npm fund
命令列出其项目的所有直接和间接依赖项的资助 URL。当提供项目名称时,还可以使用快捷方式访问每个资助 URL,例如:npm fund
(当存在多个URL时,将访问第一个URL)。
files
字段是包含一个文件匹配模式的数组,用于描述在将您的软件包安装为依赖项时应包含的条目。文件匹配模式遵循类似于 .gitignore 的语法,被 files
字段匹配的文件、目录或通配符模式(如*
、**/*
等)会在 npm 打包时包含在 tarball 中。如果省略该字段,将默认为["*"]
,表示将包含所有文件。
无论文件在 files
数组中是否匹配,某些特殊文件和目录始终会被包含或排除(见下文)。
您还可以在软件包的根目录或子目录中提供一个 .npmignore 文件,以防止文件被包含。在软件包的根目录中,它不会覆盖 files
字段,但在子目录中会。.npmignore 文件的工作方式与 .gitignore 类似。如果存在 .gitignore 文件但没有发现 .npmignore 文件,则会将 .gitignore 视为 .npmignore 文件。
某些文件始终被包含,无论设置如何:
README 和 LICENSE 可以具有任何大小写和扩展名。
相反地,某些文件始终被忽略:
main
字段是一个模块 ID,它是您程序的主要入口点。也就是说,如果您的软件包名为 foo,用户安装了它,然后使用 require("foo")
进行引入,那么您的主要模块导出的对象将被返回。
该字段应该是相对于您软件包文件夹根目录的模块路径。
对于大多数模块来说,最合理的做法是只有一个主要脚本文件。
如果未设置 main
字段,会默认将软件包根目录中的 index.js
文件作为包主入口。
module
字段用于指定模块的入口文件。这个字段通常在库或包中使用,以便构建工具(如 Webpack 和 Rollup)可以找到并使用模块的 ES6 模块版本。ES6 模块允许更好的静态分析(例如 tree-shaking),从而使构建工具可以优化生成的代码。
当构建工具处理一个包时,会首先查看 module
字段。如果不存在这个字段,那么它们会回退到其他字段,如 main
。
例如,在 package.json 中,您可以将 module
字段设置为指向 ES6 模块版本的入口文件:
{
"name": "my-library",
"version": "1.0.0",
"main": "dist/index.js",
"module": "src/index.js"
}
在这个例子中,main
字段指向的是通常的 CommonJS 版本的入口文件,而 module
字段指向的是 ES6 模块版本的入口文件。这样,支持 ES6 模块的构建工具可以使用 module
字段,而其他工具可以继续使用 main
字段。
如果您的模块用于客户端浏览器环境,应该使用 browser
字段而不是 main
字段。这有助于提示用户,该模块可能依赖于在 Node.js 环境下不可用的一些原始对象(例如 window
对象)。
您可以在 package.json 文件中添加一个 browser
字段来指定客户端浏览器环境下的模块入口点。示例如下:
{
"browser": "dist/browser.js"
}
在上述示例中,dist/browser.js
是相对于软件包根目录的模块路径,它将作为在浏览器环境中使用该模块时的入口点。
请注意,browser
字段只在浏览器环境中生效,在 Node.js 环境中不生效。
在 npm 中,大量的包都希望将一个或多个可执行文件安装到 PATH
中。npm 使这变得相当容易(事实上,它使用这个功能来安装 “npm” 可执行文件)。
要使用这个功能,在 package.json 文件中提供一个 bin
字段,它是一个命令名称到本地文件名的映射。当这个包被全局安装时,该文件将被链接到全局的 bins 目录中,或者将创建一个 cmd(Windows 命令文件),该文件会执行 bin 字段中指定的文件,以便通过名称或 name.cmd(在 Windows PowerShell 中)来运行。当这个包作为另一个包的依赖项安装时,该文件将被链接到该包中,可以通过 npm exec
直接访问,或者通过 npm run-script
在其他脚本中通过名称调用。
例如,myapp 可以这样配置:
{
"bin": {
"myapp": "./cli.js"
}
}
因此,当你安装 myapp 时,在类 Unix 的操作系统上,它会创建一个从 cli.js 脚本到 /usr/local/bin/myapp 的符号链接;在 Windows 上,它会创建一个 cmd 文件,通常位于 C:\Users{Username}\AppData\Roaming\npm\myapp.cmd,该文件运行 cli.js 脚本。
如果你只有一个可执行文件,且其名称是包名时,那么你可以直接将其提供为字符串。例如:
{
"name": "my-program",
"version": "1.2.5",
"bin": "./path/to/program"
}
与以下配置等效:
{
"name": "my-program",
"version": "1.2.5",
"bin": {
"my-program": "./path/to/program"
}
}
请确保在 bin
字段中引用的文件以 #!/usr/bin/env node
开头,否则脚本将在没有 node 可执行文件的情况下启动!
注意,你也可以使用 directories.bin
来设置可执行文件的目录。
有关可执行文件的更多信息,请参阅 folders。
man 字段是用来指定包的文档文件的位置和名称的,为单个文件或文件数组。这个字段通常被用于 Node.js 模块的文档生成工具,比如 man 命令。
man 命令是一个用于查看 Unix/Linux 系统上的帮助文档的命令,可以通过 man 命令查看 Node.js 模块的文档
如果只提供了单个文件,则安装方式是将其作为 man
的结果,而不考虑其实际文件名。例如:
{
"name": "foo",
"version": "1.2.3",
"description": "A packaged foo fooer for fooing foos",
"main": "foo.js",
"man": "./man/doc.1"
}
这将链接 ./man/doc.1
文件,使其成为 man foo
的目标。
如果文件名不以包名开头,则会添加包名前缀。因此,以下示例:
{
"name": "foo",
"version": "1.2.3",
"description": "A packaged foo fooer for fooing foos",
"main": "foo.js",
"man": [
"./man/foo.1",
"./man/bar.1"
]
}
将创建用于执行 man foo
和 man foo-bar
的文件。
man 文件必须以数字结尾,如果被压缩,则可以选择添加 .gz
后缀。该数字指定将文件安装到哪个 man 节。
{
"name": "foo",
"version": "1.2.3",
"description": "A packaged foo fooer for fooing foos",
"main": "foo.js",
"man": [
"./man/foo.1",
"./man/foo.2"
]
}
将创建 man foo
和 man 2 foo
的条目。
在 CommonJS Packages 规范中,可以使用 directories
对象来表明包的结构。如果查看 npm 的 package.json 文件,你会看到它有 doc、lib
和 man
的目录。
将来,这些信息可能会以其他耿局创造性的方式被使用。
如果在 directories.bin
中指定了一个 bin
目录,该目录中的所有文件都将被添加。
由于 bin
指令的工作方式,同时指定 bin
路径和设置 directories.bin
将会发生一个错误。如果你想指定单个文件,请使用 bin
字段;如果你想使用现有bin
目录中的所有文件,请使用 directories.bin
。
一个包含 man
页的文件夹。可以通过遍历该文件夹生成一个 man
数组的快捷方式。
在 package.json 中,可以使用 repository
字段来指定代码存放的位置,这对于希望来参与贡献的人来说非常有帮助。如果代码存储库在 GitHub 上,npm docs
命令将能够直接找到。
使用以下格式:
{
"repository": {
"type": "git",
"url": "https://github.com/npm/cli.git"
}
}
URL 应该是一个公开可访问的(可能是只读的)URL,可以直接提供给版本控制系统程序,不需要进行任何修改。
对于 GitHub、GitHub Gist、Bitbucket 或 GitLab 存储库,你可以使用与npm install
相同的简化语法:
{
"repository": "npm/npm",
"repository": "github:user/repo",
"repository": "gist:11081aaa281",
"repository": "bitbucket:user/repo",
"repository": "gitlab:user/repo"
}
如果你的包的 package.json 文件不在根目录中(例如,如果它是一个 monorepo 的一部分),你可以指定它所在的目录:
{
"repository": {
"type": "git",
"url": "https://github.com/facebook/react.git",
"directory": "packages/react-dom"
}
}
“scripts” 属性是一个包含脚本命令的字典,这些脚本命令在包的生命周期的不同阶段运行。一般而言,键是生命周期事件,值是在该事件发生时要运行的命令。
有关编写包脚本的更多信息,请查看 scripts。
config
字段通常用于存储项目中的一些通用配置参数,这些参数可以在 scripts
字段中的命令脚本里通过环境变量的形式访问。这样可以让项目更加灵活,方便在不同环境下使用不同的配置。
下面是一个简单的 package.json
文件示例,包含了 config
字段:
{
"config": {
"port": 3000
},
"scripts": {
"start": "node server.js"
},
}
在这个示例中,config
字段包含一个名为 port
的参数,值为 3000。可以在项目的脚本中通过 process.env.npm_package_config_port
访问这个参数值:
// server.js
const express = require('express');
const app = express();
const port = process.env.npm_package_config_port || 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
这样,在运行 npm start
命令时,服务器会监听 config
字段中指定的端口号。如果需要更改端口号,只需修改 package.json
文件中的 config
字段即可,无需修改代码。
dependencies
字段是 package.json 文件中的一个关键字段,它用于列出项目所需的依赖包及其版本。当你使用 Node.js 和 npm(Node Package Manager)进行项目开发时,通常会使用许多来自第三方的包(libraries 或 modules)以便更快地实现项目功能。这些包通常来自 npm 仓库,可以通过 npm install
命令安装。
dependencies
字段是一个对象,其键(key)是依赖包的名称,值(value)是所需的版本号。版本范围是一个字符串,其中包含一个或多个以空格分隔的描述符。依赖项也可以使用 tarball 或 git URL 来标识。
请不要将测试工具、转译工具或其他开发时工具放在 “dependencies” 对象中。请参阅下面的 “devDependencies”。
有关指定版本范围的更多详细信息,请参阅 semver。
>version
:必须大于指定版本>=version
:等于或大于指定版本:必须小于指定版本
<=version
:小于或等于指定版本~version
:“大约等于指定版本”,参见 semver^version
:“与指定版本兼容”,参见 semver1.2.x
:1.2.0、1.2.1等,但不包括 1.3.0http://...
:参见下面的 “URL 作为依赖项”*
:匹配任何版本""
(空字符串):与 *
相同version1 - version2
:与 >=version1 <=version2
相同range1 || range2
:如果满足 range1
或 range2
,则通过git...
:参见下面的 “Git URL 作为依赖项”user/repo
:参见下面的"GitHub URL"tag
:特定版本的标签,以 tag
形式发布,参见 npm dist-tag
path/path/path
:参见下面的"本地路径"{
"dependencies": {
"foo": "1.0.0 - 2.9999.9999",
"bar": ">=1.0.2 <2.1.2",
"baz": ">1.0.2 <=2.3.4",
"boo": "2.0.1",
"qux": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
"asd": "http://asdf.com/asdf.tar.gz",
"til": "~1.2",
"elf": "~1.2.3",
"two": "2.x",
"thr": "3.3.x",
"lat": "latest",
"dyl": "file:../dyl"
}
}
您可以在版本范围的位置指定一个 tarball URL。
该 tarball 将在安装时下载并安装到本地。
Git URL 允许你直接从 Git 仓库(如 GitHub、GitLab 等)安装依赖包,而不仅限于从 npm 仓库获取。
Git URL 的格式如下:
://[[:]@][:][:][/][# | #semver:]
其中,
可以是 git、git+ssh、git+http、git+https 或 git+file。
如果提供了 #
,将会克隆指定的提交。如果 commit-ish 的格式为 #semver:
,
可以是任何有效的 semver 范围或确切版本,npm 会在远程仓库中查找与该范围匹配的标签或引用,就像它在注册表依赖项中所做的那样。如果既没有指定 #
也没有指定 #semver:
,则使用默认分支。
示例:
git+ssh://[email protected]:npm/cli.git#v1.0.27
git+ssh://[email protected]:npm/cli#semver:^5.0
git+https://[email protected]/npm/cli.git
git://github.com/npm/cli.git#v1.0.27
当从 Git 仓库安装依赖包时,package.json
中某些字段的存在会导致 npm 认为需要执行构建。为此,你的仓库将被克隆到临时目录,安装所有依赖项,运行相关脚本,然后将生成的目录打包并安装。
如果你的 Git 依赖项使用工作区(workspaces),或者存在以下任何脚本,将触发此流程:
如果你的 Git 仓库包含预构建的工件,你可能需要确保上述脚本都未定义,否则你的依赖项将在每次安装时重新构建。
从版本 1.1.65 开始,您可以将 GitHub URL 简化为 “user/foo-project” 的形式。与 git URL 一样,可以包含提交标识后缀。例如:
{
"name": "foo",
"version": "0.0.0",
"dependencies": {
"express": "expressjs/express",
"mocha": "mochajs/mocha#4727d357ea",
"module": "user/repo#feature\/branch"
}
}
在上述示例中,“express"依赖项引用了GitHub仓库"expressjs/express”,“mocha"依赖项引用了GitHub仓库"mochajs/mocha"的特定提交"4727d357ea”,“module"依赖项引用了GitHub仓库"user/repo"的特定分支"feature/branch”。
从版本 2.0.0 开始,您可以提供指向包含包的本地目录的路径。本地路径可以通过以下形式使用 npm install -S
或 npm install --save
命令保存:
../foo/bar
~/foo/bar
./foo/bar
/foo/bar
在这种情况下,路径将被规范化为相对路径,并添加到您的 package.json
文件中。例如:
{
"name": "baz",
"dependencies": {
"bar": "file:../foo/bar"
}
}
这个特性对于本地离线开发和创建需要进行 npm install
的测试非常有用,以避免访问外部服务器。但是,在将包发布到公共注册表时,不应使用本地路径作为依赖项。
注意:当以本地路径链接的包在运行 npm install
时,它们自己的依赖项不会被自动安装。您必须在本地路径本身内部运行 npm install
命令。
devDependencies
字段用于列出项目在开发和测试过程中所需的依赖包及其版本。这些依赖包通常仅在开发环境中使用,而在生产环境中则不需要。
devDependencies
字段与 dependencies
字段类似,也是一个对象,其键(key)是依赖包的名称,值(value)是所需的版本号。区别在于,dependencies
字段中的依赖包适用于生产环境,而 devDependencies
字段中的依赖包仅在开发环境中使用。
以下是一个包含 devDependencies
字段的 package.json
示例:
{
"name": "example",
"version": "1.0.0",
"description": "An example project",
"scripts": {
"start": "node server.js",
"test": "mocha"
},
"dependencies": {
"express": "^4.17.1"
},
"devDependencies": {
"mocha": "^9.1.3",
"chai": "^4.3.4"
}
}
在这个示例中,项目的开发依赖包包括 mocha
和 chai
,它们通常用于项目的测试。当你在项目中运行 npm install
命令时,这些依赖包将被安装到 node_modules
目录下。然而,在生产环境中部署项目时,你可以使用 npm install --production
命令来仅安装 dependencies
字段中的依赖包,跳过 devDependencies
字段中的依赖包。这样可以减小生产环境的依赖包大小,提高部署速度。
peerDependencies
用于指定当前项目所依赖的包及其版本范围。但与 dependencies
和 devDependencies
不同的是,peerDependencies
中的依赖包不会被自动安装。它们主要用于插件、库和工具等场景,表示这些项目需要与其它特定的包一起使用,但不会直接导入这些依赖包。
peerDependencies
的主要作用是确保一些共享依赖包只被安装一次,避免不同版本的依赖包同时存在,导致潜在的冲突和错误。当你的项目被其他项目安装时,如果它们已经安装了 peerDependencies
中指定的依赖包,npm 会检查这些依赖包的版本是否兼容。如果不兼容,npm 会给出警告,提示用户更新依赖包版本。
以下是一个包含 peerDependencies
字段的 package.json
示例:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "A plugin for example-framework",
"peerDependencies": {
"example-framework": "^2.0.0"
}
}
在这个示例中,my-plugin
插件需要与 example-framework
一起使用,且 example-framework
的版本应在 2.0.0
以上。当用户安装 my-plugin
时,如果他们的项目中没有安装 example-framework
,或者已安装的 example-framework
版本不兼容,npm 会给出警告。用户需要自行安装或更新 example-framework
以满足 peerDependencies
中的要求。
在 npm 的 3 到 6 版本中,
peerDependencies
不会自动安装,并且如果在树中找到不合法版本的 peer 依赖项,会引发警告。从 npm v7 开始,默认情况下会安装peerDependencies
。
如果依赖树无法正确解析,尝试安装与其它插件相冲突的依赖时可能会导致错误。因此,请确保你的插件需求尽可能宽泛,不要将其限制在特定的补丁版本上。
假设宿主程序遵循 semver 规范,那么只有在宿主程序的主版本发生变化时才会破坏你的插件。因此,如果你已经使用过宿主程序的每个 1.x
版本,请使用 ^1.0
或 1.x
来表示这一点。如果你依赖于 1.5.2
中引入的功能,请使用 ^1.5.2
。
peerDependenciesMeta
用于提供关于 peerDependencies
字段中依赖项的附加元数据。它可以用于指定某些 peerDependencies
是可选的,这意味着即使它们没有被安装或版本不兼容,也不会导致安装失败或警告。
peerDependenciesMeta
是一个对象,其键(key)是 peerDependencies
中的依赖包名称,值(value)是一个包含 optional
属性的对象。将 optional
属性设置为 true
可以将对应的依赖项标记为可选。
以下是一个包含 peerDependenciesMeta
字段的 package.json
示例:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "A plugin for example-framework",
"peerDependencies": {
"example-framework": "^2.0.0",
"optional-dependency": "^1.0.0"
},
"peerDependenciesMeta": {
"optional-dependency": {
"optional": true
}
}
}
在这个示例中,my-plugin
插件依赖于 example-framework
和 optional-dependency
。通过在 peerDependenciesMeta
字段中将 optional-dependency
标记为可选,即使用户没有安装 optional-dependency
或其版本不兼容,也不会在安装过程中产生错误或警告。这对于提供可选功能的插件和库非常有用,允许它们在没有特定依赖项的情况下正常工作。
bundleDependencies
用于定义一个包名数组,这些包将在发布时捆绑在一起。这意味着当其他人安装你的包时,这些捆绑的依赖项将作为一个整体与你的包一起分发,而不需要从 npm 仓库单独下载。这对于在离线环境中使用 npm 包或确保特定依赖版本始终可用非常有用。
你可以通过在 bundleDependencies
数组中指定包名,并执行 npm pack
命令将这些包捆绑到一个 tarball 文件中。
例如:
如果我们定义了如下的 package.json
:
{
"name": "awesome-web-framework",
"version": "1.0.0",
"bundleDependencies": [
"renderized",
"super-streams"
]
}
我们可以通过运行 npm pack
命令获得 awesome-web-framework-1.0.0.tgz
文件。这个文件包含了 renderized
和 super-streams
这两个依赖,可以通过执行 npm install awesome-web-framework-1.0.0.tgz
将它们安装到新项目中。请注意,包名中不包含任何版本信息,因为这些信息已在 dependencies
中指定。
注意,bundleDependencies
字段有时也会拼写为 bundledDependencies
,这两种拼写都是有效的。
另外,bundleDependencies
也可以定义为布尔值。true
值表示捆绑所有依赖项,false
值表示不捆绑任何依赖项。
optionalDependencies
用于列出项目中可选的依赖包及其版本。这些依赖包不是项目运行所必需的,但在某些情况下,它们可以为项目提供额外的功能或性能优化。
optionalDependencies
的一个重要特性是,当安装这些依赖包时,如果出现任何问题(例如编译错误或不兼容的平台),npm 会继续安装过程而不是中断。这使得你可以在不同的环境中灵活地使用可选依赖包,而不会影响项目的正常安装和使用。
以下是一个包含 optionalDependencies
字段的 package.json
示例:
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"library-a": "^1.0.0"
},
"optionalDependencies": {
"library-b": "^2.0.0"
}
}
在这个示例中,library-a
是项目的必需依赖项,而 library-b
是可选依赖项。当你运行 npm install
时,npm 会尝试安装 library-b
,但如果安装失败,安装过程仍会继续,不会影响项目的其他部分。
请注意,如果一个依赖包同时出现在 dependencies
和 optionalDependencies
中,optionalDependencies
中的设置将优先生效,所以最好只放一个地方。
如果你需要对依赖项的依赖项进行特定更改,例如将具有已知安全问题的依赖项版本替换为其他版本,或用分支替换现有依赖项,或确保在所有地方都使用相同的包版本,那么你可以添加一个覆盖 override
。
覆盖提供了一种用另一个版本或完全不同的包替换依赖关系树中的包的方法。这些更改可以根据需要进行特定或模糊的限制。
如果要确保无论依赖项依赖的版本如何,始终将包 foo
安装为版本 1.0.0
,可按照如下写法:
{
"overrides": {
"foo": "1.0.0"
}
}
上面是一个简写表示法,可以使用完整的对象形式来允许覆盖包本身以及包的子项。这将使 foo
始终为 1.0.0
,同时使 foo
之外的任何深度的 bar
也为 1.0.0
:
{
"overrides": {
"foo": {
".": "1.0.0",
"bar": "1.0.0"
}
}
}
要仅在 foo
作为包 bar
的子项(或子子项,或子子子项等)时将其覆盖为 1.0.0
:
{
"overrides": {
"bar": {
"foo": "1.0.0"
}
}
}
键可以嵌套到任意长度。要在 foo
作为 bar
的子项且 bar
作为 baz
的子项时覆盖 foo
:
{
"overrides": {
"baz": {
"bar": {
"foo": "1.0.0"
}
}
}
}
覆盖的键还可以包括版本或版本范围。要将 foo
覆盖为 1.0.0
,但仅当它是 [email protected]
的子项时:
{
"overrides": {
"[email protected]": {
"foo": "1.0.0"
}
}
}
除非依赖项和覆盖本身共享完全相同的规范,否则你不得为直接依赖的包设置覆盖。为了更容易处理这个限制,覆盖也可以通过在希望版本匹配的包名称前加上 $
来定义为对直接依赖项的规范的引用。
{
"dependencies": {
"foo": "^1.0.0"
},
"overrides": {
// BAD, will throw an EOVERRIDE error
// "foo": "^2.0.0"
// GOOD, specs match so override is allowed
// "foo": "^1.0.0"
// BEST, the override is defined as a reference to the dependency
"foo": "$foo",
// the referenced package does not need to match the overridden one
"bar": "$foo"
}
}
通过 engines
字段可以指定您的项目适用的 Node.js 版本:
{
"engines": {
"node": ">=0.10.3 <15"
}
}
与 dependencies
类似,如果你不指定版本(或者将版本指定为 *
),那么任何版本的 Node.js 都可以使用。
你还可以使用 engines
字段来指定哪些版本的 npm 能够正确安装你的程序。例如:
{
"engines": {
"npm": "~1.0.20"
}
}
除非用户已设置 engine-strict
配置,否则此字段仅具有建议性,当你的包作为依赖项安装时,只会产生警告。
通过 os
字段可以指定你的模块可以在哪些操作系统上运行:
{
"os": [
"darwin",
"linux"
]
}
你还可以添加不被允许的操作系统,只需在被阻止的操作系统前加上 !
:
所谓的不被允许,一般值您的项目无法在对应的操作系统上运行起来
{
"os": [
"!win32"
]
}
一般宿主操作系统由 process.platform
可确定。
允许同时阻止和允许,尽管这样做无什么意义。
如果您的代码只在特定的 CPU 架构上运行,可在配置文件中指定相应的架构。
{
"cpu": [
"x64",
"ia32"
]
}
上述配置表示您的代码可以在 x64 和 ia32 架构上运行。您还可以使用 “!” 符号来阻止特定的架构。例如,如果您希望阻止 arm 和 mips 架构,可以这样配置:
{
"cpu": [
"!arm",
"!mips"
]
}
一般宿主的架构可以通过 process.arch
来确定。
如果在您的 package.json 文件中设置了 "private": true
,那么 npm 将拒绝发布它。
这是一种防止私有存储库意外发布的方式。如果您希望确保特定的软件包仅发布到特定的注册表(例如,内部注册表),那么可以使用下面描述的 publishConfig
字段来覆盖发布时的注册表配置参数。
publishConfig
是一个在发布时将被使用的配置值集合。如果你想设置标签(tag)、注册表(registry)或访问权限(access),它特别方便,这样你可以确保给定的包不会被标记为 “latest”,不会发布到公共注册表,或者默认情况下一个作用域模块是私有的。
请查看 config 以查看可以被覆盖的配置选项列表。
以下是一个包含 publishConfig
字段的 package.json 示例:
{
"name": "my-package",
"version": "1.0.0",
"publishConfig": {
"tag": "beta",
"registry": "https://my-private-registry.example.com/",
"access": "restricted"
}
}
在这个示例中,当你发布 my-package
时,它将被标记为 “beta”(而非 “latest”),发布到指定的私有注册表(而非公共注册表),并且访问权限被限制为 “restricted”(私有)。
可选的 workspaces
字段是一个文件模式数组,它描述了安装时应在本地文件系统中查找的位置,以找到需要链接到顶层 node_modules
文件夹的每个工作区。
它可以描述用作工作区的文件夹的直接路径,也可以定义将解析为这些相同文件夹的通配符(globs)。
在以下示例中,只要位于 ./packages
文件夹内的所有文件夹中都有有效的 package.json 文件,它们都将被视为工作区:
{
"name": "workspace-example",
"workspaces": [
"./packages/*"
]
}
有关更多示例,请参阅 workspaces。
npm 会根据包内容为一些值设置默认值。
"scripts": {"start": "node server.js"}
如果在包的根目录中有一个 server.js
文件,那么 npm 会将 start
命令默认设置为 node server.js
。
"scripts":{"install": "node-gyp rebuild"}
如果在包的根目录中有一个 binding.gyp
文件,并且你没有定义 install
或 preinstall
脚本,npm 会将 install
命令默认设置为使用 node-gyp
编译。
"contributors": [...]
如果在包的根目录中有一个 AUTHORS
文件,npm 会将每一行视为 Name
格式,其中 email 和 url 是可选的。以 # 开头的行或空行将被忽略。