package.json
一个包的清单文件。 它包含包的所有元数据,包括依赖项、标题、作者等等。 这是所有主要的 Node.JS 包管理工具,包括 pnpm 的保留标准。
engines
你可以指定你的软件能够运行的 Node 版本和 pnpm 版本:
{
"engines": {
"node": ">=10",
"pnpm": ">=3"
}
}
During local development, pnpm will always fail with an error message
if its version does not match the one specified in the engines field.
Unless the user has set the engine-strict config flag (see .npmrc), this
field is advisory only and will only produce warnings when your package is
installed as a dependency.
dependenciesMeta
Additional meta information used for dependencies declared inside dependencies, optionalDependencies, and devDependencies.
dependenciesMeta.*.injected
If this is set to true for a dependency that is a local workspace package, that package will be installed by creating a hard linked copy in the virtual store (node_modules/.pnpm).
If this is set to false or not set, then the dependency will instead be installed by creating a node_modules symlink that points to the package's source directory in the workspace. This is the default, as it is faster and ensures that any modifications to the dependency will be immediately visible to its consumers.
For example, suppose the following package.json is a local workspace package:
{
"name": "card",
"dependencies": {
"button": "workspace:1.0.0"
}
}
The button dependency will normally be installed by creating a symlink in the node_modules directory of card, pointing to the development directory for button.
But what if button specifies react in its peerDependencies? If all projects in the monorepo use the same version of react, then there is no problem. But what if button is required by card that uses react@16 and form that uses react@17? Normally you'd have to choose a single version of react and specify it using devDependencies of button. Symlinking does not provide a way for the react peer dependency to be satisfied differently by different consumers such as card and form.
The injected field solves this problem by installing a hard linked copies of button in the virtual store. To accomplish this, the package.json of card could be configured as follows:
{
"name": "card",
"dependencies": {
"button": "workspace:1.0.0",
"react": "16"
},
"dependenciesMeta": {
"button": {
"injected": true
}
}
}
Whereas the package.json of form could be configured as follows:
{
"name": "form",
"dependencies": {
"button": "workspace:1.0.0",
"react": "17"
},
"dependenciesMeta": {
"button": {
"injected": true
}
}
}
With these changes, we say that button is an "injected dependency" of card and form. When button imports react, it will resolve to react@16 in the context of card, but resolve to react@17 in the context of form.
Because injected dependencies produce copies of their workspace source directory, these copies must be updated somehow whenever the code is modified; otherwise, the new state will not be reflected for consumers. When building multiple projects with a command such as pnpm --recursive run build, this update must occur after each injected package is rebuilt but before its consumers are rebuilt. For simple use cases, it can be accomplished by invoking pnpm install again, perhaps using a package.json lifecycle script such as "prepare": "pnpm run build" to rebuild that one project. Third party tools such as pnpm-sync and pnpm-sync-dependencies-meta-injected provide a more robust and efficient solution for updating injected dependencies, as well as watch mode support.
peerDependenciesMeta
This field lists some extra information related to the dependencies listed in
the peerDependencies field.
peerDependenciesMeta.*.optional
如果设置为 true,所选的 peer dependency 将被包管理工具标记为可选的。 因此,消费方省略它将不再是 被报告为错误。
示例:
{
"peerDependencies": {
"foo": "1"
},
"peerDependenciesMeta": {
"foo": {
"optional": true
},
"bar": {
"optional": true
}
}
}
Note that even though bar was not specified in peerDependencies, it is
marked as optional. 因此,pnpm 将假定任何版本的 bar 都是被允许的。
However, foo is optional, but only to the required version specification.
publishConfig
在包被打包之前,可以覆盖清单中的某些字段。 以下字段可以被覆盖:
To override a field, add the publish version of the field to publishConfig.
For instance, the following package.json:
{
"name": "foo",
"version": "1.0.0",
"main": "src/index.ts",
"publishConfig": {
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}
}
将被发布为:
{
"name": "foo",
"version": "1.0.0",
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}
publishConfig.executableFiles
默认情况下,出于可移植性的原因,除了 bin 字段中列出的文件之外,不会在生成的包存档中将任何文件标记为可执行文件。 The executableFiles field lets you declare additional fields that must have the executable flag (+x) set even if they aren't directly accessible through the bin field.
{
"publishConfig": {
"executableFiles": [
"./dist/shim.js"
]
}
}
publishConfig.directory
You also can use the field publishConfig.directory to customize the published subdirectory relative to the current package.json.
预计在指定目录中有当前包的修改版本(通常使用第三方构建工具)。
In this example the
"dist"folder must contain apackage.json
{
"name": "foo",
"version": "1.0.0",
"publishConfig": {
"directory": "dist"
}
}
publishConfig.linkDirectory
- Default: true
- Type: Boolean
When set to true, the project will be symlinked from the publishConfig.directory location during local development.
示例:
{
"name": "foo",
"version": "1.0.0",
"publishConfig": {
"directory": "dist",
"linkDirectory": true
}
}
pnpm.overrides
此字段允许您指示 pnpm 覆盖依赖关系图中的任何依赖项。 This is useful for enforcing all your packages to use a single version of a dependency, backporting a fix, replacing a dependency with a fork, or removing an unused dependency.
请注意,overrides 字段只能在项目的根目录下设置。
An example of the "pnpm"."overrides" field:
{
"pnpm": {
"overrides": {
"foo": "^1.0.0",
"quux": "npm:@myorg/quux@^1.0.0",
"bar@^2.1.0": "3.0.0",
"qar@1>zoo": "2"
}
}
}
You may specify the package the overridden dependency belongs to by
separating the package selector from the dependency selector with a ">", for
example qar@1>zoo will only override the zoo dependency of qar@1, not for
any other dependencies.
一个overide可以被定义为直接依赖项的规则的引用。
This is achieved by prefixing the name of the dependency with a $:
{
"dependencies": {
"foo": "^1.0.0"
},
"pnpm": {
"overrides": {
"foo": "$foo"
}
}
}
被引用的包不必匹配需要覆盖的包:
{
"dependencies": {
"foo": "^1.0.0"
},
"pnpm": {
"overrides": {
"bar": "$foo"
}
}
}
Added in: v9.12.0
If you find that your use of a certain package doesn’t require one of its dependencies, you may use - to remove it. For example, if package foo@1.0.0 requires a large package named bar for a function that you don’t use, removing it could reduce install time:
{
"pnpm": {
"overrides": {
"foo@1.0.0>bar": "-"
}
}
}
This feature is especially useful with optionalDependencies, where most optional packages can be safely skipped.
pnpm.packageExtensions
The packageExtensions fields offer a way to extend the existing package definitions with additional information. For example, if react-redux should have react-dom in its peerDependencies but it has not, it is possible to patch react-redux using packageExtensions:
{
"pnpm": {
"packageExtensions": {
"react-redux": {
"peerDependencies": {
"react-dom": "*"
}
}
}
}
}
The keys in packageExtensions are package names or package names and semver ranges, so it is possible to patch only some versions of a package:
{
"pnpm": {
"packageExtensions": {
"react-redux@1": {
"peerDependencies": {
"react-dom": "*"
}
}
}
}
}
The following fields may be extended using packageExtensions: dependencies, optionalDependencies, peerDependencies, and peerDependenciesMeta.
一个更大的例子:
{
"pnpm": {
"packageExtensions": {
"express@1": {
"optionalDependencies": {
"typescript": "2"
}
},
"fork-ts-checker-webpack-plugin": {
"dependencies": {
"@babel/core": "1"
},
"peerDependencies": {
"eslint": ">= 6"
},
"peerDependenciesMeta": {
"eslint": {
"optional": true
}
}
}
}
}
}
Together with Yarn, we maintain a database of packageExtensions to patch broken packages in the ecosystem.
If you use packageExtensions, consider sending a PR upstream and contributing your extension to the @yarnpkg/extensions database.
pnpm.peerDependencyRules
pnpm.peerDependencyRules.ignoreMissing
pnpm 不会打印有关依赖列表中缺少对 peerDependency 的警告。
For instance, with the following configuration, pnpm will not print warnings if a dependency needs react but react is not installed:
{
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": ["react"]
}
}
}
包名也可以使用模式匹配
{
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": ["@babel/*", "@eslint/*"]
}
}
}
pnpm.peerDependencyRules.allowedVersions
对于指定版本范围的 peerDependency,将不会打印未满足版本范围的警告。
For instance, if you have some dependencies that need react@16 but you know that they work fine with react@17, then you may use the following configuration:
{
"pnpm": {
"peerDependencyRules": {
"allowedVersions": {
"react": "17"
}
}
}
}