Saltar al contenido principal
Version: 7.x

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:

¿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.