Cómo Yarn Y Pnpm Han Centrado Sus Esfuerzos Más De Cerca

Este artículo tiene como objetivo dejarle una impresión de hacia dónde se dirigen los administradores de paquetes en el futuro para satisfacer las necesidades de los desarrolladores, por ejemplo, permitiéndoles administrar grandes proyectos monorepo con un rendimiento adecuado y un buen DX.

Escribí en un artículo anterior sobre el tema de las estrategias de resolución de dependencias entre npm, Yarn y pnpm. Si bien el enfoque en el artículo anterior fue comparar conceptos y estructuras centrales, este artículo cubrirá las características avanzadas de los administradores de paquetes modernos, incluidos los monorepos, a través de espacios de trabajo.

El objetivo de este artículo es transmitir cómo Yarn y pnpm han centrado sus esfuerzos más de cerca en permitir a los desarrolladores crear monorepos a través de espacios de trabajo y proporcionar enfoques más avanzados para mejorar la seguridad y el rendimiento. 

Proyectos complementarios

Este artículo cubre varias características del administrador de paquetes. Por lo tanto, creé dos proyectos complementarios en GitHub para brindar ejemplos:

  1. Un proyecto monorepo para demostrar las características del espacio de trabajo
  2. Un proyecto separado para demostrar diferentes estrategias de resolución de dependencia

Estrategias alternativas de resolución de dependencia

Cuando se usa la configuración predeterminada, pnpm y Yarn Berry no usan los mismos algoritmos de resolución de dependencias que npm y Yarn Classic, lo que implica aplanar node_modulescarpetas. Estos administradores de paquetes modernos intentan separarse de los enfoques tradicionales para procesar y almacenar dependencias.

La razón de esto es que se requieren enfoques de resolución innovadores para hacer frente a los requisitos de los proyectos de software modernos, que utilizan cada vez más grandes cantidades de dependencias. Las estrategias tradicionales han llegado a sus límites en términos de rendimiento y eficiencia del espacio en disco.

El problema con el enfoque tradicionalnode_modules

La estrategia tradicional de resolución de dependencias para aplanar node_modulescarpetas genera varios problemas diferentes :

  • Los módulos pueden (accidentalmente) acceder a paquetes de los que no dependen, lo que puede generar errores
  • El algoritmo de aplanamiento es un proceso de E/S que requiere mucho tiempo.

El problema raíz de este diseño plano node_moduleses un concepto llamado elevación , que fue introducido por npm en v3 . Este mismo algoritmo de resolución de dependencia también fue utilizado por Yarn Classic al principio.

En pocas palabras, la elevación aplana la node_modulescarpeta de tal manera que todas las dependencias, incluso las dependencias de dependencias, terminan en el nivel raíz de node_modules. La razón para subir todo a un nivel de carpeta es reducir la redundancia que provoca el anidamiento. La siguiente imagen muestra cómo funciona esto:

 

Las diferencias entre los algoritmos node_module de npm v2 y npm v3

La elevación puede provocar errores graves y difíciles de detectar, especialmente en proyectos grandes. Jonathan Creamer brinda una visión detallada de lo que puede salir mal en un proyecto monorepo donde el algoritmo de elevación falla y provoca errores de producción. En tales situaciones, el levantamiento puede conducir a dependencias fantasmas y doppelgangers .

El enfoque Plug'n'Play de Yarn Berry

Yarn Berry trató de deshacerse por node_modulescompleto, utilizando un enfoque Plug'n'Play . Puede leer acerca de la motivación de Yarn Berry para deshacerse de node_modules, pero las razones son similares a las de pnpm.

PnP es una estrategia de instalación nueva e innovadora para Node, desarrollada en contraste con el requireflujo de trabajo establecido (y único) Common, js que aborda muchas de sus ineficiencias. A diferencia de la forma tradicional, Yarn Berry invierte la responsabilidad en quién encuentra los paquetes.

Anteriormente, Node tenía que encontrar sus paquetes dentro de las node_modulescarpetas. Yarn Berry en modo PnP ya tiene toda la información que necesita a mano y, en cambio, le dice a Node dónde encontrarla. Esto reduce drásticamente el tiempo de instalación del paquete.

Yarn Berry logra esto generando un archivo en lugar de una carpeta .pnp.cjsanidada . node_modulesContiene tablas de búsqueda para informar a Node sobre las ubicaciones de dependencia. Como uno de los beneficios, Yarn Berry puede asegurarse de compartir solo las ubicaciones de los paquetes que ha definido en uno de sus package.jsonarchivos, lo que mejora la seguridad y reduce los errores: ya no tiene que preocuparse por los duplicados, las dependencias fantasmas o otros tipos de acceso ilegal.

Sin embargo, los principales beneficios son velocidades de instalación más rápidas; solo estamos procesando un archivo, nuestro .pnp.cjsarchivo, por lo que tenemos menos operaciones de E/S. Los tiempos de inicio también se pueden mejorar porque el algoritmo de resolución de Node tiene que hacer menos trabajo.

Pero si no hay ninguna node_modulescarpeta, ¿dónde se almacenan los paquetes? Cada paquete se almacena como un archivo zip dentro de una .yarn/cache/carpeta. Esto funciona porque Yarn Berry mono parchea la API del sistema de archivos de Node de tal manera que las solicitudes de dependencias internas node_modulesdeben resolverse a partir del contenido de los archivos comprimidos dentro de la memoria caché. Estos archivos zip ocupan menos espacio en disco que la node_modulescarpeta.

PnP es el modo predeterminado de Yarn Berry, pero también puede habilitarlo explícitamente dentro de .yarnrc.yml.

# .yarnrc.yml
# alternatively, remove the next two lines, PnP strict is the default
nodeLinker: "pnp"
pnpMode: "strict"

La estructura típica de un proyecto PnP se parece a la siguiente. No hay node_modulescarpetas; las dependencias se almacenan en archivos zip en formato .yarn/cache/.

.
├── .yarn/
│   ├── cache/
│   ├── releases/
│   │   └── yarn-3.1.1.cjs
│   ├── sdk/
│   └── unplugged/
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

Problemas de depuración con dependencias en Yarn Berry PnP

Para depurar problemas con las dependencias, necesita compatibilidad con herramientas adicionales (p. ej., la extensión VS Code ), ya que debe "mirar dentro" de los archivos zip. Al momento de escribir, debe realizar pasos manuales agregando compatibilidad con SDK del editor porque dicha funcionalidad no está incorporada. El siguiente comando agrega soporte para VS Code :

$ yarn dlx @yarnpkg/sdks vscode

La CLI del SDK analiza su raíz package.jsonen busca de tecnologías compatibles y genera archivos de configuración que se almacenan en formato .yarn/sdk/.

Cambios de archivo de la CLI del SDK

En el caso de nuestro proyecto de demostración, detecta ESLint y Prettier . Consulte la rama de Git yarn-berry-pnppara ver un ejemplo de compatibilidad con PnP y SDK.

Estrategia de instalación cero de Yarn Berry

Lo bueno de PnP es que puede poner el .pnp.cjsarchivo y la .yarn/cache/carpeta bajo control de versión debido a sus tamaños de archivo justificables. Lo que obtienes de esto es una estrategia de instalación cero . Si su compañero de equipo extrae su código de Git, lo que puede llevar un poco más de tiempo usando esta estrategia, todos los paquetes y tablas de búsqueda estarán disponibles y no se requiere ningún paso de instalación antes de iniciar la aplicación. Eche un vistazo a un breve video de demostración que muestra la instalación cero en acción.

Puede ver cómo el .gitignorearchivo se parece a la rama de instalación cero de Yarn Berry PnP . Si agrega, actualiza o elimina dependencias, debe ejecutar yarn install, por supuesto, para actualizar yarn.lock, .pnp.cjsy las .yarn/cache/carpetas.

Optar por no participar en PnP: modo suelto

PnP es restrictivo y es posible que no funcione con algunos paquetes incompatibles (p. ej., React Native). Además, la migración a PnP podría no ser un camino fácil; por lo tanto, Yarn Berry proporciona un modo suelto . Puede activarlo .yarnrc.ymlconfigurando la nodeLinkerpropiedad en consecuencia.

# .yarnrc.yml
nodeLinker: "pnp"
pnpMode: "loose"

El modo suelto es un compromiso entre el modo estricto PnP y el node_modulesmecanismo tradicional de resolución de dependencias. La diferencia es que Yarn Berry solo advierte sobre el acceso de dependencia inseguro, en lugar de abortar con errores.

Debajo del capó, Yarn Berry realiza el algoritmo de elevación tradicional y lo usa como respaldo para cada dependencia no especificada. Esto todavía se considera inseguro según los estándares de Yarn Berry, pero puede ahorrar algo de tiempo: podrá analizar mejor las advertencias que recibe, solucionar sus problemas de raíz y volver a PnP estricto nuevamente rápidamente, si es necesario.

Es posible que desee cambiar a Yarn Berry porque Yarn Classic se considera heredado y, aunque se beneficia de algunas mejoras, se mantiene en el node_modulesmodo de instalación tradicional con node-modules nodeLinker.

# .yarnrc.yml
nodeLinker: "node-modules"

Con esto, la buena vieja node_modulescarpeta se vuelve a generar.

El equipo de Yarn Berry también se inspiró en la estrategia de almacenamiento direccionable por contenido de pnpm, que analizaremos a continuación, y agregó un modo con el mismo nombre. Es similar a su arquetipo y tiene como objetivo almacenar dependencias solo una vez, en su disco duro.

# .yarnrc.yml
nodeLinker: "pnpm"

Siéntase libre de probar los diferentes modos revisando las ramas de Git correspondientes de mi proyecto de demostración:

estrategia optimizada de pnpmnode_modules

pnpm almacena las dependencias en una node_modulescarpeta anidada, como npm, pero proporciona un mejor rendimiento y eficiencia del espacio en disco debido a su implementación de almacenamiento direccionable por contenido . Puede leer más sobre esto en mi artículo anterior sobre administradores de paquetes.

La estrategia Plug'n'Play de pnpm

Desde finales de 2020, pnpm v5.9 también es compatible con PnP e incluso se refiere a él como Plug'n'Play de Yarn . La documentación sobre esta función es escasa; El desarrollador principal de pnpm hace referencia a los documentos de Yarn Berry .

La rama pnpm PnP muestra cómo usar este modo. Tienes que activar el modo PnP en .npmrc.

# .npmrc
node-linker=pnp
symlink=false

Después de ejecutar pnpm i, la estructura del proyecto se ve así.

.
├── node_modules/
│   ├── .bin/
│   └── .pnpm/
├── .npmrc
├── .pnp.cjs
├── package.json
└── pnpm-lock.yaml

Consecuencias de los enfoques sin elevación

pnpm y Yarn Berry consideran que izar es una mala práctica. Como ya se mencionó, muchos proyectos en el ecosistema de JavaScript han basado sus implementaciones de elevación en la utilizada por npm y versiones anteriores de Yarn. Esta sección destaca algunos problemas que vienen con el enfoque sin elevación.

Con la rama de demostración de pnpm , tuve un problema al ejecutar un binario, ntl. No funcionaba debido al diseño no plano de pnpm node_modules, lo que me llevó a una discusión con el desarrollador principal de pnpm sobre un problema similar y me señaló la solución para hoistntl .

# .npmrc
hoist-pattern[]=*ntl*

Con el enfoque PnP de Yarn Berry, lo más probable es que te encuentres con situaciones similares. Durante el desarrollo de la rama de demostración de PnP , recibí este error al iniciar.

Error estricto de PnP al iniciar

En el seguimiento de la pila, descubrí que no react-isse encontró un paquete llamado en tiempo de ejecución. El mensaje de error en el lado izquierdo de la captura de pantalla anterior indica que esto tiene que ver con el styled-componentspaquete que especifiqué en mi archivo package.json. Parece que styled-componentsno enumera todas sus dependencias en su package.json archivo .

Hay una solución típica para tal problema PnP: la packageExtensionspropiedad . Actualizar .yarnrc.ymly ejecutar un adicional yarn installpara instalar la dependencia faltante soluciona el problema:

# .yarnrc.yml
packageExtensions:
  "styled-components@*":
    dependencies:
      react-is: "*"

Como se describió anteriormente, también puede cambiar a un enfoque de Yarn Berry menos restrictivo si está bien renunciar a los beneficios de seguridad de PnP en su proyecto.

pnpm PnP funciona de manera similar a la variante Yarn Berry y, como tal, también debe lidiar con su naturaleza más estricta. Debe especificar las dependencias que faltan en el package.json, como puede ver en la rama pnpm PnP .

// package.json
{
  "name": "package-manager-playground",
  "version": "1.0.0",
  "packageManager": "pnpm@6.24.4",
  "pnpm": {
    "packageExtensions": {
      "styled-components": {
        "dependencies": {
          "react-is": "*"
        }
      },
      "autoprefixer": {
        "dependencies": {
          "postcss": "*"
        }
      }
    }
  },
  // ...
}

Gestión de versiones mejorada

Trabajar en múltiples proyectos puede requerir diferentes versiones de Node o su administrador de paquetes. Por ejemplo, mi proyecto React Native usa Yarn Classic, pero para mi proyecto React, quiero usar una versión más reciente de Yarn Berry.

Un administrador de paquetes debería facilitar el cambio entre versiones. También debe contar con mecanismos que le permitan aplicar ciertas versiones de un administrador de paquetes, idealmente de forma automática. Esto reduce los errores causados ​​por el uso de diferentes versiones del administrador de paquetes. Como verá en un minuto, Yarn Berry es actualmente el único administrador de paquetes que ofrece una función para cambiar automáticamente a una versión en particular.

sobre el nivel del mar

La forma más fácil de cambiar una versión de Node que viene con una versión integrada de npm es usar nvm . Luego, también puede actualizar npm a la versión más reciente. Aquí hay unos ejemplos.

    $ nvm use 17.40
    $ npm -v # 8.1.2
    $ nvm install-latest-npm
    $ npm -v # 8.3.2

pnpm

pnpm proporciona su propia herramienta para administrar las versiones de Node: el pnpm envcomando agregado recientemente . Sirve como alternativa a herramientas como Volta o el mencionado nvm. Puede cambiar las versiones de Node y luego instalar versiones particulares de pnpm, ya sea con la ayuda de npm o Corepack . Aquí hay un ejemplo que aprovecha Corepack:

$ pnpm env use --global lts
$ node -v # 16.13.2
$ pnpm -v # 6.24.2
$ corepack prepare pnpm@6.25.1 --activate
$ pnpm -v # 6.25.1

Baya de hilo

Una característica poderosa de Yarn Berry, especialmente para equipos profesionales, es incluir una versión particular de Yarn Berry con su proyecto. Cuando se ejecuta en la raíz de su proyecto, el comando yarn set versionagrega la versión descargada .yarn/releases/y se actualiza .yarnrc.ymlpara establecer la versión actual con la yarnPathpropiedad .

# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs

Con esta configuración, su binario instalado localmente yarndifiere la ejecución a la versión binaria ubicada en yarnPath. Si confirma esta configuración, junto con la .yarn/releasescarpeta, todos los compañeros de equipo usarán automáticamente la misma versión del yarnbinario. Esto lleva a que la instalación de dependencia determinista se ejecute en todos los sistemas, no más problemas de "ejecuciones en mi máquina".

La siguiente demostración muestra cómo esta versión se usa automáticamente después de verificar el código de Git.

yarn set versionen acción

Si usa Corepack, el comando también agrega la yarnversión binaria instalada a la packageManagerpropiedad en su package.jsonarchivo.

La packageManagerpropiedad se agrega a nuestro package.jsonarchivo.

Esto se puede usar como una "capa" adicional en la parte superior de la yarnPathconfiguración para asegurarse de que sus compañeros desarrolladores usen el administrador de paquetes correcto.

El error de uso de Corepack que se activa con una versión diferente del administrador de paquetes

Corepack sigue siendo una tecnología completamente nueva y todos los desarrolladores deben optar por usarla. Por lo tanto, no se puede garantizar de manera confiable que todos los desarrolladores usen el mismo administrador de paquetes con la misma versión.

En general, Yarn Berry's yarn set versiones un método sólido para aplicar la yarnversión binaria correcta en todo su equipo. Este mecanismo es superior a los mecanismos de otros administradores de paquetes.

Estrategias avanzadas de instalación de CI/CD

Esta sección se centra en las características adicionales del flujo de trabajo de instalación que son especialmente útiles en contextos de CI/CD. Muchos proyectos de desarrollo requieren estrategias eficientes para reducir el tiempo de procesamiento de las ejecuciones de canalización, como las estrategias de almacenamiento en caché.

sobre el nivel del mar

npm cies un comando similar a npm install, pero package-lock.jsondebe existir un archivo. Funciona tirando el tuyo node_modulesy recreándolo desde cero.

cisignifica "integración continua" y está destinado a ser utilizado en entornos CI/CD. Al ejecutar , no se actualizará $ npm ciuna preexistente , pero la carpeta se eliminará y se volverá a crear. En contraste con , este enfoque generalmente conduce a mejoras en la velocidad y ejecuciones de canalización más confiables porque un desarrollador envía al control de versiones exactamente las mismas versiones de dependencia definidas.package-lock.jsonnode_modulesnpm installpackage-lock.json

