您必須使用諸如 esbuild 之類的打包程序,它將編譯您的專案並將其所有依賴項與其一起打包,這樣它們就不會被導入。這繞過了 ESM/CommonJS 不相容問題。
如果你不耐煩,可以直接看這個範例實現的程式碼。
在周末準備發布我的新專案 Token.js 時,我遇到了一個非常令人沮喪的問題。我希望我的包除了 ESM 之外還支援 CommonJS,但我有純粹的 ESM 依賴項。純粹的 ESM 鬥士們可能對我這麼說很不高興,但如果你正在建造一個 NPM 包並希望它被廣泛使用,你仍然需要在 2024 年支持 CommonJS。
Token.js 是一個簡單的 TypeScript SDK,可讓您整合來自 9 個不同提供者(OpenAI、Anthropic、Cohere 等)的 60 個 LLM。無恥的插件,如果你喜歡產生人工智慧,請檢查一下並告訴我你的想法。
現在有許多線上資源討論如何為 ESM、CommonJS 或兩者建立 Javascript 專案。然而,我特別難以處理這樣一個事實:我有純 ESM 的依賴項。我發現這很難處理,因為我不熟悉捆綁程式(我主要從事 Web 應用程式後端),也無法找到有關該主題的良好指南。
因此,如果其他人遇到此問題,這裡是解決方案。
我們將使用 esbuild 作為捆綁器。
yarn add esbuild --save-dev
我們需要一個簡單的建置腳本來執行 esbuild 並輸出結果。
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()
使用您首選的運行時運行。
"scripts": { "build": "vite-node ./scripts/build.ts", }
我個人很喜歡vite-node。因此,如果您想完全遵循,則需要安裝:
yarn add vite-node --save-dev
yarn build
這將導致使用 esbuild 建立您的項目,您將看到一個新檔案 dist/index.cjs,它是您的套件的 CommonJS 建置。
更新您的 package.json 以指向您的 CommonJS 入口點。
"main": "dist/index.cjs",
嘭!現在,您已經為 CommonJS 建立了套件。即使您有 ESM 依賴項,這也將起作用,因為依賴項將被捆綁
連同您的包裹。
由於呼叫 esbuild 時存在欄位“bundle: true”,因此依賴項包含在輸出中。
雖然技術上不需要,但您很可能還需要 TypeScript 聲明,遺憾的是 esbuild 目前無法輸出這些聲明。所以生成
那些,你會想要使用普通的 tsc。
將這些選項新增至 tsconfig.json 檔案將導致僅輸出 TypeScript 聲明。這正是我們想要的,因為包的其餘部分
正在使用 esbuild 建置。
"declaration": true, "declarationDir": "./dist", "emitDeclarationOnly": true
"scripts": { "build:tsc": "yarn tsc -p tsconfig.json", "build": "vite-node ./scripts/build.ts && yarn build:tsc", }
本指南建議僅為您的包輸出單一 CommonJS 入口點。就我個人而言,我認為這是最好的選擇,原因有兩個:
然而,這不是唯一的選擇。您也可以使用 CommonJS 和 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" } },
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3