Node.js と TypeScript で ES6 モジュールの相対インポートをスムーズに行う
"javascript", "node.js", "typescript" に関連する "Appending .js extension on relative import statements during Typescript compilation (ES6 modules)" のプログラミングについて分かりやすく日本語で解説
このチュートリアルでは、TypeScript コンパイル時に相対インポートステートメントに .js
拡張子を自動的に追加する方法について説明します。これは、ES6 モジュールを使用している場合に役立ちます。
背景
TypeScript は、JavaScript に静的な型付けを提供するスーパーセット言語です。 TypeScript コンパイラは、TypeScript ファイルを JavaScript ファイルに変換します。
ES6 モジュールは、JavaScript に新しいモジュールシステムを導入します。 ES6 モジュールを使用すると、相対インポートステートメントを使用して他のモジュールをインポートできます。
相対インポートステートメントは、インポートするモジュールのパスを指定します。相対パスは、現在のファイルの場所から相対的なパスです。
例:
import { Component } from './components/component';
このステートメントは、components
ディレクトリ内の component.js
ファイルから Component
クラスをインポートします。
問題
デフォルトでは、TypeScript コンパイラは相対インポートステートメントに .js
拡張子を自動的に追加しません。これは、インポートするモジュールの拡張子が .ts
である場合に問題が発生する可能性があります。
import { Component } from './components/component.ts';
このステートメントは、components
ディレクトリ内の component.ts
ファイルから Component
クラスをインポートしようとします。しかし、TypeScript コンパイラは .js
拡張子を自動的に追加しないため、このステートメントは失敗します。
解決策
この問題を解決するには、TypeScript コンパイラに相対インポートステートメントに .js
拡張子を自動的に追加するように指示する必要があります。これを行うには、compilerOptions
オプションの resolveJsonModule
プロパティを true
に設定します。
{
"compilerOptions": {
"resolveJsonModule": true
}
}
この設定を有効にすると、TypeScript コンパイラは相対インポートステートメントに .js
拡張子を自動的に追加します。
例
以下の例は、resolveJsonModule
オプションを有効にした場合の動作を示しています。
// components/component.ts
export class Component {
constructor(public name: string) {}
}
// main.ts
import { Component } from './components/component';
const component = new Component('My Component');
console.log(component.name); // My Component
この例では、main.ts
ファイルは components
ディレクトリ内の component.ts
ファイルから Component
クラスをインポートします。 TypeScript コンパイラは resolveJsonModule
オプションを有効にしているため、component.js
ファイルをインポートします。
注意事項
resolveJsonModule
オプションを有効にする前に、プロジェクトが ES6 モジュールを使用するように設定されていることを確認してください。これを行うには、package.json
ファイルの type
フィールドを module
に設定します。
{
"type": "module"
}
{
"type": "module"
}
tsconfig.json
{
"compilerOptions": {
"resolveJsonModule": true
}
}
components/component.ts
export class Component {
constructor(public name: string) {}
}
main.ts
import { Component } from './components/component';
const component = new Component('My Component');
console.log(component.name); // My Component
このコードを実行するには、次のコマンドを実行します。
tsc
このコマンドは、main.ts
ファイルを main.js
ファイルに変換します。
main.js
ファイルの内容は次のとおりです。
// main.js
"use strict";
var Component = require('./components/component').Component;
var component = new Component('My Component');
console.log(component.name); // My Component
このコードは、require()
関数を使用して components/component.js
ファイルをインポートします。 components/component.js
ファイルは、TypeScript コンパイラによって component.ts
ファイルから自動的に生成されます。
説明
main.ts
ファイルは、components/component
モジュールからComponent
クラスをインポートします。main.ts
ファイルは、Component
クラスを使用して新しいインスタンスを作成し、そのインスタンスのname
プロパティをコンソールに出力します。components/component.ts
ファイルは、Component
クラスを定義します。tsconfig.json
ファイルのresolveJsonModule
オプションは、TypeScript コンパイラに相対インポートステートメントに.js
拡張子を自動的に追加するように指示します。package.json
ファイルのtype
フィールドは、プロジェクトが ES6 モジュールを使用するように設定されていることを TypeScript コンパイラに通知します。
baseUrl
オプションを使用して、プロジェクトのルート ディレクトリを指定できます。 TypeScript コンパイラは、このオプションを使用して、相対インポートパスの解決方法を決定します。
{
"compilerOptions": {
"baseUrl": "./src",
"resolveJsonModule": true
}
}
この設定を有効にすると、TypeScript コンパイラは、すべての相対インポートパスを src
ディレクトリから解決します。
paths オプションを使用する
paths
オプションを使用して、エイリアスを定義できます。 エイリアスは、モジュールの名前を短縮する方法です。
{
"compilerOptions": {
"paths": {
"@components/*": ["components/*"]
},
"resolveJsonModule": true
}
}
この設定を有効にすると、TypeScript コンパイラは、@components
プレフィックスが付いたすべてのインポートパスを components
ディレクトリから解決します。
Node.js を使用する
Node.js を使用している場合は、--esModuleInterop
フラグを使用して、TypeScript コンパイラに ES6 モジュールの互換モードを有効にすることができます。
tsc main.ts --esModuleInterop
バンドラーを使用する
Webpack や Rollup などのバンドラーを使用している場合は、バンドラーの設定を使用して、相対インポートパスの解決方法を構成できます。
javascript node.js typescript