ESM 依存関係を使用した CommonJS 用の NPM パッケージの構築

PHPz
リリース: 2024-07-18 13:43:15
オリジナル
530 人が閲覧しました

Building NPM packages for CommonJS with ESM dependencies

TLDR

プロジェクトをコンパイルし、依存関係がインポートされないようにすべての依存関係をバンドルする esbuild などのバンドラーを使用する必要があります。これにより、ESM/CommonJS の非互換性の問題が回避されます。

せっかちな場合は、この実装例のコードに直接進んでください。

コンテクスト

週末に新しいプロジェクト Token.js をリリースする準備をしているときに、非常にイライラする問題に遭遇しました。パッケージで ESM に加えて CommonJS もサポートしたいと考えていましたが、純粋な ESM 依存関係がありました。純粋な ESM 活動家たちは、私がこのことを言うことに非常に不満を抱いているかもしれませんが、NPM パッケージを構築していて、それを広く使用したい場合は、2024 年になっても CommonJS をサポートする必要があります。

Token.js は、9 つ​​の異なるプロバイダー (OpenAI、Anthropic、Cohere など) の 60 以上の LLM を統合できるシンプルな TypeScript SDK です。恥知らずなプラグイン、ぜひチェックして、生成 AI に興味がある方は感想を聞かせてください。

現在、ESM、CommonJS、またはその両方用の Javascript プロジェクトを構築する方法を説明するオンライン リソースが多数あります。ただし、純粋な ESM の依存関係があるという事実に対処するのに特に問題がありました。私はバンドラーに詳しくなく (主に Web アプリのバックエンドに取り組んできました)、このトピックに関する適切なガイドを見つけることができなかったため、これに対処するのは非常に難しいと感じました。

他の誰かがこの問題に遭遇している場合は、ここで解決策を示します。

ガイド

エスビルドをインストールする

バンドラーには esbuild を使用します。

yarn add esbuild --save-dev
ログイン後にコピー

ビルドスクリプトを作成する

esbuild を実行して結果を出力するには、単純なビルド スクリプトが必要です。

import esbuild from 'esbuild'

const entrypoint = "<your entrypoint here>"
const tsconfig = "<your tsconfig path here>"

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()
ログイン後にコピー

package.jsonにビルドスクリプトを追加します。

好みのランタイムで実行します。

"scripts": {
  "build": "vite-node ./scripts/build.ts",
}
ログイン後にコピー

私は個人的に vite-node が大好きです。したがって、正確に従うには、それをインストールする必要があります:

yarn add vite-node --save-dev
ログイン後にコピー

プロジェクトを構築する

yarn build
ログイン後にコピー

これにより、esbuild を使用してプロジェクトがビルドされ、パッケージの CommonJS ビルドである新しいファイル dist/index.cjs が表示されます。

エントリポイントの構成

CommonJS エントリポイントを指すように package.json を更新します。

"main": "dist/index.cjs",
ログイン後にコピー

バン!これで、CommonJS 用のパッケージが構築されました。依存関係はバンドルされるため、ESM 依存関係がある場合でも機能します
パッケージと一緒に。

esbuild が呼び出されたときにフィールド Bundle: true が設定されているため、依存関係が出力に含まれます。

TypeScript の宣言

技術的には必須ではありませんが、TypeScript 宣言も必要になる可能性が高く、残念ながら現時点では esbuild は出力しません。したがって、
を生成するには それらの場合は、通常の tsc を使用することをお勧めします。

tsconfig.json を更新します

これらのオプションを 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 エントリポイントのみを出力することをお勧めします。個人的には、次の 2 つの理由から、これが最良のオプションだと考えています:

  • バンドルのサイズを最小化します
  • 二重パッケージの危険を回避

ただし、これが唯一の選択肢ではありません。 CommonJS と ESM のデュアル エントリポイントを使用してパッケージを公開することもできます。

ビルド スクリプトを更新して ESM ビルドを含める

import esbuild from 'esbuild'

const entrypoint = "<your entrypoint here>"
const tsconfig = "<your tsconfig path here>"

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()
ログイン後にコピー

package.json ファイルを更新してデュアル エントリポイントを含めます

"main": "dist/index.cjs",
"module": "dist/index.js",
"type": "module",
"exports": {
  ".": {
    "import": "./dist/index.js",
    "require": "./dist/index.cjs",
    "types": "./dist/index.d.ts"
  }
},
ログイン後にコピー

ソースコード

以上がESM 依存関係を使用した CommonJS 用の NPM パッケージの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!