Además, npm instala paquetes en un caché local para aumentar la velocidad de reinstalación. Esto permite instalaciones fuera de línea debido a la resolución de paquetes fuera de línea , por ejemplo, usando un comando como $ npm i --prefer-offlinesi no tuviera conexión a Internet o si tuviera una conexión inestable. Si desea limpiar el caché, puede usar $ npm cache clean.

Baya de hilo

No existe una contrapartida de Yarn Berry npm cipara instalar dependencias en un contexto de CI/CD, pero puede hacer cosas similares con yarn install --frozen-lockfile.

Yarn Berry tiene una función avanzada de caché fuera de línea . Almacena en caché cada paquete como un único archivo zip en su .yarn/cache/carpeta. La ubicación de la carpeta de caché predeterminada se puede cambiar con la cacheFolderpropiedad .

# .yarnrc.yml
cacheFolder: "./berry-cache"

Puede limpiar el caché con los siguientes comandos.

# manual clean is optional
$ yarn cache clean
# global mirror needs to be cleaned manually
$ yarn cache clean --mirror

De forma predeterminada, Yarn Berry crea una carpeta de caché para cada proyecto. Si desea compartir el caché con varios proyectos, puede usar un caché global en su lugar usando la enableGlobalCachepropiedad . Cada proyecto con esta misma configuración comparte el caché global.

# .yarnrc.yml
enableGlobalCache: true

pnpm

Sin conexión a Internet, los paquetes se instalan desde la tienda. También puede decirle explícitamente a pnpm que recupere todos los paquetes de la tienda con $ pnpm i --offline. Si uno o más paquetes no son parte de la tienda, obtiene un error.

No hay un comando como npm ci, pero según sus mantenedores, pnpm funciona bien en un contexto de CI/CD .

Acceso a registros privados

Cada administrador de paquetes funciona de forma inmediata con el registro público de npm . En el contexto de una empresa con bibliotecas compartidas, lo más probable es que desee reutilizar paquetes sin publicarlos públicamente. Ahí es donde entran en juego los registros privados.

sobre el nivel del mar

La siguiente configuración es parte del .npmrcarchivo ubicado en la carpeta raíz del proyecto. Indica cómo acceder a un registro privado de GitLab .

# .npmrc
@doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/<project-id>/packages/npm/

Los datos confidenciales van al .npmrcarchivo ubicado fuera del proyecto.

# ~/.npmrc
//gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

pnpm

pnpm usa el mismo mecanismo de configuración que npm , por lo que puede almacenar su configuración en un .npmrcarchivo. La configuración de un registro privado funciona de la misma manera que con npm.

Baya de hilo

La configuración de registros privados es similar a npm, pero la sintaxis difiere porque la configuración se almacena en un archivo YAML.

# .yarnrc.yml
npmScopes:
  doppelmutzi:
    npmRegistryServer: 'https://gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/'

Nuevamente, su token de autenticación debe almacenarse fuera de su proyecto.

# ~/.yarnrc.yml
npmRegistries:
  //gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

Agregar soporte monorepo con espacios de trabajo

Un monorepo es un repositorio de Git que alberga múltiples proyectos. Google gestiona la mayoría de sus proyectos en un monorepo desde hace bastante tiempo. Algunos beneficios incluyen:

  • Refactorización a gran escala
  • reutilización de código
  • Gestión de dependencia simplificada

Los administradores de paquetes modernos admiten monorepos a través de una característica llamada espacios de trabajo. En dichos proyectos, cada espacio de trabajo constituye un subproyecto y contiene un package.jsonque define su propio árbol de dependencia. Los conceptos detrás de cada implementación son bastante similares para todos los representantes: la CLI simplifica la administración de dependencias del monorepo, y los administradores de paquetes pueden incluso encargarse de las dependencias compartidas entre espacios de trabajo para mejorar la eficiencia del almacenamiento de su sistema de archivos.

Pero hay diferencias en los detalles y, por lo tanto, veremos la función de espacios de trabajo para cada administrador de paquetes.

espacios de trabajo sobre el nivel del mar

npm agregó una función de espacios de trabajo en v7, lanzada en octubre de 2020. La configuración de un proyecto de espacios de trabajo requiere solo unos pocos pasos y una package.jsonen su carpeta raíz que contiene una propiedad de espacios de trabajo que le dice a npm dónde encontrar sus espacios de trabajo.

// root package.json  
// ...
"workspaces": [
  "workspaces/a",
  "workspaces/b",
  "packages/*"
],
// ...

