Vous devez utiliser un bundler tel que esbuild qui compilera votre projet et regroupera toutes ses dépendances avec lui afin qu'elles ne soient pas importées. Cela contourne le problème d'incompatibilité ESM/CommonJS.
Si vous êtes impatient, vous pouvez accéder directement au code avec cet exemple d'implémentation.
En préparant la sortie de mon nouveau projet Token.js ce week-end, j'ai rencontré un problème assez frustrant. Je voulais que mon package prenne en charge CommonJS en plus d'ESM, mais j'avais de pures dépendances ESM. Les purs croisés de l'ESM seront peut-être assez mécontents que je le dise, mais si vous créez un package NPM et souhaitez qu'il soit largement utilisé, vous devez toujours prendre en charge CommonJS en 2024.
Token.js est un simple SDK TypeScript qui vous permet d'intégrer 60 LLM de 9 fournisseurs différents (OpenAI, Anthropic, Cohere, etc). Plug sans vergogne, jetez-y un œil et dites-moi ce que vous en pensez si vous aimez l'IA générative.
Il existe désormais un certain nombre de ressources en ligne expliquant comment créer des projets Javascript pour ESM, CommonJS ou les deux. Cependant, j'ai particulièrement eu du mal à gérer le fait que j'avais des dépendances qui étaient purement ESM. J'ai trouvé cela assez difficile à gérer car je ne suis pas familier avec les bundlers (j'ai principalement travaillé sur des backends d'applications Web) et je n'ai pas pu trouver un bon guide sur le sujet.
Donc, si quelqu'un d'autre rencontre ce problème, voici la solution.
Nous utiliserons esbuild pour le bundler.
yarn add esbuild --save-dev
Nous aurons besoin d'un simple script de build pour exécuter esbuild et afficher les résultats.
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()
Exécutez avec votre environnement d'exécution préféré.
"scripts": { "build": "vite-node ./scripts/build.ts", }
Personnellement, j'adore vite-node. Donc, si vous voulez suivre exactement, vous devrez l'installer :
yarn add vite-node --save-dev
yarn build
Cela entraînera la construction de votre projet avec esbuild et vous verrez un nouveau fichier, dist/index.cjs, qui est la version CommonJS de votre package.
Mettez à jour votre package.json pour qu'il pointe vers votre point d'entrée CommonJS.
"main": "dist/index.cjs",
Bam ! Et voilà, vous avez maintenant construit votre package pour CommonJS. Cela fonctionnera même si vous avez des dépendances ESM car les dépendances seront regroupées
avec votre colis.
Les dépendances sont incluses dans la sortie en raison du champ bundle : true lorsque esbuild est appelé.
Bien que techniquement cela ne soit pas requis, vous souhaiterez très probablement également des déclarations TypeScript qu'esbuild ne produit malheureusement pas pour le moment. Donc pour générer
ceux-là, vous voudrez utiliser le tsc normal.
L'ajout de ces options à votre fichier tsconfig.json entraînera la sortie uniquement des déclarations TypeScript. C'est exactement ce que nous souhaitons puisque le reste du package
est en cours de construction avec esbuild.
"declaration": true, "declarationDir": "./dist", "emitDeclarationOnly": true
"scripts": { "build:tsc": "yarn tsc -p tsconfig.json", "build": "vite-node ./scripts/build.ts && yarn build:tsc", }
Ce guide recommande de générer uniquement un seul point d'entrée CommonJS pour votre package. Personnellement, je pense que c'est la meilleure option pour deux raisons :
Cependant, ce n’est pas la seule option. Vous pouvez également publier votre package avec deux points d'entrée pour CommonJS et 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()
"main": "dist/index.cjs", "module": "dist/index.js", "type": "module", "exports": { ".": { "import": "./dist/index.js", "require": "./dist/index.cjs", "types": "./dist/index.d.ts" } },
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3