最新版TypeScript+webpack 5の
環境構築まとめ
(React, Three.jsのサンプル付き)

150
240

TypeScriptはMicrosoftが開発するプログラミング言語です。JavaScriptのスーパーセットという位置づけで、静的型付けなど強力な言語機能を備えています。TypeScriptは高度なウェブアプリケーションの開発で使われることが多く、Google社内の標準言語として2017年に採用されるなど、注目が高まっています(参考記事『Google社内の標準言語としてTypeScriptが承認される - Publickey』)。

▲TypeScriptの公式サイト

TypeScriptはコンパイラによってJavaScriptのコードが得られますが、TypeScriptのコンパイラにはECMAScript Modules(ES Modules = importexport文のこと)をまとめる機能が提供されていません。そのため、ES ModulesのJSファイルをまとめるモジュールバンドラー(例:webpack、Rollup等)をTypeScriptと合わせて使うのが一般的です。

この記事では、TypeScriptとwebpackの組み合わせた環境構築の方法を説明します。ライブラリごとに設定項目の違いがあるので、例示しながら説明しています。

本記事で解説していること

※webpackの基本的な使い方は前回の記事「最新版で学ぶwebpack入門」を参照ください。

webpack+TypeScriptの最小構成

webpackとTypeScriptを最小構成として作っていきましょう。初回で解説したように、Node.jsを事前にインストールしておいてください。

npmモジュールのインストール

「webpack」や「webpack-cli」と「typescript」など必要なモジュールをインストールしましょう。TypeScriptをwebpackで処理するために「ts-loader」をを利用します。

npm i -D webpack webpack-cli typescript ts-loader

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependencies以外の情報は省略しています。

package.jsonファイル

{
  "scripts": {
    "build": "webpack",
    "watch": "webpack -w"
  },
  "devDependencies": {
    "ts-loader": "^9.5.1",
    "typescript": "^5.4.3",
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4"
  },
  "private": true
}

TypeScriptの設定ファイル: tsconfig.json

次にTypeScriptの設定ファイルを用意しましょう。tsconfig.jsonというテキストファイルをプロジェクトのルートに作成し、次の内容を記述します。ソースマップを有効にすること、出力対象をECMAScript 5仕様のJavaScriptにすること、ES Modulesのまま出力することを指定しています。

tsconfig.jsonファイル

{
  "compilerOptions": {
    // ソースマップを有効化
    "sourceMap": true,
    // TSはECMAScript 5に変換
    "target": "ES5",
    // TSのモジュールはES Modulesとして出力
    "module": "ES2015",
    // 厳密モードとして設定
    "strict": true
  }
}

とくにmodulees2015を指定するのが重要です。これを指定しないと、TypeScriptコードのimport文とexport文がコンパイラによってCommonJSとして変換されるため、webpackによるツリーシェイキング(Tree Shaking = 未使用のimportを静的解析によって振り落とす機能)のメリットが得られません。ツリーシェイキングの効果を得るためには明示的にES Modulesをコンパイルオプションで指定します。

webpackの設定ファイル:webpack.config.js

webpackの設定ファイルには次のように記述します。

  • rulesの部分で拡張子.tsにはts-loaderを指定します
  • resolve.extensionsに拡張子.tsを登録することで、TypeScript内のimport文で拡張子を書く手間が省けます
  • webpackのimport文でコンパイルが通らないときは、resolve.extensions配列の指定が漏れているケースが多いです。しっかりと記述しましょう

webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: 'development',

  // メインとなるJavaScriptファイル(エントリーポイント)
  entry: './src/main.ts',

  module: {
    rules: [
      {
        // 拡張子 .ts の場合
        test: /\.ts$/,
        // TypeScript をコンパイルする
        use: 'ts-loader',
      },
    ],
  },
  // import 文で .ts ファイルを解決するため
  // これを定義しないと import 文で拡張子を書く必要が生まれる。
  // フロントエンドの開発では拡張子を省略することが多いので、
  // 記載したほうがトラブルに巻き込まれにくい。
  resolve: {
    // 拡張子を配列で指定
    extensions: [
      '.ts', '.js',
    ],
  },
};

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したTSファイルがコンパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

