クイック解決策
このエラーをすぐに修正する必要がある場合は、業界標準である次の2つの方法のいずれかを使用してください。
- プロジェクト全体での修正:
package.jsonを開き、ルートオブジェクトに"type": "module"を追加します。 - 単一ファイルでの修正: ファイルの拡張子を
.jsから.mjsに変更します。
// package.json は以下のようになります:
{
"name": "my-node-app",
"version": "1.0.0",
"type": "module",
"dependencies": { ... }
}
根本原因
Node.js は2009年に、require() を使用するモジュールシステムである CommonJS をベースに構築されました。現在のモダンな JavaScript では、import と export を使用する ECMAScript Modules (ESM) が標準となっています。これら2つのシステムでは、変数の扱いや読み込み方法が異なります。
デフォルトでは、Node.js はすべての .js ファイルを CommonJS モジュールとして扱います。CommonJS であると想定しているファイル内で import ステートメントが検出されると、エンジンは実行を停止し、次のエラーをスローします。
SyntaxError: Cannot use import statement outside a module
モダンな構文を使用するには、環境が ES Modules をサポートしていることを Node.js に明示的に伝える必要があります。
方法1:package.json によるアプローチ(推奨)
これは、モダンな Node.js プロジェクトを管理する上で最も効率的な方法です。type フィールドを設定することで、そのディレクトリ(およびすべてのサブディレクトリ)内のすべての .js ファイルが ES Module として扱われるようになります。
- プロジェクトのルートにある
package.jsonファイルを見つけます。 - メインの設定ブロックに
"type": "module"を挿入します。 node app.jsを実行してアプリケーションを再起動します。
重要な注意点: この変更により require() が無効になります。モジュール内で const fs = require('fs') を使用しようとすると、Node はエラーをスローします。それらの行を import fs from 'fs' に変換するか、特定のレガシーファイルを .cjs にリネームする必要があります。
方法2:.mjs 拡張子の使用
プロジェクト全体の設定を変更したくない場合もあります。そのような状況では、.mjs 拡張子が役立ちます。Node.js は、package.json の設定に関わらず、.mjs ファイルを常に ES Module として扱います。
server.jsをserver.mjsにリネームします。node server.mjsを使用してファイルを実行します。
このアプローチは、小さなスクリプトや、大規模なコードベースを段階的にモダンな JavaScript へ移行する場合に適しています。
方法3:TypeScript によるトランスパイル
TypeScript を使用している場合、設定が古いバージョンの Node をターゲットにしていると、このエラーが発生することがあります。tsconfig.json は、import ステートメントを古い Node バージョンが理解できる require 呼び出しに変換する架け橋として機能します。
// tsconfig.json
{
"compilerOptions": {
"module": "CommonJS",
"target": "ES2020",
"esModuleInterop": true
}
}
ts-node や tsx を使用してファイルを実行すると、この変換がメモリ内で行われるため、開発中の SyntaxError を防ぐことができます。
修正のテスト
以下のコードを含む check-version.js という名前のファイルを作成して、設定を確認します。
// check-version.js
import { versions } from 'process';
console.log("Node.jsエンジン バージョン:", versions.node);
"type": "module" を有効にした場合は、node check-version.js を実行してください。クラッシュせずにバージョン(例:20.10.0)が表示されれば、環境は正しく設定されています。
よくある障害
- Node.js のバージョン: ESM は Node.js v12.17.0 で安定版となりました。v10 などの古いバージョンを使用している場合は、実験的フラグなしで
importを使用するためにアップグレードする必要があります。 - 明示的な拡張子: CommonJS とは異なり、ESM では完全なファイル拡張子が必要です。
import { auth } from './auth'と書くことはできず、import { auth } from './auth.js'と記述する必要があります。 - ディレクトリのインポート: ESM では、フォルダをインポートして
index.jsを自動的に読み込む方法は機能しません。ファイルパスを直接指定する必要があります。
リソース
- Node.js 公式 ESM ドキュメント
- CommonJS 互換性ガイド

