Node.js と esbuild: cjs と esm の混合に注意してください
TL;DR
esbuild を使用して、cjs と esm のエントリ ポイントが混在する npm パッケージに依存するコードを --platform=node でバンドルする場合は、次の経験則を使用します。
- --bundle を使用する場合は、--format を cjs に設定します。これは、トップレベルの await を備えた esm モジュールを除くすべての場合に機能します。
- --format=esm は使用できますが、このようなポリフィルが必要です。
- --packages=external を使用する場合は、--format を esm に設定します。
cjs と esm の違いについて疑問がある場合は、「Node.js: cjs、バンドラー、および esm の簡単な歴史」を参照してください。
症状
--platform=node を指定して esbuild バンドル コードを実行すると、次のいずれかのランタイム エラーが発生する可能性があります:
Error: Dynamic require of "<module_name>" is not supported
Error [ERR_REQUIRE_ESM]: require() of ES Module (...) from (...) not supported. Instead change the require of (...) in (...) to a dynamic import() which is available in all CommonJS modules.
原因
これは、次の制限のいずれかによるものです:
- esbuild の esm から cjs (およびその逆) への変換。
- Node.js cjs/esm の相互運用性。
分析
esbuild の esm と cjs 間の変換機能は限られています。さらに、一部のシナリオは esbuild でサポートされていますが、Node.js 自体ではサポートされていません。 esbuild@0.24.0 の時点でサポートされている内容を次の表にまとめます。
Format | Scenario | Supported? |
---|---|---|
cjs | static import | Yes |
cjs | dynamic import() | Yes |
cjs | top-level await | No |
cjs | --packages=external of esm entry point | No* |
esm | require() of user modules** | Yes*** |
esm | require() of node:* modules | No**** |
esm | --packages=external of cjs entry point | Yes |
* esbuild ではサポートされていますが、Node.js ではサポートされていません
** npm パッケージまたは相対パス ファイルを指します。
*** ユーザー モジュールはサポートされていますが、いくつかの注意点があります: __dirname と __filename はポリフィルなしではサポートされません。
**** ノード:* モジュールは同じポリフィルでサポートできます。
以下は、ポリフィルを使用しない場合のこれらのシナリオの詳細な説明です。
npmパッケージ
次の npm パッケージの例を使用します:
静的インポート
静的インポートを含むesmモジュール:
Error: Dynamic require of "<module_name>" is not supported
動的インポート
非同期関数内に動的 import() を含む esm モジュール:
Error [ERR_REQUIRE_ESM]: require() of ES Module (...) from (...) not supported. Instead change the require of (...) in (...) to a dynamic import() which is available in all CommonJS modules.
トップレベル-待機
動的 import() とトップレベルの await を備えた esm モジュール:
import { version } from "node:process"; export function getVersion() { return version; }
必要とする
require() 呼び出しを含む cjs モジュール:
export async function getVersion() { const { version } = await import("node:process"); return version; }
--format=cjs
次の引数を使用して esbuild を実行します:
const { version } = await import("node:process"); export function getVersion() { return version; }
および次のコード:
const { version } = require("node:process"); exports.getVersion = function() { return version; }
静的インポート
次のものが生成され、問題なく動作します。
esbuild --bundle --format=cjs --platform=node --outfile=bundle.cjs src/main.js
動的インポート()
次のものが生成され、問題なく動作します。
import { getVersion } from "{npm-package}"; (async () => { // version can be `string` or `Promise<string>` const version = await getVersion(); console.log(version); })();
動的 import() は cjs モジュールでも許可されているため、require() に変換されないことに注意してください。
トップレベルの待機
esbuild は次のエラーで失敗します:
// node_modules/static-import/index.js var import_node_process = require("node:process"); function getVersion() { return import_node_process.version; } // src/main.js (async () => { const version2 = await getVersion(); console.log(version2); })();
--packages=外部
--packages=external の使用は、すべての npm パッケージで成功します:
// (...esbuild auto-generated helpers...) // node_modules/dynamic-import/index.js async function getVersion() { const { version } = await import("node:process"); return version; } // src/main.js (async () => { const version = await getVersion(); console.log(version); })();
が生成するもの:
[ERROR] Top-level await is currently not supported with the "cjs" output format node_modules/top-level-await/index.js:1:20: 1 │ const { version } = await import("node:process"); ╵ ~~~~~
ただし、Nodes.js では cjs モジュールが esm モジュールをインポートすることを許可していないため、これらはすべて実行に失敗します。
esbuild --packages=external --format=cjs --platform=node --outfile=bundle.cjs src/main.js
--format=esm
次の引数を使用して esbuild を実行します:
var npm_package_import = require("{npm-package}"); (async () => { const version = await (0, npm_package_import.getVersion)(); console.log(version); })();
ユーザーモジュールのrequire()
src/main.js
/(...)/bundle.cjs:1 var import_static_import = require("static-import"); ^ Error [ERR_REQUIRE_ESM]: require() of ES Module /(...)/node_modules/static-import/index.js from /(...)/bundle.cjs not supported. Instead change the require of index.js in /(...)/bundle.cjs to a dynamic import() which is available in all CommonJS modules.
次のものが生成され、問題なく動作します:
esbuild --bundle --format=esm --platform=node --outfile=bundle.mjs src/main.js
node:* モジュールの require()
src/main.js
const { getVersion } = require("static-import"); console.log(getVersion());
は次のものを生成します:
// (...esbuild auto-generated helpers...) // node_modules/static-import/index.js var static_import_exports = {}; __export(static_import_exports, { getVersion: () => getVersion }); import { version } from "node:process"; function getVersion() { return version; } var init_static_import = __esm({ "node_modules/static-import/index.js"() { } }); // src/main.js var { getVersion: getVersion2 } = (init_static_import(), __toCommonJS(static_import_exports)); console.log(getVersion2());
しかし、実行に失敗します:
import { getVersion } from "require"; console.log(getVersion());
--packages=外部
--packages=external の使用は、cjs エントリ ポイントを含むすべての npm パッケージで成功します。例:
// (...esbuild auto-generated helpers...) var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); // (...esbuild auto-generated helpers...) // node_modules/require/index.js var require_require = __commonJS({ "node_modules/require/index.js"(exports) { var { version } = __require("node:process"); exports.getVersion = function() { return version; }; } }); // src/main.js var import_require = __toESM(require_require()); console.log((0, import_require.getVersion)());
と:
src/index.js
Error: Dynamic require of "node:process" is not supported
esm モジュールは cjs エントリ ポイントを含む npm パッケージをインポートできるため、問題なく動作するほぼそのままの出力が生成されます。
esbuild --packages=external --format=esm --platform=node --outfile=bundle.mjs src/main.js
結論
この投稿が、現在および将来の esbuild 出力のトラブルシューティングに役立つことを願っています。以下からご意見をお聞かせください!
以上がNode.js と esbuild: cjs と esm の混合に注意してくださいの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

JavaScriptを学ぶことは難しくありませんが、挑戦的です。 1)変数、データ型、関数などの基本概念を理解します。2)非同期プログラミングをマスターし、イベントループを通じて実装します。 3)DOM操作を使用し、非同期リクエストを処理することを約束します。 4)一般的な間違いを避け、デバッグテクニックを使用します。 5)パフォーマンスを最適化し、ベストプラクティスに従ってください。

この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...