Este ejemplo muestra que puede enumerar explícitamente todos los paquetes ( workspaces/a, workspaces/b) o puede usar un glob ( packages/*). Cada paquete o espacio de trabajo, respectivamente, necesita su propio archivo package.json.

También puede automatizar estos pasos. Dentro de la carpeta raíz, simplemente ejecute el siguiente comando para crear un espacio de trabajo junto con la configuración requerida:

$ npm init -w ./packages/a-workspace

Esto crea la carpeta a-workspacedentro de la packagescarpeta. Además, se crea o actualiza una workspacespropiedad dentro de la carpeta raíz para que contenga archivos .package.jsona-workspace

Cuando se ejecuta npm ien la carpeta raíz, se instalan todas las dependencias de todos los paquetes. Esta es la estructura de carpetas de la rama de demostración de npm después de ejecutar install. En este ejemplo, hay tres espacios de trabajo ubicados en la packagescarpeta. La srccarpeta contiene la fuente de una aplicación React que usa los espacios de trabajo al hacer referencia a ellos en la raíz package.json.

.
├── node_modules/
│   ├── @doppelmutzi/
│   │   └── eslint-config/ # sym-link to packages/eslint-config
│   │   └── hooks/ # sym-link to packages/hooks
│   │   └── server/ # sym-link to packages/server
│   ├── # other (shared) dependencies
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── src/
├── package-lock.json
└── package.json

Como se describió anteriormente, npm eleva todas las dependencias a una node_modulescarpeta plana. En un proyecto de espacios de trabajo, esta node_modulescarpeta estaría ubicada en la carpeta raíz.

Pero en este ejemplo, todos los espacios de trabajo ( @doppelmutzi/eslint-config, @doppelmutzi/hooks, @doppelmutzi/server) se almacenan node_modules/@doppelmutzi/como enlaces simbólicos a las carpetas de origen ( packages/).

¿Qué sucede con las bibliotecas compartidas de terceros? Consideremos eso package.jsony hooks/package.jsonespecifiquemos la misma dependencia de React (17.0.2). El resultado se ve así:

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── package-lock.json
└── package.json

¿Qué pasa si añadimos react@17.0.1al serverpaquete?

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/
│   │   │   └── react/ # 17.0.1
│   │   └── package.json
├── package-lock.json
└── package.json

Esto demuestra cómo se almacenan las diferentes versiones de dependencia. Todavía hay un solo package-lock.jsonarchivo en la carpeta raíz.

npm v7 también introdujo los indicadores --workspaces(alias -ws) y --workspace(alias -w) que se pueden usar con muchos comandos CLI. Echemos un vistazo a algunos ejemplos.

// package.json of root folder
"scripts": {
  // ...
  "start-server": "npm run serve -w @doppelmutzi/server",
  "publish-eslint-config": "npm publish --workspace @doppelmutzi/eslint-config",
  "lint-packages": "npm run lint -ws --if-present",
  "lint-packages:parallel": "npm run lint -w @doppelmutzi/hooks & npm run lint -w @doppelmutzi/server"
}

El start-serverscript muestra cómo ejecutar un script dentro de un paquete desde la carpeta raíz de los espacios de trabajo:

npm run <script> -w <package-name>

package-namese refiere a la propiedad del archivo namedel paquete . package.jsonEl script publish-eslint-configdemuestra cómo ejecutar un comando npm en otro paquete que no está definido explícitamente en el package.jsonarchivo del paquete (es decir, un comando incorporado). lint-packageses un ejemplo de cómo ejecutar un script en todos los paquetes. Tenga en cuenta la --is-presentbandera que evita un error si un paquete no especifica el lintscript.

A diferencia de Yarn Berry, npm no admite la ejecución de scripts en paralelo con la -wsbandera. lint-packages:parallelmuestra una solución para lograr esto especificando cada paquete.

También puede instalar dependencias para un paquete con la -wbandera o para todos los paquetes con la -wsbandera:

$ npm i http-server -w @doppelmutzi/server
$ npm i ntl -ws

Una de las principales ventajas de monorepos es usar bibliotecas compartidas. Como ejemplo, la aplicación de demostración de React utiliza todos los espacios de trabajo especificando las dependencias en su archivo package.json.

// package.json
"dependencies": {
    "@doppelmutzi/eslint-config": "file:./packages/eslint-config",
    "@doppelmutzi/hooks": "file:./packages/hooks",
    "@doppelmutzi/server": "file:./packages/server",
    // ...
}

Espacios de trabajo de Yarn Berry

Un proyecto de espacios de trabajo de Yarn Berry se puede inicializar con yarn init -w. Crea una packagescarpeta, un .gitignore, y un package.json. contiene la package.jsonconfiguración de los espacios de trabajo que apunta a la packagescarpeta creada. Como ejemplo, con mkdir yarn-demo; cd yarn-demo; yarn init -w;lo siguiente package.jsonse genera.

{
  "name": "yarn-demo",
  "packageManager": "yarn@3.2.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Este nivel de raíz package.jsondebe ser privado y tener una workspacesmatriz que especifique dónde se ubican los espacios de trabajo. Puede especificar espacios de trabajo con el uso de globos (p. ej., packages/*) o explícitamente (p. ej., packages/hooks).

Echemos un vistazo a cómo se ve una estructura de proyecto típica después de ejecutar el yarncomando en la carpeta raíz de la rama del proyecto de demostración . Cada espacio de trabajo se encuentra en la packagescarpeta y alberga un archivo package.json.

.
├── .yarn/
│   ├── cache/
│   ├── plugins/
│   ├── releases/
│   ├── sdk/
│   └── unplugged/
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

El aspecto interesante es que solo hay un yarn.lockarchivo en el nivel raíz. Además, todas las dependencias, incluidas las de los espacios de trabajo, se almacenan en un .pnp.cjsarchivo y una .yarn/cache/carpeta, también ubicados en el nivel raíz.

Un espacio de trabajo es una carpeta que contiene un package.jsonsin requisitos especiales. Como verá a continuación, los complementos para mejorar el flujo de trabajo de los espacios de trabajo se almacenan en archivos .yarn/plugins/.

Yarn Berry proporciona un comando CLI, yarn workspace, para ejecutar comandos en el contexto de un espacio de trabajo. Como ejemplo, desde el nivel raíz puede agregar una dependencia de desarrollo al espacio de trabajo de Hooks:

$ yarn workspace @doppelmutzi/hooks add -D @babel/runtime

Después de instalar el workspace-toolscomplemento , puede utilizar el yarn workspace foreachcomando que le permite ejecutar un script en múltiples espacios de trabajo.

$ yarn plugin import workspace-tools
$ yarn workspaces foreach -p run lint

El foreachcomando anterior ejecuta el lintscript en cada espacio de trabajo con un script con este nombre. La -pbandera, abreviatura de --parallel, ejecuta todos los scripts en paralelo.

Una característica útil del yarn runcomando es que puede ejecutar secuencias de comandos que contengan dos puntos ( :) desde cada carpeta de su proyecto de espacios de trabajo. Considere un script con el nombre root:nameen la raíz package.jsonque imprime el nombre del paquete.

// root package.json
{
  // ...
  "scripts": {
    "root:name": "cat package.json | grep name"
  }
} 

No importa qué carpeta yarn root:namese ejecute, ejecuta el script con el mismo nombre de la carpeta raíz. Esta función se puede utilizar para definir algunos scripts "globales".

Si desea evitar que un paquete se resuelva desde un registro remoto desde uno de sus espacios de trabajo, debe usar el protocolo de resolución de espacios de trabajo . En lugar de usar valores de semver dentro de las propiedades de sus dependencias de desarrollo o package.jsonarchivos de dependencias, debe usar lo siguiente:

"dependencies": {
    "@doppelmutzi/eslint-config": "workspace:*"
}

Esto le dice a Yarn Berry que el paquete @doppelmutzi/eslint-configdebe resolverse desde un espacio de trabajo local que se encuentra en la packagescarpeta. Yarn Berry escanea todos los package.jsonarchivos en busca de una namepropiedad con el valor de @doppelmutzi/eslint-config.

Yarn Berry también admite la clonación de espacios de trabajo de cualquier proyecto a través del protocolo Git.

"dependencies": {
    "@doppelmutzi/eslint-config": "git@github.com:doppelmutzi/companion-project-mono-repo-2022.git#workspace=@doppelmutzi/eslint-config"
}    

En este ejemplo, recupero directamente el espacio @doppelmutzi/eslint-configde trabajo del repositorio de Git especificado que constituye un proyecto de espacios de trabajo de Yarn Berry.

Las restricciones son un mecanismo de bajo nivel para escribir reglas de espacio de trabajo que deben cumplirse. Es un poco como ESLint para package.json; por ejemplo, cada espacio de trabajo debe incluir un campo de licencia en su archivo package.json.

Para los desarrolladores de JavaScript, puede ser inusual definir estas restricciones porque las escribe con el lenguaje de programación lógica Prolog . Debe proporcionar un constraints.proarchivo en la carpeta raíz del proyecto.

% Ensure all workspaces are using packageManager field with version 3.2.0
gen_enforced_field(WorkspaceCwd, 'packageManager', 'yarn@3.2.0').

El ejemplo simple asegura que todos los espacios de trabajo tengan un packageManagercampo que aplique Yarn Berry v3.2.0 como administrador de paquetes. Como parte de un flujo de trabajo de CI/CD, puede ejecutar $ yarn constraintsy interrumpir la canalización si no se cumplen las restricciones.

espacios de trabajo pnpm

pnpm ha ofrecido soporte para espacios de trabajo desde el principio. Necesita un pnpm-workspace.yamlarchivo obligatorio en la carpeta raíz del proyecto para usar esta función.

# pnpm-workspace.yaml
packages:
  - 'packages/**'

Esta configuración de ejemplo le dice a pnpm que todos los espacios de trabajo están ubicados dentro de la packagescarpeta. Al ejecutarse pnpm ien la carpeta raíz, se instalan las dependencias definidas en la raíz package.json, así como todas las dependencias especificadas en los package.jsonarchivos de los espacios de trabajo. La siguiente estructura de carpetas de la rama pnpm Git del proyecto de demostración es el resultado del proceso de instalación.

.
├── node_modules/
│   ├── # dependencies defined in package.json
├── packages/
│   ├── eslint-config/
│   │   └── package.json # no dependencies defined
│   ├── hooks/
│   │   ├── node_modules/ # dependencies defined in hooks/package.json
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/ # dependencies defined in server/package.json
│   │   └── package.json
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

Como puede ver, solo hay un archivo de bloqueo ( pnpm-lock.yaml) pero varias node_modulescarpetas. A diferencia de los espacios de trabajo de npm, pnpm crea una node_modulescarpeta en cada espacio de trabajo, siempre que haya dependencias especificadas en el archivo package.json.

Para comparar la situación con la dependencia de React con espacios de trabajo de npm, como se describe en la sección anterior, react@17.0.2se instala en la carpeta raíz node_modulesy en el espacio de hookstrabajo porque esta dependencia se especifica en ambos package.jsonarchivos.

A diferencia de npm, las node_modulescarpetas no son planas. Como se describió anteriormente, debido al enfoque de almacenamiento direccionable por contenido, estas dependencias se instalan físicamente solo una vez en el disco duro en el almacén central.

La raíz package.jsonrevela que existen múltiples indicadores útiles y que se pueden usar en el contexto de los espacios de trabajo.

{
  // ...  
  "start-server": "pnpm serve --filter @doppelmutzi/server",
  "publish-eslint-config": "pnpm publish -F @doppelmutzi/eslint*",
  "lint-packages": "pnpm lint -r --parallel",
}

El indicador de filtro ( --filtero -F) restringe un comando a uno o más espacios de trabajo. El start-serverscript demuestra cómo ejecutar un script en un espacio de trabajo en particular ( @doppelmutzi/server). También puede usar un patrón ( *) para hacer coincidir los espacios de trabajo, como se muestra en el publish-eslint-configscript.

Con el indicador recursivo ( --recursiveo -r), puede ejecutar un comando recursivamente en todos los espacios de trabajo. El lint-packagesscript muestra un ejemplo con el comando de ejecución que ejecuta el lintscript en todos los espacios de trabajo.

A diferencia de npm, pnpm ignora todos los espacios de trabajo que no proporcionan dicho script. Con el indicador paralelo , el script se ejecuta simultáneamente.

pnpm admite un protocolo de espacio de trabajo ( workspace:) similar al de Yarn Berry para usar espacios de trabajo como dependencias en su monorepo. El uso de este protocolo evita que pnpm resuelva las dependencias del espacio de trabajo local desde un registro remoto. El extracto de la raíz package.jsondemuestra cómo usar este protocolo.

// package.json
{
  // ...
  dependencies: {
    "@doppelmutzi/eslint-config": "workspace:1.0.2",
    "@doppelmutzi/hooks": "workspace:*",
    "@doppelmutzi/server": "workspace:./packages/server",
  // ...
  }
}

El uso workspace:le dice a pnpm que desea instalar dependencias que constituyen espacios de trabajo locales. "@doppelmutzi/eslint-config": "workspace:1.0.2"instala el espacio de trabajo local @doppelmutzi/eslint-configporque su versión package.jsones 1.0.2. **Si intenta instalar otra versión, el proceso de instalación falla.

La versión en el espacio de trabajo no coincide

Lo más probable es que desee utilizar el estado actual de un espacio de trabajo tal como existe en su proyecto de espacios de trabajo. Por lo tanto, puede usar workspace:*como se demostró con la dependencia @doppelmutzi/hooks. @doppelmutzi/servermuestra que también puede hacer referencia a un espacio de trabajo con una ruta relativa. Tiene el mismo efecto que workspace:*.

Similar a Yarn Berry, también es posible hacer referencia a espacios de trabajo desde un monorepo remoto con pnpm add.

Comandos CLI relacionados con el espacio de trabajo

Las siguientes tablas comparan un conjunto seleccionado de diferentes comandos CLI disponibles en npm, Yarn Berry y pnpm en el contexto de los espacios de trabajo. Esta no es una lista completa, pero constituye una hoja de trucos. Las siguientes tablas completan los comandos de mi último artículo con ejemplos relacionados con el espacio de trabajo.

Gestión de dependencias

Esta tabla cubre los comandos de administración de dependencias para instalar o actualizar todas las dependencias especificadas en package.json, o múltiples dependencias especificándolas en los comandos. Todos los comandos se pueden ejecutar en el contexto de uno o más espacios de trabajo. y todos los comandos se ejecutan desde la carpeta raíz del proyecto de espacios de trabajo.

Acciónsobre el nivel del marBaya de hilopnpm
instalar deps de todos los espacios de trabajo
  • npm install
  • alias:i
  • yarn install
  • alias:yarn
  • pnpm install
  • alias:i
instalar dependencias de un solo espacio de trabajo
  • npm i --workspace server
  • alias:-w
  • pnpm i --filter server
  • alias:-F
Agregar dependencias de nivel raíz
  • npm i eslint
  • yarn add eslint
  • pnpm i eslint
Agregar dependencias al espacio de trabajo
  • npm i -D react -w hooks
  • yarn workspace hooks add -D react
  • pnpm i -D -F hooks react
  • pnpm add -D -F hooks react
Agregar dependencia del espacio de trabajo al espacio de trabajo
  • N / A
  • yarn workspace app add hooks@'workspace:*'
  • pnpm i -F app hooks@'workspace:*'
actualizar todas las dependencias del espacio de trabajo
  • npm update -w hooks
  • yarn workspace hooks up
  • pnpm up -F hooks
  • pnpm up --latest -F hooks
  • alias:-L
actualizar la dependencia del espacio de trabajo
  • npm update react -w hooks
  • yarn workspace hooks up react
  • pnpm up -F hooks react
  • pnpm up -L -F hooks react
Eliminar dependencias del espacio de trabajo
  • npm uninstall react -w hooks
  • yarn workspace hooks remove react
  • pnpm remove --filter hooks react

Ejecución de guiones

Esta tabla muestra comandos para ejecutar scripts en uno o varios espacios de trabajo.

Acciónsobre el nivel del marBaya de hilopnpm
ejecutar script en un espacio de trabajo
  • npm run build -w hooks
  • yarn workspace hooks build
  • pnpm run build -F hooks
  • pnpm build -F hooks
ejecutar script en múltiples espacios de trabajo
  • npm run lint -w server -w hooks
  • N / A
  • solución alterna:yarn workspace hooks lint && yarn workspace server lint
  • pnpm -F server -F hooks lint
ejecutar secuencias de comandos en todos los espacios de trabajo secuencialmente
  • npm run lint --workspaces
  • alias:-ws
  • pnpm run --recursive lint
  • alias:-r
ejecutar script en todos los espacios de trabajo secuencialmente si está disponible
  • npm run lint -ws --if-present
  • yarn workspaces foreach run lint
  • pnpm run -r lint
ejecutar script en todos los espacios de trabajo en paralelo
  • N / A
  • solución alterna:npm run lint -w p1 & npm run lint -w p2
  • yarn workspaces foreach --parallel run lint
  • alias:-p
  • pnpm run -r lint --parallel

Varios

Esta tabla cubre útiles comandos incorporados. Si no hay un comando oficial, a menudo se puede usar un comando de terceros para lograr cosas similares, a través de un paquete npm o un complemento de Yarn Berry.

 sobre el nivel del marBaya de hilopnpm
proyecto de espacios de trabajo init
  • npm init -w ./packages/server(crea la configuración junto con el espacio de trabajo especificado)
  • yarn init --workspace
  • alias:

-w

  • N / A
espacio de trabajo de inicio
  • npm init -w ./packages/server
  • N / A
  • N / A
enumerar espacios de trabajo
  • N / A
  • yarn workspaces list
  • yarn workspaces list --json
  • N / A
Comprobar las restricciones del espacio de trabajo
  • N / A
  • N / A

Qué significan todas estas innovaciones para el futuro

Los proyectos frontend son cada vez más complejos; se requieren más y más dependencias para construirlos. El proceso de instalación, especialmente para monorepos, requiere mucho tiempo y en parte es propenso a errores. El estado actual de los administradores de paquetes ha solucionado muchos problemas, pero todavía hay espacio para mejoras.

tnpm , por ejemplo, es un servicio empresarial de Alibaba que parece haber subido el listón para los administradores de paquetes en el entorno empresarial cerrado. Su estrategia de resolución de dependencias reduce las solicitudes HTTP, en comparación con los administradores de paquetes descritos anteriormente.

Además, el gráfico de dependencia de tnpm se genera en el servidor, en conexión con una estrategia de almacenamiento en caché de varios niveles. Actualmente, esto es difícil de lograr con una solución no empresarial como npm, pnpm o Yarn, pero ciertamente establece el estándar de lo que es posible.

tnpm demuestra que todavía hay potencial de mejora en el espacio del administrador de paquetes. Fuente: tnpm en Dev.to

Los administradores de paquetes públicos todavía están investigando de forma independiente formas de mejorar el rendimiento y abordar los puntos débiles conocidos (por ejemplo, el almacenamiento de dependencia ineficiente, que discutimos aquí). Incluso npm está trabajando en un "modo aislado" que creará enlaces simbólicos node_modules, inspirados en pnpm. Con este cambio, npm se ha referido a su actual estrategia de resolución a largo plazo como "modo elevado".

pnpm también está realizando investigaciones con FUSE para proporcionar una alternativa al modo PnP de Yarn Berry, que parece prometedor (y probablemente también explique por qué casi no puede encontrar información sobre pnpm PnP en línea en este momento).

En última instancia, no se puede elogiar más lo bien que trabajan juntos los administradores de paquetes en términos de inspirarse mutuamente y compartir conocimientos. Puede ver esto en muchos lugares, como la sección de comentarios de este artículo en tnpm .

Conclusión

Parece que habrá múltiples administradores de paquetes en el futuro. Es posible que no quieran tener conjuntos de características y conceptos iguales para abordar mejor la miríada de problemas que enfrentan los diferentes usuarios.

Por un lado, esto es maravilloso porque significa que habrá opciones para elegir el flujo de trabajo óptimo para un proyecto. Tampoco hay nada que nos impida usar diferentes administradores de paquetes en un entorno de equipo para diferentes proyectos, ya que se basan en conceptos similares.

Por otro lado, cada vez es más difícil para los proveedores de bibliotecas admitir todos estos administradores de paquetes y sus respectivas diferencias. Como ejemplo, en mi proyecto actual no puedo usar Yarn Berry porque una herramienta establecida no admite su formato de archivo de bloqueo. Queda por ver si se superará o no el apoyo a estas diferencias.

Fuente: https://blog.logrocket.com/exploring-workspaces-other-advanced-package-manager-features/ 

 #packaging  #workspace #pnpm #npm 

What is GEEK

Buddha Community

Cómo Yarn Y Pnpm Han Centrado Sus Esfuerzos Más De Cerca

Cómo Yarn Y Pnpm Han Centrado Sus Esfuerzos Más De Cerca

Este artículo tiene como objetivo dejarle una impresión de hacia dónde se dirigen los administradores de paquetes en el futuro para satisfacer las necesidades de los desarrolladores, por ejemplo, permitiéndoles administrar grandes proyectos monorepo con un rendimiento adecuado y un buen DX.

Escribí en un artículo anterior sobre el tema de las estrategias de resolución de dependencias entre npm, Yarn y pnpm. Si bien el enfoque en el artículo anterior fue comparar conceptos y estructuras centrales, este artículo cubrirá las características avanzadas de los administradores de paquetes modernos, incluidos los monorepos, a través de espacios de trabajo.

El objetivo de este artículo es transmitir cómo Yarn y pnpm han centrado sus esfuerzos más de cerca en permitir a los desarrolladores crear monorepos a través de espacios de trabajo y proporcionar enfoques más avanzados para mejorar la seguridad y el rendimiento. 

Proyectos complementarios

Este artículo cubre varias características del administrador de paquetes. Por lo tanto, creé dos proyectos complementarios en GitHub para brindar ejemplos:

  1. Un proyecto monorepo para demostrar las características del espacio de trabajo
  2. Un proyecto separado para demostrar diferentes estrategias de resolución de dependencia

Estrategias alternativas de resolución de dependencia

Cuando se usa la configuración predeterminada, pnpm y Yarn Berry no usan los mismos algoritmos de resolución de dependencias que npm y Yarn Classic, lo que implica aplanar node_modulescarpetas. Estos administradores de paquetes modernos intentan separarse de los enfoques tradicionales para procesar y almacenar dependencias.

La razón de esto es que se requieren enfoques de resolución innovadores para hacer frente a los requisitos de los proyectos de software modernos, que utilizan cada vez más grandes cantidades de dependencias. Las estrategias tradicionales han llegado a sus límites en términos de rendimiento y eficiencia del espacio en disco.

El problema con el enfoque tradicionalnode_modules

La estrategia tradicional de resolución de dependencias para aplanar node_modulescarpetas genera varios problemas diferentes :

  • Los módulos pueden (accidentalmente) acceder a paquetes de los que no dependen, lo que puede generar errores
  • El algoritmo de aplanamiento es un proceso de E/S que requiere mucho tiempo.

El problema raíz de este diseño plano node_moduleses un concepto llamado elevación , que fue introducido por npm en v3 . Este mismo algoritmo de resolución de dependencia también fue utilizado por Yarn Classic al principio.

En pocas palabras, la elevación aplana la node_modulescarpeta de tal manera que todas las dependencias, incluso las dependencias de dependencias, terminan en el nivel raíz de node_modules. La razón para subir todo a un nivel de carpeta es reducir la redundancia que provoca el anidamiento. La siguiente imagen muestra cómo funciona esto:

 

Las diferencias entre los algoritmos node_module de npm v2 y npm v3

La elevación puede provocar errores graves y difíciles de detectar, especialmente en proyectos grandes. Jonathan Creamer brinda una visión detallada de lo que puede salir mal en un proyecto monorepo donde el algoritmo de elevación falla y provoca errores de producción. En tales situaciones, el levantamiento puede conducir a dependencias fantasmas y doppelgangers .

El enfoque Plug'n'Play de Yarn Berry

Yarn Berry trató de deshacerse por node_modulescompleto, utilizando un enfoque Plug'n'Play . Puede leer acerca de la motivación de Yarn Berry para deshacerse de node_modules, pero las razones son similares a las de pnpm.

PnP es una estrategia de instalación nueva e innovadora para Node, desarrollada en contraste con el requireflujo de trabajo establecido (y único) Common, js que aborda muchas de sus ineficiencias. A diferencia de la forma tradicional, Yarn Berry invierte la responsabilidad en quién encuentra los paquetes.

Anteriormente, Node tenía que encontrar sus paquetes dentro de las node_modulescarpetas. Yarn Berry en modo PnP ya tiene toda la información que necesita a mano y, en cambio, le dice a Node dónde encontrarla. Esto reduce drásticamente el tiempo de instalación del paquete.

Yarn Berry logra esto generando un archivo en lugar de una carpeta .pnp.cjsanidada . node_modulesContiene tablas de búsqueda para informar a Node sobre las ubicaciones de dependencia. Como uno de los beneficios, Yarn Berry puede asegurarse de compartir solo las ubicaciones de los paquetes que ha definido en uno de sus package.jsonarchivos, lo que mejora la seguridad y reduce los errores: ya no tiene que preocuparse por los duplicados, las dependencias fantasmas o otros tipos de acceso ilegal.

Sin embargo, los principales beneficios son velocidades de instalación más rápidas; solo estamos procesando un archivo, nuestro .pnp.cjsarchivo, por lo que tenemos menos operaciones de E/S. Los tiempos de inicio también se pueden mejorar porque el algoritmo de resolución de Node tiene que hacer menos trabajo.

Pero si no hay ninguna node_modulescarpeta, ¿dónde se almacenan los paquetes? Cada paquete se almacena como un archivo zip dentro de una .yarn/cache/carpeta. Esto funciona porque Yarn Berry mono parchea la API del sistema de archivos de Node de tal manera que las solicitudes de dependencias internas node_modulesdeben resolverse a partir del contenido de los archivos comprimidos dentro de la memoria caché. Estos archivos zip ocupan menos espacio en disco que la node_modulescarpeta.

PnP es el modo predeterminado de Yarn Berry, pero también puede habilitarlo explícitamente dentro de .yarnrc.yml.

# .yarnrc.yml
# alternatively, remove the next two lines, PnP strict is the default
nodeLinker: "pnp"
pnpMode: "strict"

La estructura típica de un proyecto PnP se parece a la siguiente. No hay node_modulescarpetas; las dependencias se almacenan en archivos zip en formato .yarn/cache/.

.
├── .yarn/
│   ├── cache/
│   ├── releases/
│   │   └── yarn-3.1.1.cjs
│   ├── sdk/
│   └── unplugged/
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

Problemas de depuración con dependencias en Yarn Berry PnP

Para depurar problemas con las dependencias, necesita compatibilidad con herramientas adicionales (p. ej., la extensión VS Code ), ya que debe "mirar dentro" de los archivos zip. Al momento de escribir, debe realizar pasos manuales agregando compatibilidad con SDK del editor porque dicha funcionalidad no está incorporada. El siguiente comando agrega soporte para VS Code :

$ yarn dlx @yarnpkg/sdks vscode

La CLI del SDK analiza su raíz package.jsonen busca de tecnologías compatibles y genera archivos de configuración que se almacenan en formato .yarn/sdk/.

Cambios de archivo de la CLI del SDK

En el caso de nuestro proyecto de demostración, detecta ESLint y Prettier . Consulte la rama de Git yarn-berry-pnppara ver un ejemplo de compatibilidad con PnP y SDK.

Estrategia de instalación cero de Yarn Berry

Lo bueno de PnP es que puede poner el .pnp.cjsarchivo y la .yarn/cache/carpeta bajo control de versión debido a sus tamaños de archivo justificables. Lo que obtienes de esto es una estrategia de instalación cero . Si su compañero de equipo extrae su código de Git, lo que puede llevar un poco más de tiempo usando esta estrategia, todos los paquetes y tablas de búsqueda estarán disponibles y no se requiere ningún paso de instalación antes de iniciar la aplicación. Eche un vistazo a un breve video de demostración que muestra la instalación cero en acción.

Puede ver cómo el .gitignorearchivo se parece a la rama de instalación cero de Yarn Berry PnP . Si agrega, actualiza o elimina dependencias, debe ejecutar yarn install, por supuesto, para actualizar yarn.lock, .pnp.cjsy las .yarn/cache/carpetas.

Optar por no participar en PnP: modo suelto

PnP es restrictivo y es posible que no funcione con algunos paquetes incompatibles (p. ej., React Native). Además, la migración a PnP podría no ser un camino fácil; por lo tanto, Yarn Berry proporciona un modo suelto . Puede activarlo .yarnrc.ymlconfigurando la nodeLinkerpropiedad en consecuencia.

# .yarnrc.yml
nodeLinker: "pnp"
pnpMode: "loose"

El modo suelto es un compromiso entre el modo estricto PnP y el node_modulesmecanismo tradicional de resolución de dependencias. La diferencia es que Yarn Berry solo advierte sobre el acceso de dependencia inseguro, en lugar de abortar con errores.

Debajo del capó, Yarn Berry realiza el algoritmo de elevación tradicional y lo usa como respaldo para cada dependencia no especificada. Esto todavía se considera inseguro según los estándares de Yarn Berry, pero puede ahorrar algo de tiempo: podrá analizar mejor las advertencias que recibe, solucionar sus problemas de raíz y volver a PnP estricto nuevamente rápidamente, si es necesario.

Es posible que desee cambiar a Yarn Berry porque Yarn Classic se considera heredado y, aunque se beneficia de algunas mejoras, se mantiene en el node_modulesmodo de instalación tradicional con node-modules nodeLinker.

# .yarnrc.yml
nodeLinker: "node-modules"

Con esto, la buena vieja node_modulescarpeta se vuelve a generar.

El equipo de Yarn Berry también se inspiró en la estrategia de almacenamiento direccionable por contenido de pnpm, que analizaremos a continuación, y agregó un modo con el mismo nombre. Es similar a su arquetipo y tiene como objetivo almacenar dependencias solo una vez, en su disco duro.

# .yarnrc.yml
nodeLinker: "pnpm"

Siéntase libre de probar los diferentes modos revisando las ramas de Git correspondientes de mi proyecto de demostración:

estrategia optimizada de pnpmnode_modules

pnpm almacena las dependencias en una node_modulescarpeta anidada, como npm, pero proporciona un mejor rendimiento y eficiencia del espacio en disco debido a su implementación de almacenamiento direccionable por contenido . Puede leer más sobre esto en mi artículo anterior sobre administradores de paquetes.

La estrategia Plug'n'Play de pnpm

Desde finales de 2020, pnpm v5.9 también es compatible con PnP e incluso se refiere a él como Plug'n'Play de Yarn . La documentación sobre esta función es escasa; El desarrollador principal de pnpm hace referencia a los documentos de Yarn Berry .

La rama pnpm PnP muestra cómo usar este modo. Tienes que activar el modo PnP en .npmrc.

# .npmrc
node-linker=pnp
symlink=false

Después de ejecutar pnpm i, la estructura del proyecto se ve así.

.
├── node_modules/
│   ├── .bin/
│   └── .pnpm/
├── .npmrc
├── .pnp.cjs
├── package.json
└── pnpm-lock.yaml

Consecuencias de los enfoques sin elevación

pnpm y Yarn Berry consideran que izar es una mala práctica. Como ya se mencionó, muchos proyectos en el ecosistema de JavaScript han basado sus implementaciones de elevación en la utilizada por npm y versiones anteriores de Yarn. Esta sección destaca algunos problemas que vienen con el enfoque sin elevación.

Con la rama de demostración de pnpm , tuve un problema al ejecutar un binario, ntl. No funcionaba debido al diseño no plano de pnpm node_modules, lo que me llevó a una discusión con el desarrollador principal de pnpm sobre un problema similar y me señaló la solución para hoistntl .

# .npmrc
hoist-pattern[]=*ntl*

Con el enfoque PnP de Yarn Berry, lo más probable es que te encuentres con situaciones similares. Durante el desarrollo de la rama de demostración de PnP , recibí este error al iniciar.

Error estricto de PnP al iniciar

En el seguimiento de la pila, descubrí que no react-isse encontró un paquete llamado en tiempo de ejecución. El mensaje de error en el lado izquierdo de la captura de pantalla anterior indica que esto tiene que ver con el styled-componentspaquete que especifiqué en mi archivo package.json. Parece que styled-componentsno enumera todas sus dependencias en su package.json archivo .

Hay una solución típica para tal problema PnP: la packageExtensionspropiedad . Actualizar .yarnrc.ymly ejecutar un adicional yarn installpara instalar la dependencia faltante soluciona el problema:

# .yarnrc.yml
packageExtensions:
  "styled-components@*":
    dependencies:
      react-is: "*"

Como se describió anteriormente, también puede cambiar a un enfoque de Yarn Berry menos restrictivo si está bien renunciar a los beneficios de seguridad de PnP en su proyecto.

pnpm PnP funciona de manera similar a la variante Yarn Berry y, como tal, también debe lidiar con su naturaleza más estricta. Debe especificar las dependencias que faltan en el package.json, como puede ver en la rama pnpm PnP .

// package.json
{
  "name": "package-manager-playground",
  "version": "1.0.0",
  "packageManager": "pnpm@6.24.4",
  "pnpm": {
    "packageExtensions": {
      "styled-components": {
        "dependencies": {
          "react-is": "*"
        }
      },
      "autoprefixer": {
        "dependencies": {
          "postcss": "*"
        }
      }
    }
  },
  // ...
}

Gestión de versiones mejorada

Trabajar en múltiples proyectos puede requerir diferentes versiones de Node o su administrador de paquetes. Por ejemplo, mi proyecto React Native usa Yarn Classic, pero para mi proyecto React, quiero usar una versión más reciente de Yarn Berry.

Un administrador de paquetes debería facilitar el cambio entre versiones. También debe contar con mecanismos que le permitan aplicar ciertas versiones de un administrador de paquetes, idealmente de forma automática. Esto reduce los errores causados ​​por el uso de diferentes versiones del administrador de paquetes. Como verá en un minuto, Yarn Berry es actualmente el único administrador de paquetes que ofrece una función para cambiar automáticamente a una versión en particular.

sobre el nivel del mar

La forma más fácil de cambiar una versión de Node que viene con una versión integrada de npm es usar nvm . Luego, también puede actualizar npm a la versión más reciente. Aquí hay unos ejemplos.

    $ nvm use 17.40
    $ npm -v # 8.1.2
    $ nvm install-latest-npm
    $ npm -v # 8.3.2

pnpm

pnpm proporciona su propia herramienta para administrar las versiones de Node: el pnpm envcomando agregado recientemente . Sirve como alternativa a herramientas como Volta o el mencionado nvm. Puede cambiar las versiones de Node y luego instalar versiones particulares de pnpm, ya sea con la ayuda de npm o Corepack . Aquí hay un ejemplo que aprovecha Corepack:

$ pnpm env use --global lts
$ node -v # 16.13.2
$ pnpm -v # 6.24.2
$ corepack prepare pnpm@6.25.1 --activate
$ pnpm -v # 6.25.1

Baya de hilo

Una característica poderosa de Yarn Berry, especialmente para equipos profesionales, es incluir una versión particular de Yarn Berry con su proyecto. Cuando se ejecuta en la raíz de su proyecto, el comando yarn set versionagrega la versión descargada .yarn/releases/y se actualiza .yarnrc.ymlpara establecer la versión actual con la yarnPathpropiedad .

# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs

Con esta configuración, su binario instalado localmente yarndifiere la ejecución a la versión binaria ubicada en yarnPath. Si confirma esta configuración, junto con la .yarn/releasescarpeta, todos los compañeros de equipo usarán automáticamente la misma versión del yarnbinario. Esto lleva a que la instalación de dependencia determinista se ejecute en todos los sistemas, no más problemas de "ejecuciones en mi máquina".

La siguiente demostración muestra cómo esta versión se usa automáticamente después de verificar el código de Git.

yarn set versionen acción

Si usa Corepack, el comando también agrega la yarnversión binaria instalada a la packageManagerpropiedad en su package.jsonarchivo.

La packageManagerpropiedad se agrega a nuestro package.jsonarchivo.

Esto se puede usar como una "capa" adicional en la parte superior de la yarnPathconfiguración para asegurarse de que sus compañeros desarrolladores usen el administrador de paquetes correcto.

El error de uso de Corepack que se activa con una versión diferente del administrador de paquetes

Corepack sigue siendo una tecnología completamente nueva y todos los desarrolladores deben optar por usarla. Por lo tanto, no se puede garantizar de manera confiable que todos los desarrolladores usen el mismo administrador de paquetes con la misma versión.

En general, Yarn Berry's yarn set versiones un método sólido para aplicar la yarnversión binaria correcta en todo su equipo. Este mecanismo es superior a los mecanismos de otros administradores de paquetes.

Estrategias avanzadas de instalación de CI/CD

Esta sección se centra en las características adicionales del flujo de trabajo de instalación que son especialmente útiles en contextos de CI/CD. Muchos proyectos de desarrollo requieren estrategias eficientes para reducir el tiempo de procesamiento de las ejecuciones de canalización, como las estrategias de almacenamiento en caché.

sobre el nivel del mar

npm cies un comando similar a npm install, pero package-lock.jsondebe existir un archivo. Funciona tirando el tuyo node_modulesy recreándolo desde cero.

cisignifica "integración continua" y está destinado a ser utilizado en entornos CI/CD. Al ejecutar , no se actualizará $ npm ciuna preexistente , pero la carpeta se eliminará y se volverá a crear. En contraste con , este enfoque generalmente conduce a mejoras en la velocidad y ejecuciones de canalización más confiables porque un desarrollador envía al control de versiones exactamente las mismas versiones de dependencia definidas.package-lock.jsonnode_modulesnpm installpackage-lock.json

Además, npm instala paquetes en un caché local para aumentar la velocidad de reinstalación. Esto permite instalaciones fuera de línea debido a la resolución de paquetes fuera de línea , por ejemplo, usando un comando como $ npm i --prefer-offlinesi no tuviera conexión a Internet o si tuviera una conexión inestable. Si desea limpiar el caché, puede usar $ npm cache clean.

Baya de hilo

No existe una contrapartida de Yarn Berry npm cipara instalar dependencias en un contexto de CI/CD, pero puede hacer cosas similares con yarn install --frozen-lockfile.

Yarn Berry tiene una función avanzada de caché fuera de línea . Almacena en caché cada paquete como un único archivo zip en su .yarn/cache/carpeta. La ubicación de la carpeta de caché predeterminada se puede cambiar con la cacheFolderpropiedad .

# .yarnrc.yml
cacheFolder: "./berry-cache"

Puede limpiar el caché con los siguientes comandos.

# manual clean is optional
$ yarn cache clean
# global mirror needs to be cleaned manually
$ yarn cache clean --mirror

De forma predeterminada, Yarn Berry crea una carpeta de caché para cada proyecto. Si desea compartir el caché con varios proyectos, puede usar un caché global en su lugar usando la enableGlobalCachepropiedad . Cada proyecto con esta misma configuración comparte el caché global.

# .yarnrc.yml
enableGlobalCache: true

pnpm

Sin conexión a Internet, los paquetes se instalan desde la tienda. También puede decirle explícitamente a pnpm que recupere todos los paquetes de la tienda con $ pnpm i --offline. Si uno o más paquetes no son parte de la tienda, obtiene un error.

No hay un comando como npm ci, pero según sus mantenedores, pnpm funciona bien en un contexto de CI/CD .

Acceso a registros privados

Cada administrador de paquetes funciona de forma inmediata con el registro público de npm . En el contexto de una empresa con bibliotecas compartidas, lo más probable es que desee reutilizar paquetes sin publicarlos públicamente. Ahí es donde entran en juego los registros privados.

sobre el nivel del mar

La siguiente configuración es parte del .npmrcarchivo ubicado en la carpeta raíz del proyecto. Indica cómo acceder a un registro privado de GitLab .

# .npmrc
@doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/<project-id>/packages/npm/

Los datos confidenciales van al .npmrcarchivo ubicado fuera del proyecto.

# ~/.npmrc
//gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

pnpm

pnpm usa el mismo mecanismo de configuración que npm , por lo que puede almacenar su configuración en un .npmrcarchivo. La configuración de un registro privado funciona de la misma manera que con npm.

Baya de hilo

La configuración de registros privados es similar a npm, pero la sintaxis difiere porque la configuración se almacena en un archivo YAML.

# .yarnrc.yml
npmScopes:
  doppelmutzi:
    npmRegistryServer: 'https://gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/'

Nuevamente, su token de autenticación debe almacenarse fuera de su proyecto.

# ~/.yarnrc.yml
npmRegistries:
  //gitlab.doppelmutzi.com/api/v4/projects/123/packages/npm/:
    npmAlwaysAuth: true
    npmAuthToken: "<my-token>"

Agregar soporte monorepo con espacios de trabajo

Un monorepo es un repositorio de Git que alberga múltiples proyectos. Google gestiona la mayoría de sus proyectos en un monorepo desde hace bastante tiempo. Algunos beneficios incluyen:

  • Refactorización a gran escala
  • reutilización de código
  • Gestión de dependencia simplificada

Los administradores de paquetes modernos admiten monorepos a través de una característica llamada espacios de trabajo. En dichos proyectos, cada espacio de trabajo constituye un subproyecto y contiene un package.jsonque define su propio árbol de dependencia. Los conceptos detrás de cada implementación son bastante similares para todos los representantes: la CLI simplifica la administración de dependencias del monorepo, y los administradores de paquetes pueden incluso encargarse de las dependencias compartidas entre espacios de trabajo para mejorar la eficiencia del almacenamiento de su sistema de archivos.

Pero hay diferencias en los detalles y, por lo tanto, veremos la función de espacios de trabajo para cada administrador de paquetes.

espacios de trabajo sobre el nivel del mar

npm agregó una función de espacios de trabajo en v7, lanzada en octubre de 2020. La configuración de un proyecto de espacios de trabajo requiere solo unos pocos pasos y una package.jsonen su carpeta raíz que contiene una propiedad de espacios de trabajo que le dice a npm dónde encontrar sus espacios de trabajo.

// root package.json  
// ...
"workspaces": [
  "workspaces/a",
  "workspaces/b",
  "packages/*"
],
// ...

Este ejemplo muestra que puede enumerar explícitamente todos los paquetes ( workspaces/a, workspaces/b) o puede usar un glob ( packages/*). Cada paquete o espacio de trabajo, respectivamente, necesita su propio archivo package.json.

También puede automatizar estos pasos. Dentro de la carpeta raíz, simplemente ejecute el siguiente comando para crear un espacio de trabajo junto con la configuración requerida:

$ npm init -w ./packages/a-workspace

Esto crea la carpeta a-workspacedentro de la packagescarpeta. Además, se crea o actualiza una workspacespropiedad dentro de la carpeta raíz para que contenga archivos .package.jsona-workspace

Cuando se ejecuta npm ien la carpeta raíz, se instalan todas las dependencias de todos los paquetes. Esta es la estructura de carpetas de la rama de demostración de npm después de ejecutar install. En este ejemplo, hay tres espacios de trabajo ubicados en la packagescarpeta. La srccarpeta contiene la fuente de una aplicación React que usa los espacios de trabajo al hacer referencia a ellos en la raíz package.json.

.
├── node_modules/
│   ├── @doppelmutzi/
│   │   └── eslint-config/ # sym-link to packages/eslint-config
│   │   └── hooks/ # sym-link to packages/hooks
│   │   └── server/ # sym-link to packages/server
│   ├── # other (shared) dependencies
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── src/
├── package-lock.json
└── package.json

Como se describió anteriormente, npm eleva todas las dependencias a una node_modulescarpeta plana. En un proyecto de espacios de trabajo, esta node_modulescarpeta estaría ubicada en la carpeta raíz.

Pero en este ejemplo, todos los espacios de trabajo ( @doppelmutzi/eslint-config, @doppelmutzi/hooks, @doppelmutzi/server) se almacenan node_modules/@doppelmutzi/como enlaces simbólicos a las carpetas de origen ( packages/).

¿Qué sucede con las bibliotecas compartidas de terceros? Consideremos eso package.jsony hooks/package.jsonespecifiquemos la misma dependencia de React (17.0.2). El resultado se ve así:

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── package-lock.json
└── package.json

¿Qué pasa si añadimos react@17.0.1al serverpaquete?

.
├── node_modules/
│   ├── # other (shared) dependencies
│   ├── react/ # 17.0.2 
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/
│   │   │   └── react/ # 17.0.1
│   │   └── package.json
├── package-lock.json
└── package.json

Esto demuestra cómo se almacenan las diferentes versiones de dependencia. Todavía hay un solo package-lock.jsonarchivo en la carpeta raíz.

npm v7 también introdujo los indicadores --workspaces(alias -ws) y --workspace(alias -w) que se pueden usar con muchos comandos CLI. Echemos un vistazo a algunos ejemplos.

// package.json of root folder
"scripts": {
  // ...
  "start-server": "npm run serve -w @doppelmutzi/server",
  "publish-eslint-config": "npm publish --workspace @doppelmutzi/eslint-config",
  "lint-packages": "npm run lint -ws --if-present",
  "lint-packages:parallel": "npm run lint -w @doppelmutzi/hooks & npm run lint -w @doppelmutzi/server"
}

El start-serverscript muestra cómo ejecutar un script dentro de un paquete desde la carpeta raíz de los espacios de trabajo:

npm run <script> -w <package-name>

package-namese refiere a la propiedad del archivo namedel paquete . package.jsonEl script publish-eslint-configdemuestra cómo ejecutar un comando npm en otro paquete que no está definido explícitamente en el package.jsonarchivo del paquete (es decir, un comando incorporado). lint-packageses un ejemplo de cómo ejecutar un script en todos los paquetes. Tenga en cuenta la --is-presentbandera que evita un error si un paquete no especifica el lintscript.

A diferencia de Yarn Berry, npm no admite la ejecución de scripts en paralelo con la -wsbandera. lint-packages:parallelmuestra una solución para lograr esto especificando cada paquete.

También puede instalar dependencias para un paquete con la -wbandera o para todos los paquetes con la -wsbandera:

$ npm i http-server -w @doppelmutzi/server
$ npm i ntl -ws

Una de las principales ventajas de monorepos es usar bibliotecas compartidas. Como ejemplo, la aplicación de demostración de React utiliza todos los espacios de trabajo especificando las dependencias en su archivo package.json.

// package.json
"dependencies": {
    "@doppelmutzi/eslint-config": "file:./packages/eslint-config",
    "@doppelmutzi/hooks": "file:./packages/hooks",
    "@doppelmutzi/server": "file:./packages/server",
    // ...
}

Espacios de trabajo de Yarn Berry

Un proyecto de espacios de trabajo de Yarn Berry se puede inicializar con yarn init -w. Crea una packagescarpeta, un .gitignore, y un package.json. contiene la package.jsonconfiguración de los espacios de trabajo que apunta a la packagescarpeta creada. Como ejemplo, con mkdir yarn-demo; cd yarn-demo; yarn init -w;lo siguiente package.jsonse genera.

{
  "name": "yarn-demo",
  "packageManager": "yarn@3.2.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Este nivel de raíz package.jsondebe ser privado y tener una workspacesmatriz que especifique dónde se ubican los espacios de trabajo. Puede especificar espacios de trabajo con el uso de globos (p. ej., packages/*) o explícitamente (p. ej., packages/hooks).

Echemos un vistazo a cómo se ve una estructura de proyecto típica después de ejecutar el yarncomando en la carpeta raíz de la rama del proyecto de demostración . Cada espacio de trabajo se encuentra en la packagescarpeta y alberga un archivo package.json.

.
├── .yarn/
│   ├── cache/
│   ├── plugins/
│   ├── releases/
│   ├── sdk/
│   └── unplugged/
├── packages/
│   ├── eslint-config/
│   │   └── package.json
│   ├── hooks/
│   │   └── package.json
│   ├── server/
│   │   └── package.json
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

El aspecto interesante es que solo hay un yarn.lockarchivo en el nivel raíz. Además, todas las dependencias, incluidas las de los espacios de trabajo, se almacenan en un .pnp.cjsarchivo y una .yarn/cache/carpeta, también ubicados en el nivel raíz.

Un espacio de trabajo es una carpeta que contiene un package.jsonsin requisitos especiales. Como verá a continuación, los complementos para mejorar el flujo de trabajo de los espacios de trabajo se almacenan en archivos .yarn/plugins/.

Yarn Berry proporciona un comando CLI, yarn workspace, para ejecutar comandos en el contexto de un espacio de trabajo. Como ejemplo, desde el nivel raíz puede agregar una dependencia de desarrollo al espacio de trabajo de Hooks:

$ yarn workspace @doppelmutzi/hooks add -D @babel/runtime

Después de instalar el workspace-toolscomplemento , puede utilizar el yarn workspace foreachcomando que le permite ejecutar un script en múltiples espacios de trabajo.

$ yarn plugin import workspace-tools
$ yarn workspaces foreach -p run lint

El foreachcomando anterior ejecuta el lintscript en cada espacio de trabajo con un script con este nombre. La -pbandera, abreviatura de --parallel, ejecuta todos los scripts en paralelo.

Una característica útil del yarn runcomando es que puede ejecutar secuencias de comandos que contengan dos puntos ( :) desde cada carpeta de su proyecto de espacios de trabajo. Considere un script con el nombre root:nameen la raíz package.jsonque imprime el nombre del paquete.

// root package.json
{
  // ...
  "scripts": {
    "root:name": "cat package.json | grep name"
  }
} 

No importa qué carpeta yarn root:namese ejecute, ejecuta el script con el mismo nombre de la carpeta raíz. Esta función se puede utilizar para definir algunos scripts "globales".

Si desea evitar que un paquete se resuelva desde un registro remoto desde uno de sus espacios de trabajo, debe usar el protocolo de resolución de espacios de trabajo . En lugar de usar valores de semver dentro de las propiedades de sus dependencias de desarrollo o package.jsonarchivos de dependencias, debe usar lo siguiente:

"dependencies": {
    "@doppelmutzi/eslint-config": "workspace:*"
}

Esto le dice a Yarn Berry que el paquete @doppelmutzi/eslint-configdebe resolverse desde un espacio de trabajo local que se encuentra en la packagescarpeta. Yarn Berry escanea todos los package.jsonarchivos en busca de una namepropiedad con el valor de @doppelmutzi/eslint-config.

Yarn Berry también admite la clonación de espacios de trabajo de cualquier proyecto a través del protocolo Git.

"dependencies": {
    "@doppelmutzi/eslint-config": "git@github.com:doppelmutzi/companion-project-mono-repo-2022.git#workspace=@doppelmutzi/eslint-config"
}    

En este ejemplo, recupero directamente el espacio @doppelmutzi/eslint-configde trabajo del repositorio de Git especificado que constituye un proyecto de espacios de trabajo de Yarn Berry.

Las restricciones son un mecanismo de bajo nivel para escribir reglas de espacio de trabajo que deben cumplirse. Es un poco como ESLint para package.json; por ejemplo, cada espacio de trabajo debe incluir un campo de licencia en su archivo package.json.

Para los desarrolladores de JavaScript, puede ser inusual definir estas restricciones porque las escribe con el lenguaje de programación lógica Prolog . Debe proporcionar un constraints.proarchivo en la carpeta raíz del proyecto.

% Ensure all workspaces are using packageManager field with version 3.2.0
gen_enforced_field(WorkspaceCwd, 'packageManager', 'yarn@3.2.0').

El ejemplo simple asegura que todos los espacios de trabajo tengan un packageManagercampo que aplique Yarn Berry v3.2.0 como administrador de paquetes. Como parte de un flujo de trabajo de CI/CD, puede ejecutar $ yarn constraintsy interrumpir la canalización si no se cumplen las restricciones.

espacios de trabajo pnpm

pnpm ha ofrecido soporte para espacios de trabajo desde el principio. Necesita un pnpm-workspace.yamlarchivo obligatorio en la carpeta raíz del proyecto para usar esta función.

# pnpm-workspace.yaml
packages:
  - 'packages/**'

Esta configuración de ejemplo le dice a pnpm que todos los espacios de trabajo están ubicados dentro de la packagescarpeta. Al ejecutarse pnpm ien la carpeta raíz, se instalan las dependencias definidas en la raíz package.json, así como todas las dependencias especificadas en los package.jsonarchivos de los espacios de trabajo. La siguiente estructura de carpetas de la rama pnpm Git del proyecto de demostración es el resultado del proceso de instalación.

.
├── node_modules/
│   ├── # dependencies defined in package.json
├── packages/
│   ├── eslint-config/
│   │   └── package.json # no dependencies defined
│   ├── hooks/
│   │   ├── node_modules/ # dependencies defined in hooks/package.json
│   │   └── package.json
│   ├── server/
│   │   ├── node_modules/ # dependencies defined in server/package.json
│   │   └── package.json
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

Como puede ver, solo hay un archivo de bloqueo ( pnpm-lock.yaml) pero varias node_modulescarpetas. A diferencia de los espacios de trabajo de npm, pnpm crea una node_modulescarpeta en cada espacio de trabajo, siempre que haya dependencias especificadas en el archivo package.json.

Para comparar la situación con la dependencia de React con espacios de trabajo de npm, como se describe en la sección anterior, react@17.0.2se instala en la carpeta raíz node_modulesy en el espacio de hookstrabajo porque esta dependencia se especifica en ambos package.jsonarchivos.

A diferencia de npm, las node_modulescarpetas no son planas. Como se describió anteriormente, debido al enfoque de almacenamiento direccionable por contenido, estas dependencias se instalan físicamente solo una vez en el disco duro en el almacén central.

La raíz package.jsonrevela que existen múltiples indicadores útiles y que se pueden usar en el contexto de los espacios de trabajo.

{
  // ...  
  "start-server": "pnpm serve --filter @doppelmutzi/server",
  "publish-eslint-config": "pnpm publish -F @doppelmutzi/eslint*",
  "lint-packages": "pnpm lint -r --parallel",
}

El indicador de filtro ( --filtero -F) restringe un comando a uno o más espacios de trabajo. El start-serverscript demuestra cómo ejecutar un script en un espacio de trabajo en particular ( @doppelmutzi/server). También puede usar un patrón ( *) para hacer coincidir los espacios de trabajo, como se muestra en el publish-eslint-configscript.

Con el indicador recursivo ( --recursiveo -r), puede ejecutar un comando recursivamente en todos los espacios de trabajo. El lint-packagesscript muestra un ejemplo con el comando de ejecución que ejecuta el lintscript en todos los espacios de trabajo.

A diferencia de npm, pnpm ignora todos los espacios de trabajo que no proporcionan dicho script. Con el indicador paralelo , el script se ejecuta simultáneamente.

pnpm admite un protocolo de espacio de trabajo ( workspace:) similar al de Yarn Berry para usar espacios de trabajo como dependencias en su monorepo. El uso de este protocolo evita que pnpm resuelva las dependencias del espacio de trabajo local desde un registro remoto. El extracto de la raíz package.jsondemuestra cómo usar este protocolo.

// package.json
{
  // ...
  dependencies: {
    "@doppelmutzi/eslint-config": "workspace:1.0.2",
    "@doppelmutzi/hooks": "workspace:*",
    "@doppelmutzi/server": "workspace:./packages/server",
  // ...
  }
}

El uso workspace:le dice a pnpm que desea instalar dependencias que constituyen espacios de trabajo locales. "@doppelmutzi/eslint-config": "workspace:1.0.2"instala el espacio de trabajo local @doppelmutzi/eslint-configporque su versión package.jsones 1.0.2. **Si intenta instalar otra versión, el proceso de instalación falla.

La versión en el espacio de trabajo no coincide

Lo más probable es que desee utilizar el estado actual de un espacio de trabajo tal como existe en su proyecto de espacios de trabajo. Por lo tanto, puede usar workspace:*como se demostró con la dependencia @doppelmutzi/hooks. @doppelmutzi/servermuestra que también puede hacer referencia a un espacio de trabajo con una ruta relativa. Tiene el mismo efecto que workspace:*.

Similar a Yarn Berry, también es posible hacer referencia a espacios de trabajo desde un monorepo remoto con pnpm add.

Comandos CLI relacionados con el espacio de trabajo

Las siguientes tablas comparan un conjunto seleccionado de diferentes comandos CLI disponibles en npm, Yarn Berry y pnpm en el contexto de los espacios de trabajo. Esta no es una lista completa, pero constituye una hoja de trucos. Las siguientes tablas completan los comandos de mi último artículo con ejemplos relacionados con el espacio de trabajo.

Gestión de dependencias

Esta tabla cubre los comandos de administración de dependencias para instalar o actualizar todas las dependencias especificadas en package.json, o múltiples dependencias especificándolas en los comandos. Todos los comandos se pueden ejecutar en el contexto de uno o más espacios de trabajo. y todos los comandos se ejecutan desde la carpeta raíz del proyecto de espacios de trabajo.

Acciónsobre el nivel del marBaya de hilopnpm
instalar deps de todos los espacios de trabajo
  • npm install
  • alias:i
  • yarn install
  • alias:yarn
  • pnpm install
  • alias:i
instalar dependencias de un solo espacio de trabajo
  • npm i --workspace server
  • alias:-w
  • pnpm i --filter server
  • alias:-F
Agregar dependencias de nivel raíz
  • npm i eslint
  • yarn add eslint
  • pnpm i eslint
Agregar dependencias al espacio de trabajo
  • npm i -D react -w hooks
  • yarn workspace hooks add -D react
  • pnpm i -D -F hooks react
  • pnpm add -D -F hooks react
Agregar dependencia del espacio de trabajo al espacio de trabajo
  • N / A
  • yarn workspace app add hooks@'workspace:*'
  • pnpm i -F app hooks@'workspace:*'
actualizar todas las dependencias del espacio de trabajo
  • npm update -w hooks
  • yarn workspace hooks up
  • pnpm up -F hooks
  • pnpm up --latest -F hooks
  • alias:-L
actualizar la dependencia del espacio de trabajo
  • npm update react -w hooks
  • yarn workspace hooks up react
  • pnpm up -F hooks react
  • pnpm up -L -F hooks react
Eliminar dependencias del espacio de trabajo
  • npm uninstall react -w hooks
  • yarn workspace hooks remove react
  • pnpm remove --filter hooks react

Ejecución de guiones

Esta tabla muestra comandos para ejecutar scripts en uno o varios espacios de trabajo.

Acciónsobre el nivel del marBaya de hilopnpm
ejecutar script en un espacio de trabajo
  • npm run build -w hooks
  • yarn workspace hooks build
  • pnpm run build -F hooks
  • pnpm build -F hooks
ejecutar script en múltiples espacios de trabajo
  • npm run lint -w server -w hooks
  • N / A
  • solución alterna:yarn workspace hooks lint && yarn workspace server lint
  • pnpm -F server -F hooks lint
ejecutar secuencias de comandos en todos los espacios de trabajo secuencialmente
  • npm run lint --workspaces
  • alias:-ws
  • pnpm run --recursive lint
  • alias:-r
ejecutar script en todos los espacios de trabajo secuencialmente si está disponible
  • npm run lint -ws --if-present
  • yarn workspaces foreach run lint
  • pnpm run -r lint
ejecutar script en todos los espacios de trabajo en paralelo
  • N / A
  • solución alterna:npm run lint -w p1 & npm run lint -w p2
  • yarn workspaces foreach --parallel run lint
  • alias:-p
  • pnpm run -r lint --parallel

Varios

Esta tabla cubre útiles comandos incorporados. Si no hay un comando oficial, a menudo se puede usar un comando de terceros para lograr cosas similares, a través de un paquete npm o un complemento de Yarn Berry.

 sobre el nivel del marBaya de hilopnpm
proyecto de espacios de trabajo init
  • npm init -w ./packages/server(crea la configuración junto con el espacio de trabajo especificado)
  • yarn init --workspace
  • alias:

-w

  • N / A
espacio de trabajo de inicio
  • npm init -w ./packages/server
  • N / A
  • N / A
enumerar espacios de trabajo
  • N / A
  • yarn workspaces list
  • yarn workspaces list --json
  • N / A
Comprobar las restricciones del espacio de trabajo
  • N / A
  • N / A

Qué significan todas estas innovaciones para el futuro

Los proyectos frontend son cada vez más complejos; se requieren más y más dependencias para construirlos. El proceso de instalación, especialmente para monorepos, requiere mucho tiempo y en parte es propenso a errores. El estado actual de los administradores de paquetes ha solucionado muchos problemas, pero todavía hay espacio para mejoras.

tnpm , por ejemplo, es un servicio empresarial de Alibaba que parece haber subido el listón para los administradores de paquetes en el entorno empresarial cerrado. Su estrategia de resolución de dependencias reduce las solicitudes HTTP, en comparación con los administradores de paquetes descritos anteriormente.

Además, el gráfico de dependencia de tnpm se genera en el servidor, en conexión con una estrategia de almacenamiento en caché de varios niveles. Actualmente, esto es difícil de lograr con una solución no empresarial como npm, pnpm o Yarn, pero ciertamente establece el estándar de lo que es posible.

tnpm demuestra que todavía hay potencial de mejora en el espacio del administrador de paquetes. Fuente: tnpm en Dev.to

Los administradores de paquetes públicos todavía están investigando de forma independiente formas de mejorar el rendimiento y abordar los puntos débiles conocidos (por ejemplo, el almacenamiento de dependencia ineficiente, que discutimos aquí). Incluso npm está trabajando en un "modo aislado" que creará enlaces simbólicos node_modules, inspirados en pnpm. Con este cambio, npm se ha referido a su actual estrategia de resolución a largo plazo como "modo elevado".

pnpm también está realizando investigaciones con FUSE para proporcionar una alternativa al modo PnP de Yarn Berry, que parece prometedor (y probablemente también explique por qué casi no puede encontrar información sobre pnpm PnP en línea en este momento).

En última instancia, no se puede elogiar más lo bien que trabajan juntos los administradores de paquetes en términos de inspirarse mutuamente y compartir conocimientos. Puede ver esto en muchos lugares, como la sección de comentarios de este artículo en tnpm .

Conclusión

Parece que habrá múltiples administradores de paquetes en el futuro. Es posible que no quieran tener conjuntos de características y conceptos iguales para abordar mejor la miríada de problemas que enfrentan los diferentes usuarios.

Por un lado, esto es maravilloso porque significa que habrá opciones para elegir el flujo de trabajo óptimo para un proyecto. Tampoco hay nada que nos impida usar diferentes administradores de paquetes en un entorno de equipo para diferentes proyectos, ya que se basan en conceptos similares.

Por otro lado, cada vez es más difícil para los proveedores de bibliotecas admitir todos estos administradores de paquetes y sus respectivas diferencias. Como ejemplo, en mi proyecto actual no puedo usar Yarn Berry porque una herramienta establecida no admite su formato de archivo de bloqueo. Queda por ver si se superará o no el apoyo a estas diferencias.

Fuente: https://blog.logrocket.com/exploring-workspaces-other-advanced-package-manager-features/ 

 #packaging  #workspace #pnpm #npm 

joe biden

1617255938

¿Cómo migrar los buzones de correo de Exchange a la nube de Office 365?

Si tiene problemas para migrar los buzones de correo de Exchange a Office 365, debe leer este artículo para saber cómo migrar los buzones de correo de Exchange EDB a Office 365. Al migrar a Office 365, los usuarios pueden acceder a sus buzones de correo desde cualquier lugar y desde cualquier dispositivo.

En esta publicación, explicaremos las razones detrás de esta migración y una solución profesional para migrar de Exchange a Office 365.

Razones para migrar Exchange Server a la nube de Office 365

Office 365 apareció por primera vez en 2011 y, dado que se considera la mejor plataforma para aquellas organizaciones que desean administrar todo su sistema de correo electrónico en la nube. Estas son las características clave de Office 365:

  1. Permite trabajar desde cualquier lugar y desde cualquier lugar.
  2. No se preocupe por el spam y el malware.
  3. La seguridad proporcionada por Office 365 es altamente confiable.
  4. Controla el costo total y brinda flexibilidad financiera.
  5. Todas las actualizaciones y mejoras son administradas por Microsoft.

¿Cómo migrar los buzones de correo de Exchange a Office 365?

Hay varias formas manuales de migrar los buzones de correo de Exchange EDB a Office 365, pero para evitar estos complicados y prolongados procedimientos, presentamos una solución de terceros, es decir, la herramienta de migración de Exchange, que es automatizada y directa para la migración de Exchange a Office 365. La herramienta funciona rápidamente y migra todos los elementos del buzón de Exchange Server a Office 365.

La herramienta de migración de Datavare Exchange es demasiado fácil de usar y ofrece pasos sencillos para migrar EDB a Office 365:

  1. Descargue e instale el software en su sistema.
  2. Agregue el archivo EDB de Exchange con el botón Examinar.
  3. Seleccione exportar a buzones de correo de Office 365.
  4. Proporcione los detalles de inicio de sesión de la cuenta de Office 365.
  5. Seleccione la carpeta y presione el botón Finalizar.

Por lo tanto, todos sus buzones de correo de Exchange EDB ahora se migran a Office 365.
Nota: puede usar filtros para migrar los elementos de datos deseados de la cuenta de Exchange a la de Office 365

Líneas finales

Este blog le indica una solución profesional para la migración de buzones de correo de Exchange a la cuenta de Office 365. Dado que las soluciones manuales son complicadas, sugerimos la herramienta de migración de Exchange, que es demasiado simple de usar. Los usuarios no se enfrentan a problemas al operar el programa. La mejor parte de este software es que no necesita habilidades técnicas para realizar la migración. Se puede comprender el funcionamiento del software descargando la versión de demostración que permite la migración de los primeros 50 elementos por carpeta.

Más información:- https://www.datavare.com/software/edb-migration.html

#herramienta de migración de intercambio #migración de intercambio #migrar buzones de correo de exchange

joe biden

1617257581

Software de restauración de Exchange para restaurar sin problemas PST en Exchange Server

¿Quiere restaurar los buzones de correo de PST a Exchange Server? Entonces, estás en la página correcta. Aquí, lo guiaremos sobre cómo puede restaurar fácilmente mensajes y otros elementos de PST a MS Exchange Server.

Muchas veces, los usuarios necesitan restaurar los elementos de datos de PST en Exchange Server, pero debido a la falta de disponibilidad de una solución confiable, los usuarios no pueden obtener la solución. Háganos saber primero sobre el archivo PST y MS Exchange Server.

Conozca PST y Exchange Server

PST es un formato de archivo utilizado por MS Outlook, un cliente de correo electrónico de Windows y muy popular entre los usuarios domésticos y comerciales.

Por otro lado, Exchange Server es un poderoso servidor de correo electrónico donde todos los datos se almacenan en un archivo EDB. Los usuarios generalmente guardan la copia de seguridad de los buzones de correo de Exchange en el archivo PST, pero muchas veces, los usuarios deben restaurar los datos del archivo PST en Exchange. Para resolver este problema, estamos aquí con una solución profesional que discutiremos en la siguiente sección de esta publicación.

Un método profesional para restaurar PST a Exchange Server

No le recomendamos que elija una solución al azar para restaurar los datos de PST en Exchange Server. Por lo tanto, al realizar varias investigaciones, estamos aquí con una solución inteligente y conveniente, es decir, Exchange Restore Software. Es demasiado fácil de manejar por todos los usuarios y restaurar cómodamente todos los datos del archivo PST a Exchange Server.

Funciones principales ofrecidas por Exchange Restore Software

El software es demasiado simple de usar y se puede instalar fácilmente en todas las versiones de Windows. Con unos pocos clics, la herramienta puede restaurar los elementos del buzón de Exchange.

No es necesario que MS Outlook restaure los datos PST en Exchange. Todos los correos electrónicos, contactos, notas, calendarios, etc. se restauran desde el archivo PST a Exchange Server.

Todas las versiones de Outlook son compatibles con la herramienta, como Outlook 2019, 2016, 2013, 2010, 2007, etc. La herramienta proporciona varios filtros mediante los cuales se pueden restaurar los datos deseados desde un archivo PST a Exchange Server. El programa se puede instalar en todas las versiones de Windows como Windows 10, 8.1, 8, 7, XP, Vista, etc.

Descargue la versión de demostración del software de restauración de Exchange y analice el funcionamiento del software restaurando los primeros 50 elementos por carpeta.

Líneas finales

No existe una solución manual para restaurar los buzones de correo de Exchange desde el archivo PST. Por lo tanto, hemos explicado una solución fácil e inteligente para restaurar datos de archivos PST en Exchange Server. Simplemente puede usar este software y restaurar todos los datos de PST a Exchange Server.

Más información:- https://www.datavare.com/software/exchange-restore.html

#intercambio de software de restauración #intercambio de restauración #buzón del servidor de intercambio #herramienta de restauración de intercambio

Administradores De Paquetes De JavaScript Comparados: Npm, Yarn O Pnpm

Nota del editor : esta publicación se reescribió por completo el 16 de febrero de 2022 para reevaluar el panorama del administrador de paquetes, hacer referencia y comparar nuevas herramientas y espacios de trabajo, analizar la funcionalidad de Corepack y los impactos en el rendimiento, brindar una vista panorámica del uso del administrador de paquetes entre proyectos populares de código abierto y explicar más a fondo la evolución de los gestores de paquetes desde 2010.

Actualmente existen tres jugadores principales en el campo de los administradores de paquetes:

  1. sobre el nivel del mar
  2. Yarn : veremos en breve que Yarn puede referirse a Yarn Classic (< v2) o a su versión más moderna Yarn Berry (≥ v2)
  3. rendimiento sobre el nivel del mar (pnpm)

Prácticamente, hemos logrado la paridad de características entre todos los administradores de paquetes, por lo que lo más probable es que decida qué administrador de paquetes usar en función de los requisitos no funcionales, como la velocidad de instalación, el consumo de almacenamiento o cómo se integra con su flujo de trabajo existente.

Por supuesto, la forma en que elija usar cada administrador de paquetes será diferente, pero todos comparten un conjunto de conceptos principales. Puede hacer lo siguiente con cualquiera de estos administradores de paquetes:

  • Manejar y escribir metadatos
  • Instalar por lotes o actualizar todas las dependencias
  • Agregar, actualizar y eliminar dependencias
  • Ejecutar guiones
  • Publicar paquetes
  • Realizar auditorías de seguridad

Sin embargo, a pesar de esta paridad, los administradores de paquetes difieren bajo el capó. Tradicionalmente, npm e Yarn han instalado dependencias en una node_modulescarpeta plana . Pero esta estrategia de resolución de la dependencia no está exenta de críticas.

Por lo tanto, pnpm ha introducido algunos conceptos nuevos para almacenar dependencias de manera más eficiente en una node_modulescarpeta anidada. Yarn Berry va aún más lejos al abandonar por node_modulescompleto su modo Plug'n'Play (PnP).

Siéntase libre de saltar y leer lo que sea más relevante para usted.

Cómo utilizar el proyecto complementario

Creé una aplicación React complementaria para demostrar algunos de los conceptos únicos de los diferentes administradores de paquetes. Existe una rama Git correspondiente para cada variante del administrador de paquetes. Este es el proyecto que también utilicé para crear la tabla de rendimiento en la sección a continuación de esta publicación.

Aunque el tipo de aplicación no es importante para el tema de este artículo, he elegido un proyecto de tamaño mediano y realista para poder iluminar diferentes aspectos; como ejemplo del pasado reciente, el mecanismo PnP de Yarn Berry provocó algunas discusiones acaloradas sobre problemas de compatibilidad que este proyecto es adecuado para ayudar a examinar.

Una breve historia de los administradores de paquetes de JavaScript

El primer administrador de paquetes que se lanzó fue npm, en enero de 2010. Estableció los principios básicos de cómo funcionan los administradores de paquetes en la actualidad.

Si npm existe desde hace más de 10 años, ¿por qué existen alternativas? Aquí hay algunas razones clave por las que han surgido:

  • Diferentes algoritmos de resolución de dependencias con diferentes node_modulesestructuras de carpetas (anidado, plano, node_modulesmodo PnP)
  • Diferentes soportes para izar , lo que tiene implicaciones de seguridad.
  • Diferentes formatos de archivo de bloqueo, cada uno de los cuales tiene implicaciones de rendimiento
  • Diferentes enfoques para almacenar paquetes en disco, lo que tiene implicaciones en la eficiencia del espacio en disco
  • Soporte diferente para proyectos de paquetes múltiples (también conocidos como espacios de trabajo), lo que afecta la capacidad de mantenimiento y la velocidad de grandes monorepos
  • Diferentes necesidades de nuevas herramientas y comandos, cada uno de los cuales tiene implicaciones DX
    • Relacionado, diferentes necesidades de extensibilidad a través de complementos y herramientas comunitarias
  • Diferentes grados de configurabilidad y flexibilidad.

Profundicemos en una breve historia de cómo se identificaron estas necesidades después de que npm saltó a la fama, cómo Yarn Classic resolvió algunas de ellas, cómo pnpm amplió estos conceptos y cómo Yarn Berry, como sucesor de Yarn Classic, trató de romper el molde. por estos conceptos y procesos tradicionales.

sobre el nivel del mar, el pionero

npm es el antepasado de los administradores de paquetes. Por error, mucha gente cree que npm es un acrónimo de “Node package manager”, pero no es así . Sin embargo, se incluye con el tiempo de ejecución de Node.js.

Su lanzamiento supuso una revolución porque, hasta entonces, las dependencias de los proyectos se descargaban y gestionaban de forma manual. Conceptos como el package.jsonarchivo con sus campos de metadatos (p. ej., devDependencies), el almacenamiento de dependencias en node_modules, scripts personalizados, registros de paquetes públicos y privados, y más, fueron introducidos por npm.

En 2020, GitHub adquirió npm , por lo que, en principio, npm ahora está bajo la administración de Microsoft. Al momento de escribir este artículo, la versión principal más reciente es v8 , lanzada en octubre de 2021.

Yarn (v1 / Classic), responsable de muchas innovaciones

En una publicación de blog de octubre de 2016 , Facebook anunció un esfuerzo de colaboración con Google y algunos otros para desarrollar un nuevo administrador de paquetes que resolvería los problemas de consistencia, seguridad y rendimiento que npm tenía en ese momento. Llamaron a la alternativa Yarn , que significa Otro Negociador de Recursos.

Aunque basaron el diseño arquitectónico de Yarn en muchos conceptos y procesos establecidos por npm, Yarn tuvo un gran impacto en el panorama del administrador de paquetes en su versión inicial. A diferencia de npm, Yarn paralelizó las operaciones para acelerar el proceso de instalación, que había sido un gran problema para las primeras versiones de npm.

Yarn puso el listón más alto en DX, seguridad y rendimiento, y también inventó muchos conceptos, entre ellos:

  • Soporte monorepo nativo
  • Instalaciones con reconocimiento de caché
  • Almacenamiento en caché sin conexión
  • Bloquear archivos

Yarn v1 entró en modo de mantenimiento en 2020 . Desde entonces, la línea v1.x se ha considerado heredada y se le cambió el nombre a Yarn Classic. Su sucesor, Yarn v2 o Berry, es ahora la rama de desarrollo activa.

pnpm, rápido y eficiente en disco

La versión 1 de pnpm fue lanzada en 2017 por Zoltan Kochan. Es un reemplazo directo para npm, por lo que si tiene un proyecto npm, ¡puede usar pnpm de inmediato!

El principal problema que tenían los creadores de pnpm con npm e Yarn era el almacenamiento redundante de dependencias que se usaban en todos los proyectos. Aunque Yarn Classic tenía ventajas de velocidad sobre npm, usaba el mismo enfoque de resolución de dependencias, lo cual era imposible para los creadores de pnpm: npm y Yarn Classic usaban elevación para aplanar su node_modules.

En lugar de izar, pnpm introdujo una estrategia alternativa de resolución de dependencias: almacenamiento direccionable por contenido . Este método da como resultado una node_modulescarpeta anidada que almacena paquetes en un almacén global en su carpeta de inicio ( ~/.pnpm-store/). Cada versión de una dependencia se almacena físicamente en esa carpeta solo una vez, lo que constituye una única fuente de verdad y ahorra bastante espacio en disco.

Esto se logra a través de un node_modulesdiseño, utilizando enlaces simbólicos para crear una estructura anidada de dependencias, donde cada archivo de cada paquete dentro de la carpeta es un enlace fijo a la tienda. El siguiente diagrama de la documentación oficial aclara esto.

Fuente: pnpm

La influencia de pnpm se puede ver en su informe de 2021 : los competidores quieren adoptar los conceptos de instalación de pnpm, como la estructura de enlaces simbólicosnode_modules y la gestión eficiente del disco de los paquetes debido a sus innovaciones en el almacenamiento direccionable por contenido .

Yarn (v2, Berry), reinventa la rueda con Plug'n'Play

Yarn 2 se lanzó en enero de 2020 y se anunció como una actualización importante del Yarn original. El equipo de Yarn comenzó a referirse a él como Yarn Berry para que fuera más obvio que era esencialmente un nuevo administrador de paquetes con una nueva base de código y nuevos principios.

La principal innovación de Yarn Berry es su enfoque Plug'n'Play (PnP) , que surgió como una estrategia para corregirnode_modules . En lugar de generar node_modules, se genera un .pnp.cjsarchivo con tablas de búsqueda de dependencias, que se puede procesar de manera más eficiente porque es un archivo único en lugar de una estructura de carpetas anidadas. Además, cada paquete se almacena como un archivo zip dentro de la .yarn/cache/carpeta, lo que ocupa menos espacio en disco que la node_modulescarpeta.

Todo este cambio, y tan rápido, generó una gran controversia después del lanzamiento. Los cambios importantes de PnP requirieron que los mantenedores actualizaran sus paquetes existentes para ser compatibles con él. El nuevo enfoque PnP se usó de forma predeterminada, y volver al node_modulesprincipio no fue sencillo, lo que llevó a muchos desarrolladores destacados a criticar abiertamente a Yarn 2 por no habilitarlo.

Desde entonces, el equipo de Yarn Berry ha abordado muchos problemas en sus versiones posteriores. Para abordar la incompatibilidad de PnP, el equipo ofreció algunas formas de cambiar fácilmente el modo de operación predeterminado. Con la ayuda de un node_modulescomplemento , solo se necesitaba una línea de configuración para usar el node_modulesenfoque tradicional.

Además, el ecosistema de JavaScript ha brindado más y más soporte para PnP a lo largo del tiempo, como puede ver en esta tabla de compatibilidad , y algunos grandes proyectos se han movido para adoptar Yarn Berry. En mi proyecto complementario , también pude implementar correctamente PnP con mi proyecto de demostración React.

Aunque Yarn Berry es bastante joven, también tiene un impacto en el panorama de los administradores de paquetes: pnpm adoptó un enfoque PnP a fines de 2020.

Flujos de trabajo de instalación

Primero se debe instalar un administrador de paquetes en los sistemas locales y de CI/CD de cada desarrollador.

sobre el nivel del mar

npm se envía con Node.js, por lo que no se necesita ningún paso adicional. Además de descargar el instalador de Node.js para su sistema operativo, se ha vuelto una práctica común usar herramientas CLI para administrar versiones de software. En el contexto de Node, Node Version Manager (nvm) o Volta se han convertido en utilidades muy útiles.

Yarn Classic y Yarn Berry

Puede instalar Yarn 1 de diferentes maneras, por ejemplo, como un paquete npm con $ npm i -g yarn.

Para migrar de Yarn Classic a Yarn Berry , la forma recomendada es:

  • Instale o actualice Yarn Classic a la última versión 1.x
  • Use el yarn set versioncomando para actualizar a la última versión moderna:$ yarn set version berry

Sin embargo, la forma recomendada de instalar Yarn Berry es a través de Corepack.

Corepack fue creado por la gente de Yarn Berry. La iniciativa se llamó originalmente administrador de paquetes (pmm) 🤯 y se fusionó con Node en LTS v16.

Con la ayuda de Corepack, no tiene que instalar los administradores de paquetes alternativos de npm "por separado" porque Node incluye binarios Yarn Classic, Yarn Berry y pnpm como correcciones. Estas correcciones permiten a los usuarios ejecutar comandos Yarn y pnpm sin tener que instalarlos explícitamente primero y sin saturar la distribución de Node.

Corepack viene preinstalado con Node.js ≥ v16.9.0. Sin embargo, para versiones anteriores de Node, puede instalarlo usando $ npm install -g corepack.

Habilite Corepack primero, antes de usarlo. El ejemplo muestra cómo activarlo en Yarn Berry v3.1.1.

# you need to opt-in first
$ corepack enable
# shim installed but concrete version needs to activated
$ corepack prepare yarn@3.1.1 --activate

pnpm

Puede instalar pnpm como un paquete npm con $ npm i -g pnpm. También puede instalar pnpm con Corepack : $ corepack prepare pnpm@6.24.2 --activate.

Estructuras de proyecto

En esta sección verás de un vistazo las principales características de los diferentes gestores de paquetes. Puede detectar fácilmente qué archivos están involucrados en la configuración de administradores de paquetes particulares y qué archivos se generan en un paso de instalación.

Todos los administradores de paquetes almacenan toda la metainformación importante en el archivo de manifiesto del proyecto, package.json. Además, se puede usar un archivo de configuración en el nivel raíz para configurar registros privados o métodos de resolución de dependencias.

Con un paso de instalación, las dependencias se almacenan en una estructura de archivos (por ejemplo, dentro de node_modules) y se genera un archivo de bloqueo. Esta sección no tiene en cuenta la configuración de espacios de trabajo , por lo que todos los ejemplos solo muestran una única ubicación donde se almacenan las dependencias.

sobre el nivel del mar

Con $ npm install, o el más corto $ npm i, se generan un package-lock.jsonarchivo y una carpeta. Se puede colocar un archivo de configuraciónnode_modules opcional en el nivel raíz. Consulte la siguiente sección para obtener más información sobre los archivos de bloqueo..npmrc

.
├── node_modules/
├── .npmrc
├── package-lock.json
└── package.json

Hilo clásico

Ejecutar $ yarncrea un yarn.lockarchivo y una node_modulescarpeta. Un .yarnrcarchivo también puede ser una opción de configuración; Yarn Classic también hace honor a los .npmrcarchivos. Opcionalmente, se puede usar una carpeta de caché ( .yarn/cache/) y una ubicación que almacene la versión actual de Yarn Classic ( .yarn/releases/). Las diferentes formas de configurar esto se pueden ver en la sección de comparación de configuraciones.

.
├── .yarn/
│   ├── cache/
│   └── releases/
│       └── yarn-1.22.17.cjs
├── node_modules/
├── .yarnrc
├── package.json
└── yarn.lock

Baya de hilo connode_modules

Independientemente del modo de instalación, tendrá que manejar más archivos y carpetas en los proyectos de Yarn Berry que en los proyectos que usan otros administradores de paquetes. Algunos son opcionales y otros son obligatorios.

Yarn Berry ya no honra .npmrcni .yarnrcarchiva; en su lugar, se requiere un .yarnrc.ymlarchivo de configuración . Para un flujo de trabajo tradicional con una node_modulescarpeta generada, debe proporcionar una nodeLinkerconfiguración que use una node_modulesvariante de instalación inspirada en pnpm.

# .yarnrc.yml
nodeLinker: node-modules # or pnpm

La ejecución $ yarninstala todas las dependencias en una node_modulescarpeta. Se yarn.lockgenera un archivo más nuevo pero incompatible con Yarn Classic. Además, .yarn/cache/se genera una carpeta que se usa para instalaciones sin conexión. La releasescarpeta es opcional y almacena la versión de Yarn Berry que usa el proyecto, como veremos en la sección de comparación de configuraciones.

.
├── .yarn/
│   ├── cache/
│   └── releases/
│       └── yarn-3.1.1.cjs
├── node_modules/
├── .yarnrc.yml
├── package.json
└── yarn.lock

Baya de hilo con PnP

Tanto para los modos PnP estrictos como flexibles$ yarn , la ejecución genera .yarn/cache/y .yarn/unplugged/, junto con .pnp.cjsy yarn.lockarchivos. PnP estricto es el modo predeterminado, pero para suelto, se requiere una configuración.

# .yarnrc.yml
nodeLinker: pnp
pnpMode: loose

En un proyecto PnP, .yarn/lo más probable es que la carpeta contenga una sdk/carpeta para proporcionar compatibilidad con IDE además de una releases/carpeta. Hay incluso más carpetas que pueden formar parte de .yarn/, según su caso de uso.

.
├── .yarn/
│   ├── cache/
│   ├── releases/
│   │   └── yarn-3.1.1.cjs
│   ├── sdk/
│   └── unplugged/
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock

pnpm

El estado inicial de un proyecto pnpm se parece a un proyecto npm o Yarn Classic: necesita un package.jsonarchivo. Después de instalar las dependencias con , se genera $ pnpm iuna carpeta, pero su estructura es completamente diferente debido a su enfoque de almacenamiento direccionable por contenido.node_modules

pnpm también genera su propia versión de un archivo de bloqueo, pnp-lock.yml. Puede proporcionar una configuración adicional con un .npmrcarchivo opcional.

.
├── node_modules/
│   └── .pnpm/
├── .npmrc
├── package.json
└── pnpm-lock.yml

Bloquear archivos y almacenamiento de dependencias

Como se describe en la sección anterior, cada administrador de paquetes crea archivos de bloqueo .

Los archivos de bloqueo almacenan exactamente las versiones de cada dependencia instalada para su proyecto, lo que permite instalaciones más predecibles y deterministas. Esto es necesario porque las versiones de dependencia probablemente se declaran con rangos de versión (p. ej., ≥ v1.2.5) y, por lo tanto, las versiones realmente instaladas podrían diferir si no "bloquea" sus versiones.

Los archivos de bloqueo a veces también almacenan sumas de verificación, que trataremos con más detalle en nuestra sección sobre seguridad.

Los archivos de bloqueo han sido una característica de npm desde v5 ( package-lock.json), en pnpm desde el primer día ( pnpm-lock.yaml) y en un nuevo formato YAML en Yarn Berry ( yarn.lock).

En la sección anterior, vimos el enfoque tradicional, donde las dependencias se instalan en una node_modulesestructura de carpetas. Este es el esquema que utilizan npm, Yarn Classic y pnpm , donde pnpm lo hace de manera más eficiente que los demás.

Yarn Berry en modo PnP lo hace de manera diferente. En lugar de una node_modulescarpeta, las dependencias se almacenan como archivos zip en combinación con un archivo .yarn/cache/y ..pnp.cjs

Es mejor tener estos archivos bloqueados bajo el control de versiones porque resuelve el problema "funciona en mi máquina": todos los miembros del equipo instalan las mismas versiones.

Comandos CLI

Las siguientes tablas comparan un conjunto seleccionado de diferentes comandos CLI disponibles en npm, Yarn Classic, Yarn Berry y pnpm. Esta no es una lista completa, pero constituye una hoja de trucos. Esta sección no cubre los comandos relacionados con el espacio de trabajo.

npm y pnpm presentan especialmente muchos alias de comandos y opciones, lo que significa que los comandos pueden tener diferentes nombres, es decir, $ npm installes lo mismo que $ npm add. Además, muchas opciones de comandos tienen versiones cortas, por ejemplo, -Den lugar de --save-dev.

En las tablas, me referiré a todas las versiones cortas como alias. Con todos los administradores de paquetes, puede agregar, actualizar o eliminar varias dependencias separándolas con espacios (p. ej., npm update react react-dom). En aras de la claridad, los ejemplos solo muestran el uso con dependencias individuales.

Gestión de dependencias

Esta tabla cubre los comandos de administración de dependencias para instalar o actualizar todas las dependencias especificadas en package.json, o múltiples dependencias especificándolas en los comandos.

Acciónsobre el nivel del marHilo clásicoBaya de hilopnpm
instalar deps enpackage.jsonnpm install
alias: i,add
yarn installoyarncomo clásicopnpm install
alias:i
actualizar deps en package.jsonacc. severnpm update
alias: up,upgrade
yarn upgradeyarn semver up(a través del complemento )pnpm update
alias:up
actualizar las dependencias package.jsona la últimaN / Ayarn upgrade --latestyarn uppnpm update --latest
alias:-L
actualizar deps acc. severnpm update reactyarn upgrade reactyarn semver up reactpnpm up react
actualizar deps a la últimanpm update react@latestyarn upgrade react --latestyarn up reactpnpm up -L react
actualizar deps de forma interactivaN / Ayarn upgrade-interactiveyarn upgrade-interactive(a través del complemento )$ pnpm up --interactive
alias:-i
agregar dependencias de tiempo de ejecuciónnpm i reactyarn add reactcomo clásicopnpm add react
añadir departamentos de desarrollonpm i -D babel
alias:--save-dev
yarn add -D babel
alias:  --dev
como clásicopnpm add -D babel
alias:--save-dev
agregar deps a package.jsonsin semvernpm i -E react
alias:--save-exact
yarn add -E react
alias:--exact
como clásicopnpm add -E react
alias:--save-exact
desinstalar deps y eliminar depackage.jsonnpm uninstall react
alias: remove, rm, r, un,unlink
yarn remove reactcomo clásicopnpm remove react
alias: rm, un,uninstall
desinstalar deps sin actualización depackage.jsonnpm uninstall 
--no-save
N / AN / AN / A

Ejecución de paquetes

Los siguientes ejemplos muestran cómo administrar paquetes que constituyen herramientas de utilidad durante el tiempo de desarrollo, también conocidos como archivos binarios, como ntl , para ejecutar secuencias de comandos de forma interactiva. La terminología utilizada en la tabla:

  • Paquete: dependencia o binario
  • Binario: una utilidad ejecutable que se ejecuta desde node_modules/.bin/o .yarn/cache/(PnP)

Es importante comprender que Yarn Berry solo nos permite ejecutar archivos binarios que hemos especificado en nuestro campo package.jsono que están expuestos en su binmetacampo por razones de seguridad. pnpm presenta el mismo comportamiento de seguridad .

Acciónsobre el nivel del marHilo clásicoBaya de hilopnpm
instalar paquetes globalmentenpm i -g ntl
alias:--global
yarn global add ntlN/A ( global eliminado )pnpm add --global ntl
actualizar paquetes globalmentenpm update -g ntlyarn global upgrade ntlN / Apnpm update --global ntl
eliminar paquetes globalmentenpm uninstall -g ntlyarn global remove ntlN / Apnpm remove
--global ntl
ejecutar binarios desde la terminalnpm exec ntlyarn ntlyarn ntlpnpm ntl
ejecutar binarios desde el scriptntlntlntlntl
ejecución de paquetes dinámicosnpx ntlN / Ayarn dlx ntlpnpm dlx ntl
agregar dependencias de tiempo de ejecuciónnpm i reactyarn add reactcomo clásicopnpm add react
añadir departamentos de desarrollonpm i -D babel
alias:--save-dev
yarn add -D babel
alias:--dev
como clásicopnpm add -D babel
alias:--save-dev
agregar deps a package.jsonsin semvernpm i -E react
alias:--save-exact
yarn add -E react
alias:--exact
como clásicopnpm add -E react
alias:--save-exact
desinstalar deps y eliminar depackage.jsonnpm uninstall react
alias: remove, rm, r, un,unlink
yarn remove reactcomo clásicopnpm remove react
alias: rm, un,uninstall
desinstalar deps sin actualización depackage.jsonnpm uninstall
--no-save
N / AN / AN / A

Comandos comunes

Esta tabla cubre útiles comandos incorporados. Si no hay un comando oficial, a menudo se puede usar un comando de terceros, a través de un paquete npm o un complemento de Yarn Berry.

Acciónsobre el nivel del marHilo clásicoBaya de hilopnpm
publicar paquetenpm publishyarn publishyarn npm publishpnpm publish
lista de unidades instaladasnpm ls
alias: list, la,ll
yarn list pnpm list
alias:ls
lista de dependencias obsoletasnpm outdatedyarn outdatedyarn upgrade-interactivepnpm outdated
imprimir información sobre depsnpm explain ntl
alias:why
yarn why ntlcomo clásicopnpm why ntl
proyecto de inicionpm init -y
npm init(interactivo)
alias:--yes
yarn init -y
yarn init(interactivo)
alias:--yes
yarn initpnpm init -y
pnpm init(interactivo)
alias:--yes
imprimir información de licenciasN/A (a través de un paquete de terceros)yarn licenses listN/A (o a través de un complemento , otro complemento )N/A (a través de un paquete de terceros)
actualizar la versión del administrador de paquetesN/A (con herramientas de terceros, por ejemplo, nvm)con npm:yarn policies set-version 1.13.0con paquete básico:yarn set version 3.1.1N/A (con npm, Corepack)
realizar auditoria de seguridadnpm audityarn audityarn npm auditpnpm audit
agregar deps a package.jsonsin semvernpm i -E react
alias:--save-exact
yarn add -E react
alias:--exact
como clásicopnpm add -E react
alias:--save-exact
desinstalar deps y eliminar depackage.jsonnpm uninstall react
alias: remove, rm, r, un,unlink
yarn remove reactcomo clásicopnpm remove react
alias: rm, un,uninstall
desinstalar deps sin actualización depackage.jsonnpm uninstall
--no-save
N / AN / AN / A

Archivos de configuración

La configuración de los administradores de paquetes se lleva a cabo tanto en sus package.jsonarchivos de configuración como en los dedicados. Ejemplos de opciones de configuración son:

  • Definir la versión exacta a utilizar
  • Usar una estrategia particular de resolución de dependencia
  • Configurar el acceso a un registro privado
  • Dígale al administrador de paquetes dónde encontrar espacios de trabajo dentro de un monorepo

sobre el nivel del mar

La mayor parte de la configuración tiene lugar en un archivo de configuración dedicado ( .npmrc).

Si desea utilizar la función de espacios de trabajo de npm, debe agregar una configuración package.jsonmediante el campo de metadatos de espacios de trabajo para indicarle a npm dónde encontrar las carpetas que constituyen subproyectos o espacios de trabajo, respectivamente.

{
  // ...
  "workspaces": [
    "hooks",
    "utils"
  ]
}

Cada administrador de paquetes funciona de manera inmediata con el registro público de npm. En el contexto de una empresa con bibliotecas compartidas, lo más probable es que desee reutilizarlas sin publicarlas en un registro público. Para configurar un registro privado, puede hacerlo en un .npmrcarchivo.

# .npmrc
@doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/41/packages/npm/

Existen muchas opciones de configuración para npm y se ven mejor en los documentos.

Hilo clásico

Puede configurar espacios de trabajo de Yarn en su archivo package.json. Es similar a npm, pero el espacio de trabajo debe ser un paquete privado.

{
  // ...
  "private": true,
  "workspaces": ["workspace-a", "workspace-b"]
}

Cualquier configuración opcional va a un .yarnrcarchivo . Una opción de configuración común es establecer un yarn-path, que impone una versión binaria particular para que la use cada miembro del equipo. El yarn-pathdirige a una carpeta (p. ej., .yarn/releases/) que contiene una versión particular de Yarn. Puede instalar una versión de Yarn Classic con el yarn policiescomando .

Baya de hilo

La configuración de espacios de trabajo en Yarn Berry también es análoga a cómo se hace en Yarn Classic, con un archivo package.json. La mayor parte de la configuración de Yarn Berry tiene lugar en .yarnrc.yml, y hay muchas opciones de configuración disponibles. El ejemplo de Yarn Classic también es posible, pero el campo de metadatos se renombra a yarnPath.

# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs

Yarn Berry se puede ampliar con complementos mediante el uso de yarn plugin import. Este comando actualiza el .yarnrc.yml.

# .yarnrc.yml
plugins:
  - path: .yarn/plugins/@yarnpkg/plugin-semver-up.cjs
    spec: "https://raw.githubusercontent.com/tophat/yarn-plugin-semver-up/master/bundles/%40yarnpkg/plugin-semver-up.js"

Como se describe en la sección de historial, puede haber problemas con las dependencias en el modo estricto PnP debido a la incompatibilidad. Existe una solución típica para un problema PnP de este tipo: la packageExtensionspropiedad de configuración . Puede seguir el siguiente ejemplo con el proyecto complementario .

# .yarnrc.yml
packageExtensions:
  "styled-components@*":
    dependencies:
      react-is: "*"

pnpm

pnpm usa el mismo mecanismo de configuración que npm , por lo que puede usar un .npmrcarchivo. La configuración de un registro privado también funciona de la misma manera que con npm.

Con la característica de espacios de trabajo de pnpm , está disponible el soporte para proyectos de paquetes múltiples. Para inicializar un monorepo, debe especificar la ubicación de los paquetes en un pnpm-workspace.yamlarchivo.

# pnpm-workspace.yaml
packages:
  - 'packages/**'

soporte Monorepo

¿Qué es un monorepo?

Un monorepo es un repositorio que alberga múltiples proyectos, que se denominan espacios de trabajo o paquetes. Es una estrategia de organización de proyectos para mantener todo en un solo lugar en lugar de usar múltiples repositorios.

Por supuesto, esto viene con una complejidad adicional. Yarn Classic fue el primero en habilitar esta funcionalidad, pero ahora todos los principales administradores de paquetes ofrecen una función de espacios de trabajo. Esta sección muestra cómo configurar espacios de trabajo con cada uno de los diferentes administradores de paquetes.

sobre el nivel del mar

El equipo de npm lanzó la tan esperada función de espacios de trabajo de npm en v7. Contenía una serie de comandos CLI que ayudaron a administrar proyectos de paquetes múltiples desde un paquete raíz. La mayoría de los comandos se pueden usar con opciones relacionadas con el espacio de trabajo para decirle a npm si debe ejecutarse en un espacio de trabajo específico, en varios o en todos.

# Installing all dependencies for all workspaces
$ npm i --workspaces.
# run against one package
$ npm run test --workspace=hooks
# run against multiple packages
$ npm run test --workspace=hooks --workspace=utils
# run against all
$ npm run test --workspaces
# ignore all packages missing test
$ npm run test --workspaces --if-present

A diferencia de otros administradores de paquetes, npm v8 actualmente no admite el filtrado avanzado ni la ejecución de varios comandos relacionados con el espacio de trabajo en paralelo.

Hilo clásico

En agosto de 2017, el equipo de Yarn anunció soporte monorepo de primera clase en términos de una función de espacios de trabajo . Antes de este punto, solo era posible usar un administrador de paquetes en un proyecto de paquetes múltiples con software de terceros como Lerna . Esta adición a Yarn allanó el camino para que otros administradores de paquetes también implementaran dicha función.

También he escrito anteriormente sobre cómo usar la función de espacios de trabajo de Yarn Classic con y sin Lerna, si está interesado. Pero esta publicación solo cubrirá algunos comandos necesarios para ayudarlo a administrar las dependencias en una configuración de espacios de trabajo de Yarn Classic.

# Installing all dependencies for all workspaces
$ yarn
# display dependency tree
$ yarn workspaces info
# run start command only for one package
$ yarn workspace awesome-package start
# add Webpack to package
$ yarn workspace awesome-package add -D webpack
# add React to all packages
$ yarn add react -W

Baya de hilo

Yarn Berry presentó espacios de trabajo desde el principio porque su implementación se basó en los conceptos de Yarn Classic. En un comentario de Reddit , un desarrollador principal de Yarn Berry dio una breve descripción general de las funciones orientadas al espacio de trabajo, que incluyen:

Yarn Berry hace un uso intensivo de los protocolos , que se pueden usar en los campos dependencieso de los archivos. Uno de ellos es el protocolo .devDependenciespackage.jsonworkspace:

A diferencia de los espacios de trabajo de Yarn Classic, Yarn Berry define explícitamente que una dependencia debe ser uno de los paquetes de este monorrepositorio. De lo contrario, Yarn Berry podría intentar obtener una versión de un registro remoto si las versiones no coinciden.

{
  // ...
  "dependencies": {
    "@doppelmutzi/hooks": "workspace:*",
    "http-server": "14.0.0",
    // ...
  }  
}

pnpm

Con su workspace:protocolo, pnpm facilita proyectos monorepo de manera similar a Yarn Berry. Muchos comandos pnpm aceptan opciones como --recursive( -r) o --filterque son especialmente útiles en un contexto monorepo. Su comando de filtrado nativo también es un buen complemento o reemplazo para Lerna.

# prune all workspaces  
pnpm -r exec -- rm -rf node_modules && rm pnpm-lock.yaml  
# run all tests for all workspaces with scope @doppelmutzi
pnpm recursive run test --filter @doppelmutzi/

Rendimiento y eficiencia del espacio en disco

El rendimiento es una parte crucial de la toma de decisiones. Esta sección muestra mis puntos de referencia basados ​​en un proyecto pequeño y uno mediano. Aquí hay algunas notas sobre los proyectos de muestra:

  • Ningún conjunto de puntos de referencia utiliza funciones de espacio de trabajo
  • El pequeño proyecto especifica 33 dependencias.
  • El proyecto mediano especifica 44 dependencias.

Realicé mediciones para tres casos de uso (UC), una vez para cada una de nuestras variantes de administrador de paquetes. Para conocer la evaluación detallada con explicaciones, echa un vistazo a los resultados del proyecto 1 (P1) y del proyecto 2 (P2) .

  • UC 1: Sin caché/almacén, sin archivos de bloqueo, sin node_moduleso.pnp.cjs
  • UC 2: existe caché/almacenamiento, no hay archivos de bloqueo, no node_moduleso.pnp.cjs
  • UC 3: existe caché/almacenamiento, existen archivos de bloqueo, no node_moduleso.pnp.cjs

Usé la herramienta gnomon para medir el tiempo que consume una instalación (por ejemplo, $ yarn | gnomon). Además, medí los tamaños de los archivos generados, por ejemplo, $ du -sh node_modules.

Con mis proyectos y mis medidas, Yarn Berry PnP strict fue el ganador en términos de velocidad de instalación para todos los casos de uso y ambos proyectos.

Resultados de desempeño para el Proyecto 1
Métodonpm
v8.1.2
Hilo clásico
v1.23.0
pnpm
v6.24.4
Hilo Berry PnP suelto
v3.1.1
Hilo Berry PnP estricto
v3.1.1
Baya de hilo node_modules
v3.1.1
Hilo Berry
pnpm
v3.1.1
CU 186.63s108.89s43.58s31.77s30.13 s56.64s60.91s
CU 241.54s65.49s26.43 s12.46s12,66 s46.36s40.74s
CU 323.59s40.35s20.32s1,61 s1,36 s28.72s31.89s
archivos y tamañopackage-lock.json: 1.3M
node_modules: 467M
node_modules: 397M
yarn.lock: 504K
pnpm-lock.yaml: 412K
node_modules: 319M
yarn.lock: 540K
caché: 68M
desenchufado: 29M
.pnp.cjs: 1,6M
yarn.lock: 540K
caché: 68M
desenchufado: 29M
.pnp.cjs: 1,5M
node_modules: 395M
yarn.lock: 540K
caché: 68M
node_modules: 374M
yarn.lock: 540K
caché: 68M

 

Resultados de desempeño para el Proyecto 2
Métodonpm
v8.1.2
Hilo clásico v1.23.0pnpm
v6.24.4
Hilo Berry PnP suelto
v3.1.1
Hilo Berry PnP estricto
v3.1.1
Baya de hilo node_modules
v3.1.1
Hilo Berry
pnpm
v3.1.1
CU 134.91s43.26s15,6 s13.92s6.44s23.62s20.09s
CU 27.92s33.65s8.86s7.09s5,63 s15.12 s14.93 s
CU 35.09s15.64 s4,73 s0,93 s0,79 s8.18 s6.02s
archivos y tamañopackage-lock.json: 684K
node_modules: 151M
yarn.lock: 268K
node_modules: 159M
pnpm-lock.yaml: 212K
node_modules: 141M
.pnp.cjs: 1.1M :
.pnp.loader.mjs8.0K
yarn.lock: 292K
.yarn: 38M
.pnp.cjs: 1.0M
.pnp.loader.mjs: 8.0K
yarn.lock: 292K
.yarn: 38M
yarn.lock: 292K
node_modules: 164M
caché: 34M
yarn.lock: 292K
node_modules: 156M
caché: 34M

Estos son los puntos de referencia oficiales del equipo de Yarn Berry y de pnpm .

Características de seguridad

sobre el nivel del mar

npm ha sido demasiado indulgente cuando se trata de trabajar con paquetes defectuosos y ha experimentado algunas vulnerabilidades de seguridad que afectaron directamente a muchos proyectos. Por ejemplo, en la versión 5.7.0, cuando ejecutaba el sudo npmcomando en un sistema operativo Linux, era posible cambiar la propiedad de los archivos del sistema, lo que hacía que el sistema operativo quedara inutilizable.

Otro incidente ocurrió en 2018 e involucró el robo de Bitcoin. Básicamente, el popular paquete EventStream de Node.js agregó una dependencia maliciosa en su versión 3.3.6. Este paquete malicioso contenía una carga útil encriptada que intentaba robar Bitcoin de la máquina del desarrollador.

Para ayudar a resolver estos problemas, las versiones más recientes de npm utilizan el SHA-512algoritmo de criptografía package-lock.jsonpara verificar la integridad de los paquetes que instala.

En general, npm ha hecho cada vez más para cerrar sus brechas de seguridad, especialmente aquellas que se hicieron más obvias en comparación con Yarn.

Hilo

Tanto Yarn Classic como Yarn Berry han verificado la integridad de cada paquete con sumas de verificación almacenadas yarn.lockdesde el principio. Yarn también intenta evitar que recuperes paquetes maliciosos que no están declarados en tu package.jsondurante la instalación: si se encuentra una discrepancia, la instalación se cancela.

Yarn Berry en modo PnP no sufre los problemas de seguridad del node_modulesenfoque tradicional. A diferencia de Yarn Classic, Yarn Berry mejora la seguridad de la ejecución de comandos. Solo puede ejecutar binarios de dependencias que haya declarado explícitamente en su archivo package.json. Esta función de seguridad es similar a pnpm, que describiré a continuación.

pnpm

pnpm también usa sumas de verificación para verificar la integridad de cada paquete instalado antes de que se ejecute su código.

Como mencionamos anteriormente, npm y Yarn Classic tienen problemas de seguridad debido a la elevación . pnpm evita esto porque su modelo no usa elevación; en su lugar, genera node_modulescarpetas anidadas que eliminan el riesgo de acceso de dependencia ilegal. Esto significa que las dependencias solo pueden acceder a otras dependencias si se declaran explícitamente en package.json.

Esto es especialmente crucial en una configuración monorepo, como comentamos, porque el algoritmo de elevación a veces puede conducir a dependencias fantasma y doppelgangers .

Adopción por proyectos populares

Analicé muchos proyectos populares de código abierto para tener una idea de qué administradores de paquetes usa hoy en día la "élite de desarrolladores". Era importante para mí que estos proyectos se mantuvieran activamente y se actualizaran por última vez recientemente. Esto podría darle otra perspectiva al elegir un administrador de paquetes.

sobre el nivel del marHilo clásicoBaya de hilopnpm
EsbeltoReaccionares (con node_modules)Ver 3
PreactuarAngularLibro de cuentos (con node_modules)lista de navegadores
Express.jsHumanoBabel (con node_modules)Prisma
MeteoritoSiguiente.jsKit de herramientas Redux (con node_modules)SvelteKit
Servidor Apologatsby  
 Siguiente  
 Crear aplicación de reacción  
 webpack-cli  
 Emoción  

Curiosamente, en el momento de escribir este artículo, ninguno de estos proyectos de código abierto utiliza un enfoque PnP.

Conclusión

El estado actual de los administradores de paquetes es excelente. Prácticamente hemos alcanzado la paridad de características entre todos los principales administradores de paquetes. Pero aún así, difieren bastante bajo el capó.

pnpm se parece a npm al principio porque su uso de CLI es similar, pero la administración de dependencias es muy diferente; El método de pnpm conduce a un mejor rendimiento y la mejor eficiencia de espacio en disco. Yarn Classic sigue siendo muy popular, pero se considera un software heredado y es posible que el soporte se elimine en un futuro próximo. Yarn Berry PnP es el nuevo chico del bloque, pero no se ha dado cuenta completamente de su potencial para revolucionar el panorama de los administradores de paquetes una vez más.

A lo largo de los años, muchos usuarios han preguntado quién usa qué administradores de paquetes y, en general, parece que la gente está especialmente interesada en la madurez y adopción de Yarn Berry PnP.

El objetivo de este artículo es brindarle muchas perspectivas para que tome una decisión sobre qué administrador de paquetes usar por su cuenta. Me gustaría señalar que no recomiendo un administrador de paquetes en particular. Depende de cómo sopeses los diferentes requisitos, ¡así que aún puedes elegir lo que quieras! 

Fuente: https://blog.logrocket.com/javascript-package-managers-compared/

#javascript #yarn #npm #pnpm 

Olivia jons

1624638940

¿Copia de seguridad de sus archivos de Gmail sin problemas y de forma fiable?

Los usuarios pueden hacer una copia de seguridad de sus archivos de Gmail utilizando este software Mailvita Gmail Backup probado profesionalmente. La aplicación proporciona a los usuarios obtener un resultado cualitativo en todo momento. La aplicación eth no tiene ningún obstáculo ni ningún tipo de problema al hacer una copia de seguridad de sus archivos de Gmail. Este software de copia de seguridad de Gmail proporciona una amplia plataforma a todos sus usuarios para realizar copias de seguridad de los archivos de Gmail.

DESCARGAR AHORA EN MAC
DESCARGAR AHORA EN WINDOWS

Con este increíble software de copia de seguridad de Gmail, los usuarios pueden obtener un resultado preciso y también mantiene la integridad de los archivos. Además, la aplicación promueve la copia de seguridad de los archivos de Gmail con total precisión. La originalidad de los archivos se mantiene tal como está gracias a la herramienta. La aplicación proporciona un resultado eficiente y sin esfuerzo a la herramienta en todo momento. Los usuarios pueden realizar copias de seguridad de sus archivos de Gmail cómodamente. Es una utilidad inteligente para ser utilizada por los usuarios. Con solo unos pocos clics, la aplicación proporciona el resultado deseado por el usuario. Con esta increíble aplicación, se proporciona una copia de seguridad directa de los archivos de Gmail. Además, la aplicación conserva las metapropiedades de los archivos tal cual están. Los usuarios pueden hacer una copia de seguridad de la mayor parte de los archivos de Gmail con la ayuda de esta herramienta. Se realiza una copia de seguridad de todos los datos, incluidos correos electrónicos, mensajes, notas y archivos adjuntos, mediante esta aplicación de copia de seguridad de Gmail. Proporciona una amplia plataforma para todos los usuarios. Con un solo clic, los usuarios pueden obtener un resultado satisfactorio en todo momento. Los usuarios no se enfrentan a ningún daño o fuga de datos al hacer una copia de seguridad de los archivos de Gmail. Además, la compatibilidad de la aplicación es asombrosa, por lo que los usuarios pueden usar rápidamente esta asombrosa aplicación en cualquiera de los sistemas operativos de Windows.

Necesidad de hacer una copia de seguridad de los archivos de Gmail

Los usuarios deben hacer una copia de seguridad de los archivos de Gmail, ya que Gmail es una aplicación basada en la nube, por lo que hay más posibilidades de que los datos se dañen o se pirateen. Si los usuarios hacen una copia de seguridad de sus archivos de Gmail en el formato de su elección, los usuarios pueden mantener sus archivos de Gmail de forma segura.

Funciones clave de la aplicación

Las características clave de esta increíble aplicación se proporcionan a continuación. Háganos saber acerca de estas características profunda y agudamente.

• Copia de seguridad masiva: - Los usuarios pueden realizar copias de seguridad de cualquier cantidad de archivos de Gmail con esta increíble aplicación. Los usuarios pueden hacer una copia de seguridad de todos los archivos de Gmail. Los usuarios no enfrentan ningún tipo de restricción al hacer una copia de seguridad de los archivos de Gmail.

• Mantiene la precisión: - Los usuarios siempre obtienen un resultado preciso de la herramienta en todo momento. Además, la aplicación mantiene la integridad de la aplicación. Las propiedades de los archivos permanecen intactas por la aplicación que utiliza esta increíble herramienta de copia de seguridad de Gmail.

Pasos para hacer una copia de seguridad de los archivos de Gmail

Para realizar una copia de seguridad, los usuarios de los archivos de Gmail que utilizan esta increíble herramienta de copia de seguridad de Gmail deben seguir algunos pasos que se proporcionan a continuación. Estos pasos son fáciles de seguir por cualquier usuario sin ningún tipo de problema.

Paso 1- Primero instale la aplicación de copia de seguridad de Gmail en su sistema operativo Windows
Paso 2- Inicie la aplicación
Paso 3- Autentíquese ingresando los detalles correctos de la identificación de correo electrónico y la contraseña de su cuenta de Gmail.
Paso 4- Seleccione la carpeta de la que desea realizar una copia de seguridad
Paso 5- Elija el formato en el que desea realizar la copia de seguridad de los archivos de Gmail.
Paso 6- Seleccione el destino en el que desea guardar los archivos de Gmail respaldados.
Paso 7- Por último, haga clic en el botón “Hacer copia de seguridad ahora”

Estos pasos pueden ser procesados ​​por cualquier usuario sin enfrentarse a ningún obstáculo. Cualquier usuario novato puede respaldar fácilmente sus archivos de Gmail sin enfrentar ningún obstáculo. Además, si los usuarios tienen alguna consulta o se enfrentan a algún tipo de obligación, los usuarios pueden consultar las capturas de pantalla de los pasos.

Declaración concluyente

Todos los usuarios que quieran hacer una copia de seguridad de sus archivos de Gmail deben probar esta increíble herramienta de copia de seguridad de Gmail. Esta aplicación de copia de seguridad de Gmail es la mejor plataforma para utilizar. La aplicación no pierde ni un solo archivo de Gmail mientras realiza la copia de seguridad. Para probar la aplicación y conocerla, esta herramienta inteligente proporciona una versión de demostración. La versión de demostración es gratuita para todos los usuarios. Si los usuarios quieren hacer una copia de seguridad de una cantidad ilimitada de archivos de Gmail, entonces tienen que comprar la versión con licencia de la aplicación que les permitirá hacer copias de seguridad de tantos archivos como quieran convertir porque la versión de demostración solo permite unos pocos. copias de seguridad de los archivos de Gmail. Aparte de eso, la versión con licencia también otorga una actualización gratuita de por vida de la aplicación. Los profesionales recomiendan comprar la versión con licencia de la aplicación después, primero, pruebe la versión de demostración.

Si la herramienta se enfrenta a algún tipo de problema al convertir los archivos PST de Outlook, la herramienta también proporciona asistencia al cliente las 24 horas del día, los 7 días de la semana.

Para obtener más información, visite aquí: - https://www.mailvita.com/gmail-backup-for-mac/

#herramienta de copia de seguridad de gmail #gmail backup tool #gmail backup