package.json
O arquivo de manifesto de um pacote. Contém todos os metadados do pacote, incluindo dependências, título, autor e etc. Este é um padrão preservado por todos os principais gerenciadores de pacotes do Node.JS, incluindo o pnpm.
engines
Você pode especificar a versão do Node e do pnpm em que o seu software funciona:
{
    "engines": {
        "node": ">=10",
        "pnpm": ">=3"
    }
}
Durante o desenvolvimento local, o pnpm sempre falhará com uma mensagem de erro se sua versão não corresponder à especificada no campo engines.
A menos que o usuário tenha definido a flag de configuração engine-strict (veja .npmrc), esse campo é apenas consultivo e só produzirá avisos quando seu pacote for instalado como dependência.
dependenciesMeta
Informações meta adicionais usadas para dependências declaradas dentro de dependencies, optionalDependencies, e devDependencies.
dependenciesMeta.*.injected
Se isto é configurado como true para uma dependência local, o pacote será linkado fisicamente para o armazenamento virtual (node_modules/.pnpm) e linkado simbolicamente do armazenamento virtual para o diretório de módulos.
Se isto é configurado como false ou não configurado para uma dependência local, o pacote será linkado simbolicamente diretamente de sua localização no espaço de trabalho para o diretório do módulo.
Por exemplo, o seguinte package.json num espaço de trabalho criará um link simbólico para button no diretório node_modules de card:
{
  "name": "card",
  "dependencies": {
    "button": "workspace:1.0.0"
  }
}
Mas e se button tiver react em suas dependências? Se todos os projetos no monorepo usarem as mesmas versões de react, então não há problema. Mas e se button for exigido por card que usa react@16 e form com react@17? Sem usar inject, você teria que escolher uma única versão de react e instalá-la como dependência de desenvolvimento de button. Mas usando o campo injected você pode injetar button em um pacote, e button será instalado com o react na versão desse pacote.
Então esse será o package.json de card:
{
  "name": "card",
  "dependencies": {
    "button": "workspace:1.0.0",
    "react": "16"
  },
  "dependenciesMeta": {
    "button": {
      "injected": true
    }
  }
}
button será vinculado fisicamente às dependências de card, e react@16 será linkado simbolicamente as dependências de card/node_modules/button.
E esse será o package.json de form:
{
  "name": "form",
  "dependencies": {
    "button": "workspace:1.0.0",
    "react": "17"
  },
  "dependenciesMeta": {
    "button": {
      "injected": true
    }
  }
}
button será linkado fisicamente às dependências de form, e react@17 será linkado simbolicamente as dependências de form/node_modules/button.
In contrast to normal dependencies, injected ones are not symlinked to the destination folder, so they are not updated automatically, e.g. after running the build script. To update the hard linked folder contents to the latest state of the dependency package folder, call pnpm i again.
Note that the button package must have any lifecycle script that runs on install in order for pnpm to detect the changes and update it. For example, the package can be rebuilt on install: "prepare": "pnpm run build". Any script would work, even a simple unrelated command without side effects, like this: "prepare": "pnpm root".
peerDependenciesMeta
This field lists some extra information related to the dependencies listed in the peerDependencies field.
peerDependenciesMeta.*.optional
If this is set to true, the selected peer dependency will be marked as optional by the package manager. Therefore, the consumer omitting it will no longer be reported as an error.
Por exemplo:
{
    "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 will therefore assume that any version of bar is fine. However, foo is optional, but only to the required version specification.
publishConfig
It is possible to override some fields in the manifest before the package is packed. The following fields may be overridden:
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"
    }
}
Will be published as:
{
    "name": "foo",
    "version": "1.0.0",
    "main": "lib/index.js",
    "typings": "lib/index.d.ts"
}
publishConfig.executableFiles
By default, for portability reasons, no files except those listed in the bin field will be marked as executable in the resulting package archive. 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.
It is expected to have a modified version of the current package in the specified directory (usually using third party build tools).
Nesse exemplo, a pasta
distdeve conter umpackage.json
{
  "name": "foo",
  "version": "1.0.0",
  "publishConfig": {
    "directory": "dist"
  }
}