webpack+TypeScript+Three.jsの最小構成

Three.js公式サイト

Three.jsは3D表現の制作に役立つ人気のJSライブラリです。使い方は記事「Three.js入門」で説明していますので参照ください。webpackとTypeScriptとThree.jsを最小構成として作っていきましょう。

注意点として、Three.jsライブラリはIE 11向けのJSファイルを提供していません。Three.jsをIE 11向けに利用するにはTypeScriptのコンパイルに加えて、Babelのトランスパイルも必要となります。本記事ではその手順も後述しますが、まずはモダンブラウザ向けの環境構築方法から説明します。

npmモジュールのインストール

webpackとTypeScriptなど必要なモジュールをインストールしましょう。TypeScriptをwebpackで処理するためには「ts-loader」を利用します。

npm i -D webpack webpack-cli typescript ts-loader

実行用の「three」モジュールもインストールしましょう。なお、実行ファイルに含まれるモジュールとして利用したいので、コマンドオプション「-S」を指定します。

npm i -S three @types/three

※ヒント:TypeScriptの型定義ファイルは2019年〜2020年頃まで「three」に内包されていましたが、r125から含まれなくなりました開発者の事情)。そのため、「@types/three」のインストールは必要です。

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependencies以外の情報は省略しています。

package.jsonファイル

{
  "scripts": {
    "build": "webpack",
    "watch": "webpack -w"
  },
  "devDependencies": {
    "ts-loader": "^9.5.1",
    "typescript": "^5.4.3",
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4"
  },
  "dependencies": {
    "@types/three": "^0.163.0",
    "three": "^0.163.0"
  },
  "private": true
}

TypeScriptの設定ファイル

次にTypeScriptの設定ファイルを用意しましょう。tsconfig.jsonというテキストファイルをプロジェクトのルートに作成し、次の内容を記述します。libにはTypeScriptでのコンパイル時にECMAScriptの先端機能を使うことを明示的に指定します。これはThree.jsが内部的に最新のECMAScript 2015+を一部使っているためで、コンパイルを通すためです。

tsconfig.jsonファイル

{
  "compilerOptions": {
    // Three.jsがES5未サポートなので、割り切って比較的新しい仕様でビルドする
    "target": "ES2015",
    // TSのモジュールはES Modulesとして出力
    "module": "ES2015",
    // node_modules からライブラリを読み込む
    "moduleResolution": "node",
    // 厳密モード
    "strict": true,
    "lib": [
      "ES2023",
      "DOM"
    ]
  }
}

webpackの設定ファイル:webpack.config.js

webpackの設定ファイルには次のように記述します。rulesの部分でts-loaderを指定。resolveに拡張子.ts.jsを指定しています。

webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "development",

  // メインとなるJavaScriptファイル(エントリーポイント)
  entry: "./src/index.ts",
  // ファイルの出力設定
  output: {
    //  出力ファイルのディレクトリ名
    path: `${__dirname}/dist`,
    // 出力ファイル名
    filename: "main.js"
  },
  module: {
    rules: [
      {
        // 拡張子 .ts の場合
        test: /\.ts$/,
        // TypeScript をコンパイルする
        use: "ts-loader"
      }
    ]
  },
  // import 文で .ts ファイルを解決するため
  resolve: {
    extensions: [".ts", ".js"]
  }
};

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したTSファイルがコンパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

Three.jsのサンプルの実行結果は次となります。

IE 11向けにThree.jsをビルドする方法

前述のとおり、IE 11向けにThree.jsをビルドするにはBabelの併用が必要となります。Three.js自体がES2015+のJavaScriptで提供されているため、JSライブラリ自体もIE 11互換のJavaScriptに変換しなければならないからです。ts-loaderとbabel-loaderを組み合わせたうえで、ポリフィルを導入して開発環境を整えます。

詳しい開発環境のサンプルはGitHubに用意していますので、参考ください。以下の環境でビルドしたファイルはIE 11で再生できています。

Three.js + TypeScript + webpackのサンプル

当サイトの3Dのデモは基本的にThree.js + TypeScript + webpackのアーキテクチャーで構築しています。3Dコンテンツの開発ではさまざまなAPIを利用するため、TypeScriptによる型定義が生産効率上とても重要です。環境構築のサンプルとして次の記事もあわせて参照ください。

