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
dist
deve conter umpackage.json
{
"name": "foo",
"version": "1.0.0",
"publishConfig": {
"directory": "dist"
}
}