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.
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.
Wir werden esbuild für den Bundler verwenden.
yarn add esbuild --save-dev
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()
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
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.
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.
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.
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
"scripts": { "build:tsc": "yarn tsc -p tsconfig.json", "build": "vite-node ./scripts/build.ts && yarn build:tsc", }
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:
Dies ist jedoch nicht die einzige Option. Sie können Ihr Paket auch mit zwei Einstiegspunkten für CommonJS und ESM veröffentlichen.
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()
"main": "dist/index.cjs", "module": "dist/index.js", "type": "module", "exports": { ".": { "import": "./dist/index.js", "require": "./dist/index.cjs", "types": "./dist/index.d.ts" } },
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