0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TypeScript】package.json の type と tsconfig.json の module の違いを理解する

Posted at

はじめに

TypeScript で Web 開発をしていると、モジュールシステムの設定で混乱することがありませんか?特に package.jsontype フィールドと tsconfig.jsonmodule オプション、どちらも "commonjs" など同じ値を設定できるので、「何が違うの?」と思った方もいるのではないでしょうか?

この記事では、実際にコードを書いて動かしながら、この2つの違いを整理してみます。

結論

  • package.json の type: Node.js が .js ファイルをどう解釈するかを決める(実行に影響)
  • tsconfig.json の module: TypeScript コンパイラがどんな形式の JS コードを出力するかを決める(コンパイル時に影響)

開発環境

開発環境は以下の通りです。

  • Windows11
  • TypeScript 5.9.2
  • Node.js 22.18.0
  • npm 11.5.2

事前準備

まず、動作確認用にシンプルな TypeScript ファイルを作成します。

src/math.ts
export const add = (a: number, b: number): number => {
  return a + b;
};

export const multiply = (a: number, b: number): number => {
  return a * b;
};
src/index.ts
import { add, multiply } from './math';

console.log('2 + 3 =', add(2, 3));
console.log('4 * 5 =', multiply(4, 5));

パターン別検証

package.jsontypetsconfigmodule の設定値ごとにコンパイルと実行結果を確認していきます。

パターン1: package.json type 未指定 + tsconfig module: "commonjs"

package.jsontsconfig をそれぞれ以下のように設定します。

package.json
{
  "name": "module-test",
  "version": "1.0.0",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "devDependencies": {
    "@types/node": "^24.3.1",
    "typescript": "^5.9.02"
  }
}
tsconfig.json
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true
  }
}

index.ts のコンパイル結果は以下の通りです。

dist/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const math_1 = require("./math");
console.log("2 + 3 =", (0, math_1.add)(2, 3));
console.log("4 * 5 =", (0, math_1.multiply)(4, 5));

コンパイル結果からは、以下のことが読み取れます。

  • TypeScript の import / exportrequire() / exports に変換
  • "use strict" が追加され、厳格モードで実行
  • Object.defineProperty(exports, "__esModule", { value: true }) でES Module との互換性を確保
  • package.jsontype 指定がないため、Node.js は .js ファイルを CommonJS として認識

正常に実行できます。

> module-test@1.0.0 start
> node dist/index.js

2 + 3 = 5
4 * 5 = 20

tsconfig.jsonmodule"commonjs" にしたため、TypeScript が CommonJS 形式でコンパイルされました。また、package.jsontype 指定がないため、Node.js は .js ファイルを CommonJS として認識しています。その結果、コンパイルされた .js ファイルと Node.js が認識する .js ファイルの形式が一致して正常に動作します。

パターン2: package.json type: "module" + tsconfig module: "commonjs"

package.jsontsconfig をそれぞれ以下のように設定します。

package.json
{
  "name": "module-test",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "devDependencies": {
    "typescript": "^5.0.0"
  }
}
tsconfig.json
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true
  }
}

ビルドして、実行する(npm run build && npm start)とエラーになります。

ReferenceError: require is not defined in ES module scope

TypeScript はパターン1と同じく require() を使った CommonJS 形式でコンパイルされました。しかし、package.json"type": "module" により、Node.js は .js ファイルを ES Module として解釈しようとします。ES Module では requireexports は存在しないため、エラーになります。

package.jsontype はコンパイル済みの .js ファイルに影響し、TypeScript のコンパイル自体には関与しません。

パターン3: package.json type: "module" + tsconfig module: "nodenext"

package.jsontsconfig をそれぞれ以下のように設定します。

package.json
{
  "name": "module-test",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "devDependencies": {
    "typescript": "^5.0.0"
  }
}
tsconfig.json
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "nodenext",
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true
  }
}

index.ts のコンパイル結果は以下の通りです。

dist/index.js
import { add, multiply } from "./math.js";
console.log("2 + 3 =", add(2, 3));
console.log("4 * 5 =", multiply(4, 5));

コンパイル結果からは、以下のことが読み取れます。

  • TypeScript が import / export 構文をそのまま残してコンパイル
  • "use strict"Object.defineProperty などの CommonJS 特有の処理が存在しない

正常に実行できます。

> module-test@1.0.0 start
> node dist/index.js

2 + 3 = 5
4 * 5 = 20

まとめ

package.jsontypetsconfig.jsonmodule は、それぞれ異なる役割を持っています:

  • package.jsonのtype: Node.js ランタイムへの指示
  • tsconfig.jsonのmodule: TypeScript コンパイラへの指示

この2つを適切に組み合わせることで、意図した通りのモジュールシステムでアプリケーションを動かすことができます。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?