TypeScriptでよく遭遇する「ES Modules」と「CommonJS」のモジュールシステムに関する問題について、具体的な解決方法を解説します。
モジュールシステムの基本的な違い
ES Modules(ESM)とCommonJS(CJS)は、JavaScriptにおける2つの主要なモジュールシステムです。
ES Modules の特徴
// エクスポート
export const hello = () => console.log('Hello');
export default class User {}
// インポート
import { hello } from './module';
import User from './module';CommonJS の特徴
// エクスポート
const hello = () => console.log('Hello');
module.exports = { hello };
// インポート
const { hello } = require('./module');TypeScriptでの設定方法
`tsconfig.json`でモジュールシステムを指定できます:
{
"compilerOptions": {
"module": "ESNext", // ES Modules用
// または
"module": "CommonJS" // CommonJS用
}
}よくある問題と解決策
1. 混在による問題
問題
// ESMとCJSの混在
import express from 'express';
const lodash = require('lodash');解決策
// 統一したインポート方式を使用
import express from 'express';
import lodash from 'lodash';2. パッケージの互換性問題
問題
// Type Error: Cannot use import statement outside a module
import { someFunction } from 'some-package';解決策
`package.json`に以下を追加:
{
"type": "module"
}3. 動的インポートの扱い
ESM方式
const module = await import('./module.js');CJS方式
const module = require('./module.js');ベストプラクティス
1. プロジェクト全体で一貫したモジュールシステムを使用
- 新規プロジェクトではES Modulesを推奨
- レガシープロジェクトではCommonJSを維持
2. package.jsonの適切な設定
{
"type": "module", // ES Modules用
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
}3. 拡張子の明示的な指定
// 推奨
import { function } from './module.js';モジュールシステムの選択基準
1. ES Modulesを選ぶ場合
- 最新のNode.js環境を使用
- ブラウザ環境での実行が主
- Tree Shakingを活用したい
2. CommonJSを選ぶ場合
- レガシーなNode.js環境との互換性が必要
- 既存のCommonJSプロジェクトとの統合
- 動的なモジュール解決が必要
まとめ
- ES ModulesとCommonJSの違いを理解し、プロジェクトに適したものを選択
- 一貫したモジュールシステムの使用で問題を回避
- 適切な設定とベストプラクティスの遵守が重要
これらの知識を活用することで、TypeScriptプロジェクトでのモジュールシステムに関する問題を効果的に解決できます。