"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Creación de paquetes NPM para CommonJS con dependencias de ESM

Creación de paquetes NPM para CommonJS con dependencias de ESM

Publicado el 2024-08-14
Navegar:153

Building NPM packages for CommonJS with ESM dependencies

TLDR

Tienes que usar un paquete como esbuild que compilará tu proyecto y agrupará todas sus dependencias junto con él para que no se importen. Esto evita el problema de incompatibilidad de ESM/CommonJS.

Si estás impaciente, puedes ir directamente al código con esta implementación de ejemplo.

Contexto

Mientras me preparaba para lanzar mi nuevo proyecto Token.js durante el fin de semana, me encontré con un problema bastante frustrante. Quería que mi paquete fuera compatible con CommonJS además de ESM, pero tenía dependencias puras de ESM. Los defensores puros de ESM pueden estar bastante descontentos con que lo diga, pero si está creando un paquete NPM y desea que se use ampliamente, aún necesita admitir CommonJS en 2024.

Token.js es un SDK de TypeScript simple que le permite integrar 60 LLM de 9 proveedores diferentes (OpenAI, Anthropic, Cohere, etc.). Enchufe descarado, compruébalo y déjame saber qué piensas si te gusta la IA generativa.

Ahora hay una serie de recursos en línea que analizan cómo crear proyectos Javascript para ESM, CommonJS o ambos. Sin embargo, específicamente tuve problemas para lidiar con el hecho de que tenía dependencias que eran puramente ESM. Me resultó bastante difícil lidiar con esto porque no estoy familiarizado con los paquetes (he trabajado principalmente en backends de aplicaciones web) y no pude encontrar una buena guía sobre el tema.

Entonces, si alguien más tiene este problema, aquí está la solución.

Guía

Instalar esbuild

Usaremos esbuild para el paquete.

yarn add esbuild --save-dev

Crear un script de compilación

Necesitaremos un script de compilación simple para ejecutar esbuild y generar los resultados.

import esbuild from 'esbuild'

const entrypoint = ""
const tsconfig = ""

const build = async () => {
  await Promise.all([
    // bundle for commonjs
    esbuild.build({
      entryPoints: [entrypoint],
      bundle: true,
      minify: true,
      format: 'cjs',
      outfile: `./dist/index.cjs`,
      platform: 'node',
      treeShaking: true,
      tsconfig,
    }),
  ])
}

build()

Agregue un script de compilación a su paquete.json

Ejecuta con tu tiempo de ejecución preferido.

"scripts": {
  "build": "vite-node ./scripts/build.ts",
}

Personalmente me encanta vite-node. Entonces, si quieres seguir exactamente, necesitarás instalarlo:

yarn add vite-node --save-dev

Construye tu proyecto

yarn build

Esto hará que construyas tu proyecto con esbuild y verás un nuevo archivo, dist/index.cjs, que es la compilación CommonJS de tu paquete.

Configurar punto de entrada

Actualiza tu paquete.json para que apunte a tu punto de entrada de CommonJS.

"main": "dist/index.cjs",

¡Bam! Ahí lo tienes, ahora has creado tu paquete para CommonJS. Esto funcionará incluso si tiene dependencias de ESM porque las dependencias estarán agrupadas
junto con tu paquete.

Las dependencias se incluyen en la salida debido al paquete de campos: verdadero cuando se llama a esbuild.

Declaraciones de TypeScript

Aunque técnicamente no es necesario, es muy probable que también desee declaraciones de TypeScript que desafortunadamente esbuild no genera en este momento. Entonces para generar
esos, querrás usar tsc normal.

Actualiza tu tsconfig.json

Agregar estas opciones a su archivo tsconfig.json hará que solo se generen las declaraciones de TypeScript. Esto es exactamente lo que queremos desde el resto del paquete
se está construyendo con esbuild.

"declaration": true,
"declarationDir": "./dist",
"emitDeclarationOnly": true

Actualiza tu script de compilación

"scripts": {
  "build:tsc": "yarn tsc -p tsconfig.json",
  "build": "vite-node ./scripts/build.ts && yarn build:tsc",
}

Puntos de entrada duales

Esta guía recomienda generar solo un único punto de entrada CommonJS para su paquete. Personalmente creo que esta es la mejor opción por dos motivos:

  • Minimiza el tamaño del paquete
  • Evita el riesgo de doble paquete

Sin embargo, esta no es la única opción. También puede publicar su paquete con puntos de entrada duales para CommonJS y ESM.

Actualice su script de compilación para incluir una compilación de ESM

import esbuild from 'esbuild'

const entrypoint = ""
const tsconfig = ""

const build = async () => {
  await Promise.all([
    // bundle for commonjs
    esbuild.build({
      entryPoints: [entrypoint],
      bundle: true,
      minify: true,
      format: 'cjs',
      outfile: `./dist/index.cjs`,
      platform: 'node',
      treeShaking: true,
      tsconfig,
    }),
    // bundle for ESM
    esbuild.build({
      entryPoints: [entrypoint],
      bundle: true,
      minify: true,
      format: 'esm',
      outfile: `./dist/index.js`,
      platform: 'node',
      treeShaking: true,
      tsconfig,
    }),
  ])
}

build()

Actualice su archivo package.json para incluir puntos de entrada duales

"main": "dist/index.cjs",
"module": "dist/index.js",
"type": "module",
"exports": {
  ".": {
    "import": "./dist/index.js",
    "require": "./dist/index.cjs",
    "types": "./dist/index.d.ts"
  }
},

código fuente

Declaración de liberación Este artículo se reproduce en: https://dev.to/ryan_pate_f494c0931176673/how-to-build-npm-packages-for-commonjs-with-pure-esm-dependencies-38jm?1 Si hay alguna infracción, comuníquese con Study_golang @163.com eliminar
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3