webpack+TypeScript+Reactの最小構成

React公式サイト

Reactはウェブアプリケーションの開発に役立つ人気のJSライブラリです。ReactではJSXと言われる独特の記法を使えるようにしなければなりません。webpackとTypeScriptで最小構成として作っていきましょう。

npmモジュールのインストール

webpackとTypeScriptなど必要なモジュールをインストールしましょう。TypeScriptをwebpackで処理するためには「ts-loader」を利用します。

npm i -D webpack webpack-cli typescript ts-loader

実行用の「react」「react-dom」モジュールもインストールしましょう。型定義ファイルも欲しいので「@types/react」「@types/react-dom」も指定します。なお、実行ファイルに含まれるモジュールとして利用したいので、コマンドオプション「-S」を指定します。

npm i -S react react-dom @types/react @types/react-dom

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependencies以外の情報は省略しています。

package.jsonファイル

{
  "scripts": {
    "build": "webpack",
    "watch": "webpack -w"
  },
  "devDependencies": {
    "ts-loader": "^9.5.1",
    "typescript": "^5.4.3",
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4"
  },
  "dependencies": {
    "@types/react": "^18.2.73",
    "@types/react-dom": "^18.2.23",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "private": true
}

TypeScriptの設定ファイル: tsconfig.json

次にTypeScriptの設定ファイルを用意しましょう。tsconfig.jsonというテキストファイルをプロジェクトのルートに作成し、次の内容を記述します。jsxオプションにはreact-jsxを指定するのがポイントです。これによって、JSXと呼ばれるReact特有のシンタックス(JavaScriptの中にDOM要素を記述する方法)を解釈できるようになります

tsconfig.jsonファイル

{
  "compilerOptions": {
    // 厳密モードとして設定
    "strict": true,
    // ソースマップを有効化
    "sourceMap": true,
    // TSはECMAScript 5に変換
    "target": "ES5",
    // TSのモジュールはES Modulesとして出力
    "module": "ES2015",
    // JSXの書式を有効に設定
    "jsx": "react-jsx",
    "moduleResolution": "node",
    "lib": [
      "ES2023",
      "DOM"
    ]
  }
}

webpackの設定ファイル:webpack.config.js

webpackの設定ファイルには次のように記述します。rulesresolveの部分で拡張子.tsxを指定するのが重要です。

webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "development",

  // メインとなるJavaScriptファイル(エントリーポイント)
  entry: "./src/main.tsx",
  // ファイルの出力設定
  output: {
    //  出力ファイルのディレクトリ名
    path: `${__dirname}/dist`,
    // 出力ファイル名
    filename: "main.js"
  },
  module: {
    rules: [
      {
        // 拡張子 .ts もしくは .tsx の場合
        test: /\.tsx?$/,
        // TypeScript をコンパイルする
        use: "ts-loader"
      }
    ]
  },
  // import 文で .ts や .tsx ファイルを解決するため
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".json"]
  },
  // ES5(IE11等)向けの指定(webpack 5以上で必要)
  target: ["web", "es5"],
};

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したTSXファイルがコンパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

Reactのサンプルの実行結果は次となります。

このほかにもサンプルを用意してます

このほかにも、さまざまなJavaScriptライブラリのサンプルを用意してます。ここまで記事を読み進めて頂いた方であれば、次のリポジトリのソースコードを見れば簡単に導入できるはずです。

webpack+TypeScript+画像バンドルの最小構成

webpackは画像を取り込めることが1つの利点です。webpack 5ではデフォルトで、画像はBase64文字列としてJavaScriptにバンドルできます。しかし、TypeScriptで扱おうとすると工夫が必要です。

npmモジュールのインストール

webpackとTypeScriptなど必要なモジュールをインストールしましょう。TypeScriptをwebpackで処理するためには「ts-loader」を利用します。

npm i -D webpack webpack-cli typescript ts-loader

これをインストールすると、package.jsonファイルは次の内容になります。scriptsは自前のビルドコマンドを記述しておきます。scriptsdevDependencies以外の情報は省略しています。

