Node.jsで「Cannot use import statement outside a module」エラーの解決方法
問題:ESモジュールのインポートができない
Node.jsでESモジュール(ECMAScript Modules)の構文を使用しようとすると、次のエラーが発生することがあります:
SyntaxError: Cannot use import statement outside a moduleこれは、以下のようなコードを実行したときに発生します:
// main.js
import * as myModule from "mod";
myModule.func();// mod.js
export function func(){
console.log("Hello World");
}このエラーは、Node.jsがデフォルトでCommonJSモジュールシステムを使用しており、ESモジュール構文を認識しないために発生します。
解決方法
方法1:package.jsonでモジュールタイプを設定(推奨)
プロジェクトのルートにあるpackage.jsonファイルに"type": "module"を追加します:
{
"name": "your-project",
"version": "1.0.0",
"type": "module",
// ... その他の設定
}この設定後、.jsファイルでESモジュール構文を使用できるようになります。
INFO
Node.js 13.0.0以降ではこの方法が正式にサポートされています。それ以前のバージョンでは追加の設定が必要です。
方法2:ファイル拡張子を.mjsに変更
ESモジュールを使用するファイルの拡張子を.mjs(Module JavaScript)に変更します:
# ファイル名を変更
mv main.js main.mjs
mv mod.js mod.mjs
# .mjsファイルを実行
node main.mjsTIP
Node.jsは.mjs拡張子を持つファイルを自動的にESモジュールとして扱います。
方法3:実験的フラグの使用(古いNode.jsバージョン用)
Node.js 13より前のバージョンでは、実験的フラグを使用する必要があります:
node --experimental-modules main.jsWARNING
この方法は非推奨です。可能な限りNode.jsを最新バージョンにアップデートし、方法1または2を使用してください。
方法4:CommonJS構文への切り替え
ESモジュール構文を使用する必要がない場合は、CommonJS構文に戻すことも解決策になります:
// mod.js
module.exports.func = function (){
console.log("Hello World");
}// main.js
const myMod = require("./mod");
myMod.func();ブラウザ環境での解決方法
ブラウザでESモジュールを使用する場合は、scriptタグにtype="module"属性を追加する必要があります:
<script src="main.js" type="module"></script>TypeScriptプロジェクトの場合
TypeScriptを使用している場合、コンパイルと実行の手順に注意が必要です:
# TypeScriptをJavaScriptにコンパイル
npx tsc file.ts
# コンパイルされたJavaScriptを実行
node file.jsテスト環境での設定
Mochaなどのテストフレームワークを使用している場合、package.jsonのスクリプト設定でモジュールタイプを明示することができます:
{
"scripts": {
"test": "cross-env TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\" }' mocha -r ts-node/register -r src/**/*.spec.ts"
}
}まとめ
Cannot use import statement outside a moduleエラーは、Node.jsのモジュールシステムの設定に関する問題です。以下のいずれかの方法で解決できます:
- package.jsonに
"type": "module"を追加(最新のNode.jsで推奨) - ファイル拡張子を
.mjsに変更 - CommonJS構文に切り替え(
require/module.exportsを使用)
プロジェクトの要件や使用しているNode.jsのバージョンに応じて、適切な方法を選択してください。新しいプロジェクトでは、ESモジュールの使用を推奨します。