Preguntas Frecuentes
¿Por qué mi node_modules
usa espacio en disco si los paquetes se almacenan en una tienda global?
pnpm crea enlaces duros desde el almacén global a las carpetas node_modules
. Los enlaces duros apuntan al mismo lugar en el disco donde se encuentran los archivos originales. Entonces, por ejemplo, si tiene foo
en su proyecto como una dependencia y ocupa 1 Mb de espacio, entonces parecerá que ocupa 1 Mb de espacio en node_modules
del proyecto y la misma cantidad de espacio en el almacén global. Sin embargo, ese 1 Mb es el mismo espacio en el disco direccionado desde dos ubicaciones diferentes. Entonces, en total, foo
ocupa 1 Mb, no 2 Mb.
Para más sobre este tema:
- ¿Por qué los enlaces duros parecen ocupar el mismo espacio que los originales?
- Un hilo de la sala de chat de pnpm
- Un issue en el repositorio de pnpm
¿Funciona en Windows?
Respuesta corta: Sí. Respuesta larga: el uso de enlaces simbólicos en Windows es problemático, por decir lo menos, sin embargo, pnpm tiene una solución. Para Windows, usamos junctions en su lugar.
¿Pero el anidado de node_modules
es incompatible con Windows?
Las primeras versiones de npm tenían problemas debido al anidamiento de todos los node_modules
(consulte este issue). Sin embargo, pnpm no crea carpetas profundas, almacena todos los paquetes de forma plana y usa enlaces simbólicos para crear la estructura de árbol de dependencia.
¿Qué pasa con los enlaces simbólicos circulares?
Aunque pnpm utiliza enlaces para poner dependencias en carpetas node_modules
, se evita el uso enlaces simbólicos circulares porque los paquetes principales se colocan en el mismo node_modules
en el que están sus dependencias. Así que las dependencias de foo
no están en foo/node_modules
, sino que foo
está en node_modules
junto con sus propias dependencias.
¿Por qué tener enlaces duros en absoluto? ¿Por qué no enlazar directamente con el almacén global?
Un paquete puede tener diferentes conjuntos de dependencias en una máquina.
En el proyecto A foo@1.0.0
puede tener una dependencia resuelta en bar@1.0.0
, pero en el proyecto B la misma dependencia de foo
podría resolverse en bar@1.1.0
; entonces, pnpm vincula foo@1.0.0
a cada proyecto donde se usa, para crear diferentes conjuntos de dependencias para él.
Los enlaces simbólicos directos al almacén global funcionarían con el flag --preserve-symlinks
de Node; sin embargo, ese enfoque viene con bastantes problemas propios, por lo que decidimos seguir con los enlaces duros. Para obtener más detalles sobre por qué se tomó esta decisión, consulte este issue.
¿pnpm funciona a través de varios discos o sistemas de archivos?
El almacén de paquetes debe estar en el mismo disco y sistema de archivos que las instalaciones, de lo contrario, los paquetes se copiarán, no se vincularán. Esto se debe a una limitación en cómo funcionan los enlaces duros, en el sentido de que un archivo en un sistema de archivos no puede dirigirse a una ubicación en otro. Consulte el Issue #712 para obtener más detalles.
pnpm funciona de forma diferente en los 2 casos siguientes:
La ruta el almacén está especificada
Si la ruta del almacén se especifica a través de la configuración del mismo, entonces se realiza la copia entre el almacén y cualquier proyecto que esté en un disco diferente.
Si ejecuta pnpm install
en el disco A
, entonces el almacén de pnpm debe estar en el disco A
. Si la tienda pnpm se encuentra en el disco B
, se copiarán todos los paquetes necesarios directamente en la ubicación del proyecto en lugar de vincularse. Esto inhibe severamente los beneficios de almacenamiento y rendimiento de pnpm.
La ruta el almacén NO está especificada
Si no se establece la ruta del almacén, se crean varios (uno por disco o sistema de archivos).
Si la instalación se ejecuta en el disco A
, el almacén será creado en A
.pnpm-store
en la raíz del sistema de archivos. Si luego la instalación se ejecuta en el disco B
, se creará un almacén independiente en B
en .pnpm-store
. Los proyectos aún mantendrían los beneficios de pnpm, pero cada disco puede tener paquetes redundantes.
¿Qué significa pnpm
?
pnpm
significa performant npm
, en español, "npm rendidor". @rstacruz es a quien se le ocurrió el nombre.
¿pnpm
no funciona con <TU-PROYECTO-AQUÍ>?
En la mayoría de los casos, significa que una de las dependencias requiere paquetes no declarados en paquete.json
. Es un error común causado por node_modules
plano. Si esto sucede, se trata de un error en la dependencia y se debe arreglar la misma. Esto puede tomar un buen tiempo, por lo que pnpm proporciona alternativas para hacer funcionar los paquetes con errores.
Solución 1
In case there are issues, you can use the node-linker=hoisted
setting. This creates a flat node_modules
structure similar to the one created by npm
.
Solución 2
In the following example, a dependency does not have the iterall
module in its own list of deps.
The easiest solution to resolve missing dependencies of the buggy packages is to add iterall
as a dependency to our project's package.json
.
You can do so, by installing it via pnpm add iterall
, and will be automatically added to your project's package.json
.
"dependencies": {
...
"iterall": "^1.2.2",
...
}
Solución 3
One of the solutions is to use hooks for adding the missing dependencies to the package's package.json
.
An example was Webpack Dashboard which wasn't working with pnpm
. It has since been resolved such that it works with pnpm
now.
It used to throw an error:
Error: Cannot find module 'babel-traverse'
at /node_modules/inspectpack@2.2.3/node_modules/inspectpack/lib/actions/parse
The problem was that babel-traverse
was used in inspectpack
which was used by webpack-dashboard
, but babel-traverse
wasn't specified in inspectpack
's package.json
. It still worked with npm
and yarn
because they create flat node_modules
.
The solution was to create a .pnpmfile.cjs
with the following contents:
module.exports = {
hooks: {
readPackage: (pkg) => {
if (pkg.name === "inspectpack") {
pkg.dependencies['babel-traverse'] = '^6.26.0';
}
return pkg;
}
}
};
After creating a .pnpmfile.cjs
, delete pnpm-lock.yaml
only - there is no need to delete node_modules
, as pnpm hooks only affect module resolution. Then, rebuild the dependencies & it should be working.