package.jsonファイル

{
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "ts-loader": "^9.5.1",
    "typescript": "^5.4.3",
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4"
  },
  "private": true
}

TypeScriptの設定ファイル

次にTypeScriptの設定ファイルを用意しましょう。特記するような注意点はありません。

tsconfig.jsonファイル

{
  "compilerOptions": {
    "sourceMap": true,
    // TSはECMAScript 5に変換
    "target": "ES5",
    // TSのモジュールはES Modulesとして出力
    "module": "ES2015",
    // これの設定も必要 デフォルトインポートの有効化
    "allowSyntheticDefaultImports": true
  }
}

webpackの設定ファイル

webpackの設定ファイルには次のように記述します。画像ファイルの箇所でtype: "asset/inline"を指定します。typeプロパティーはwebpack 5から搭載された新機能で従来のurl-loaderと似た機能が提供されています。

webpack.config.jsファイル

module.exports = {
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: "production",

  module: {
    rules: [
      {
        // 拡張子 .ts の場合
        test: /\.ts$/,
        // TypeScript をコンパイルする
        use: "ts-loader"
      },
      {
        // 対象となるファイルの拡張子
        test: /\.(gif|png|jpg|eot|wof|woff|ttf|svg)$/,
        // 画像をBase64として取り込む
        type: "asset/inline",
      }
    ]
  },
  // import 文で .ts ファイルを解決するため
  resolve: {
    extensions: [".ts", ".js"]
  },
  // ES5(IE11等)向けの指定(webpack 5以上で必要)
  target: ["web", "es5"],
};

次に定義ファイルを用意します。srcフォルダーに格納しておけば、自動的に型定義が認識されます。

src/definitions.d.ts ファイル

declare module '*.png' {
  const value: any;
  export = value;
}

declare module '*.jpg' {
  const value: any;
  export = value;
}

declare module '*.gif' {
  const value: any;
  export = value;
}

TypeScriptからは次のように利用します。

src/definitions.d.ts ファイル

// import文を解決する
import myImage from "./images/bg.jpg";

// img要素を生成
const img = document.createElement("img");

// Base64の画像を代入
img.src = myImage;

// 画面に表示する
document.body.appendChild(img);

以上で設定は完了です。npm run buildコマンドを入力すると、srcフォルダーに配置したtsファイルがコンパイルされ、distフォルダーにmain.jsファイルが出力されます。

ここまでの手順をサンプルファイルとしてGitHubで公開していますので、参考ください。

最後に

弊社ではTypeScriptを2013年から導入し、多くのプロジェクトで活用してきました。「この言語には将来性がある」「もっと広く使われるはず」と考え、2013年に記事「HTML5デモを作って分かったCreateJSとTypeScriptでの効率的な開発手法」でTypeScriptの利点を紹介しました。

当時はそれでもTypeScriptに懐疑的な意見をもつフロントエンドエンジニアも多くいましたが、記事「人気上昇中のJavaScriptライブラリを調べてみた【2016年版】 - Build Insider」あたりから状況は変わり、今ではaltJSの中ではTypeScriptの人気が飛び抜け、他をさらに引き離し続けています。

ECMAScript 2023仕様のJavaScriptがブラウザで使えるようになってきたとはいえ、静的型付けのあるTypeScriptは魅力的です。コンパイル時の型チェックなど開発の安全性があったり、WebStormをはじめとする開発ツールのサポートの充実(コードヒントやコード補完、import文の追加/整理)によって、さらに便利になっています。

本記事では、webpackとTypeScriptの連携について最小構成で説明しました。現場ではJavaScriptの圧縮やソースマップ、ローカルサーバーの起動(webpack-dev-server)なども合わせて使うのが一般的です。連載の初回「最新版で学ぶwebpack入門」で解説してますので、あわせて参照くださいませ。

連載一覧

※この記事が公開されたのは7年前ですが、8か月前の3月に内容をメンテナンスしています。

池田 泰延

ICS代表。筑波大学 非常勤講師。ICS MEDIA編集長。個人実験サイト「ClockMaker Labs」のようなビジュアルプログラミングとUIデザインが得意分野です。

この担当の記事一覧