„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Erstellen von NPM-Paketen für CommonJS mit ESM-Abhängigkeiten

Erstellen von NPM-Paketen für CommonJS mit ESM-Abhängigkeiten

Veröffentlicht am 14.08.2024
Durchsuche:343

Building NPM packages for CommonJS with ESM dependencies

TLDR

Sie müssen einen Bundler wie esbuild verwenden, der Ihr Projekt kompiliert und alle seine Abhängigkeiten bündelt, damit sie nicht importiert werden. Dadurch wird das ESM/CommonJS-Inkompatibilitätsproblem umgangen.

Wenn Sie ungeduldig sind, können Sie mit dieser Beispielimplementierung direkt zum Code gehen.

Kontext

Als ich mich am Wochenende auf die Veröffentlichung meines neuen Projekts Token.js vorbereitete, stieß ich auf ein ziemlich frustrierendes Problem. Ich wollte, dass mein Paket zusätzlich zu ESM auch CommonJS unterstützt, aber ich hatte reine ESM-Abhängigkeiten. Die reinen ESM-Kreuzfahrer da draußen mögen ziemlich unzufrieden sein, wenn ich das sage, aber wenn Sie ein NPM-Paket erstellen und möchten, dass es weit verbreitet ist, müssen Sie CommonJS auch im Jahr 2024 unterstützen.

Token.js ist ein einfaches TypeScript-SDK, mit dem Sie 60 LLMs von 9 verschiedenen Anbietern (OpenAI, Anthropic, Cohere usw.) integrieren können. Shameless Plug, schau es dir an und lass mich wissen, was du denkst, wenn du dich für generative KI interessierst.

Jetzt gibt es online eine Reihe von Ressourcen, die diskutieren, wie man Javascript-Projekte für ESM, CommonJS oder beide erstellt. Allerdings hatte ich insbesondere Probleme damit, mit der Tatsache umzugehen, dass ich Abhängigkeiten hatte, die reines ESM waren. Es fiel mir ziemlich schwer, damit umzugehen, da ich mit Bundlern nicht vertraut bin (ich habe hauptsächlich an Webapp-Backends gearbeitet) und keinen guten Leitfaden zu diesem Thema finden konnte.

Wenn also jemand anderes auf dieses Problem stößt, finden Sie hier die Lösung.

Führung

Esbuild installieren

Wir werden esbuild für den Bundler verwenden.

yarn add esbuild --save-dev

Erstellen Sie ein Build-Skript

Wir benötigen ein einfaches Build-Skript, um esbuild auszuführen und die Ergebnisse auszugeben.

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()

Fügen Sie Ihrer package.json ein Build-Skript hinzu

Mit Ihrer bevorzugten Laufzeit ausführen.

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

Ich persönlich liebe vite-node. Wenn Sie also genau mitmachen möchten, müssen Sie Folgendes installieren:

yarn add vite-node --save-dev

Erstellen Sie Ihr Projekt

yarn build

Dadurch wird Ihr Projekt mit esbuild erstellt und Sie sehen eine neue Datei, dist/index.cjs, die der CommonJS-Build Ihres Pakets ist.

Einstiegspunkt konfigurieren

Aktualisieren Sie Ihre package.json so, dass sie auf Ihren CommonJS-Einstiegspunkt verweist.

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

Bam! Nun haben Sie Ihr Paket für CommonJS erstellt. Dies funktioniert auch dann, wenn Sie ESM-Abhängigkeiten haben, da die Abhängigkeiten gebündelt werden
zusammen mit Ihrem Paket.

Die Abhängigkeiten sind aufgrund des Feldes bundle: true in der Ausgabe enthalten, wenn esbuild aufgerufen wird.

TypeScript-Deklarationen

Obwohl technisch nicht erforderlich, möchten Sie höchstwahrscheinlich auch TypeScript-Deklarationen, die esbuild derzeit leider nicht ausgibt. Um also
zu generieren Für diese sollten Sie normales tsc verwenden.

Aktualisieren Sie Ihre tsconfig.json

Das Hinzufügen dieser Optionen zu Ihrer tsconfig.json-Datei führt dazu, dass nur die TypeScript-Deklarationen ausgegeben werden. Das ist genau das, was wir wollen, da der Rest des Pakets
wird mit esbuild erstellt.

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

Aktualisieren Sie Ihr Build-Skript

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

Duale Einstiegspunkte

Diese Anleitung empfiehlt, nur einen einzigen CommonJS-Einstiegspunkt für Ihr Paket auszugeben. Persönlich denke ich, dass dies aus zwei Gründen die beste Option ist:

  • Minimiert die Bundle-Größe
  • Vermeidet die Gefahr von Doppelpaketen

Dies ist jedoch nicht die einzige Option. Sie können Ihr Paket auch mit zwei Einstiegspunkten für CommonJS und ESM veröffentlichen.

Aktualisieren Sie Ihr Build-Skript, um einen ESM-Build einzuschließen

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()

Aktualisieren Sie Ihre package.json-Datei, um zwei Einstiegspunkte einzuschließen

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

Quellcode

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/ryan_pate_f494c0931176673/how-to-build-npm-packages-for-commonjs-with-pure-esm-dependencies-38jm?1 Bei Verstößen wenden Sie sich bitte an Study_golang @163.com löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3