こんにちは、フリーランスエンジニアの太田雅昭です。
PulumiでTypeScriptモジュールをインポートする際に遭遇したエラーと、その解決方法について記録します。
環境
- @pulumi/pulumi: 3.207.0
- Node.js: ESM環境
発生した問題
Pulumiプロジェクトで自作のTypeScriptモジュールをインポートしようとしたところ、以下のエラーが発生しました。
Module '"xxx"' has no exported member yyy
モジュール自体は正しくエクスポートしているのに、なぜかPulumiから認識されないという状況です。
原因
Pulumiが生成するtsconfig.jsonには以下の設定が含まれています。
{
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "nodenext"
}
}
この設定は公式ドキュメントで指定されており、変更することができません。
module: "nodenext"の場合、ESMではimport文に拡張子が必須となります。
つまり、読み込まれる側のモジュールで以下のように拡張子を省略していると:
export * from "./utils"; // ❌ 拡張子省略 → Pulumiから読めない
export const foo = "bar"; // ✅ 直接エクスポート → 読める
再エクスポート(export * from ...)の部分だけがPulumiから認識されず、エラーになります。
解決方法
1. 拡張子を明示的に指定
モジュール側で拡張子を含めてエクスポートします。
export * from "./utils.ts"; // ✅ 読める!
export const foo = "bar"; // ✅ 読める
2. tsconfig.jsonの調整
.ts拡張子を付けるとTypeScriptがエラーを出す場合があります。その際は以下の設定を追加します。
{
"compilerOptions": {
"noEmit": true,
"allowImportingTsExtensions": true
}
}
noEmit: コンパイル結果を出力しない(型チェックのみ)allowImportingTsExtensions:.ts拡張子付きimportを許可
まとめ
Pulumiはnodenextモジュール解決を使用するため、ESMの厳密なルールに従う必要があります。再エクスポートを使う場合は拡張子を明示的に指定します。