TypeScriptへの取り組み
本書をサポートしてください:購入 または 寄付
(広告、ブロックしないでください。)

9 TypeScriptとwebpackによるウェブアプリ作成



本章では、TypeScriptとwebpackを使用してウェブアプリを作成する方法について説明します。特定のフロントエンドフレームワークではなく、DOM APIのみを使用します。

  GitHubリポジトリ:`ts-demo-webpack`

本章で扱うリポジトリ`ts-demo-webpack`は、GitHubからダウンロードできます。

9.1 必要な知識

大まかに以下の知識が必要です。

9.2 制限事項

本章では、TypeScriptで最もよくサポートされているもの、つまりCommonJSモジュールをスクリプトファイルとしてバンドルすることに重点を置いています。

9.3 リポジトリ`ts-demo-webpack`

リポジトリ`ts-demo-webpack`の構造は以下のとおりです。

ts-demo-webpack/
  build/   (created on demand)
  html/
    index.html
  package.json
  ts/
    src/
      main.ts
  tsconfig.json
  webpack.config.js

ウェブアプリは次のようにビルドされます。

両方の出力タスクはwebpackによって処理されます。

9.4 `package.json`

`package.json`には、プロジェクトのメタデータが含まれています。

{
  "private": true,
  "scripts": {
    "tsc": "tsc",
    "tscw": "tsc --watch",
    "wp": "webpack",
    "wpw": "webpack --watch",
    "serve": "http-server build"
  },
  "dependencies": {
    "@types/lodash": "···",
    "copy-webpack-plugin": "···",
    "http-server": "···",
    "lodash": "···",
    "ts-loader": "···",
    "typescript": "···",
    "webpack": "···",
    "webpack-cli": "···"
  }
}

プロパティの動作は以下のとおりです。

9.5 `webpack.config.js`

webpackは次のように設定します。

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  ···
  entry: {
    main: "./ts/src/main.ts",
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: "[name]-bundle.js",
  },
  resolve: {
    // Add ".ts" and ".tsx" as resolvable extensions.
    extensions: [".ts", ".tsx", ".js"],
  },
  module: {
    rules: [
      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
      { test: /\.tsx?$/, loader: "ts-loader" },
    ],
  },
  plugins: [
    new CopyWebpackPlugin([
      {
        from: './html',
      }
    ]),
  ],
};

プロパティ

webpackの設定の詳細については、webpackのウェブサイトを参照してください。

9.6 `tsconfig.json`

このファイルはTypeScriptコンパイラを設定します。

{
  "compilerOptions": {
    "rootDir": "ts",
    "outDir": "dist",
    "target": "es2019",
    "lib": [
      "es2019",
      "dom"
    ],
    "module": "commonjs",
    "esModuleInterop": true,
    "strict": true,
    "sourceMap": true
  }
}

`ts-loader`と共にwebpackを使用する場合は、`outDir`オプションは必要ありません。ただし、ローダーなしでwebpackを使用する場合は(本章で後述するように)、必要になります。

9.7 `index.html`

これはウェブアプリのHTMLページです。

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>ts-demo-webpack</title>
</head>
<body>
  <div id="output"></div>
  <script src="main-bundle.js"></script>
</body>
</html>

IDが`output`の`<div>`は、ウェブアプリが出力を表示する場所です。`main-bundle.js`には、バンドルされたコードが含まれています。

9.8 `main.ts`

これはウェブアプリのTypeScriptコードです。

import template from 'lodash/template';

const outputElement = document.getElementById('output');
if (outputElement) {
  const compiled = template(`
    <h1><%- heading %></h1>
    Current date and time: <%- dateTimeString %>
  `.trim());
  outputElement.innerHTML = compiled({
    heading: 'ts-demo-webpack',
    dateTimeString: new Date().toISOString(),
  });
}

9.9 ウェブアプリのインストール、ビルド、実行

まず、ウェブアプリが依存するすべてのnpmパッケージをインストールする必要があります。

npm install

次に、`package.json`内のスクリプトを使用して、(前のステップでインストールされた)webpackを実行する必要があります。

npm run wpw

以降、webpackはリポジトリ内のファイルの変更を監視し、変更を検出するたびにウェブアプリを再構築します。

別のコマンドラインで、`build/`の内容をlocalhostで提供するウェブサーバーを開始できます。

npm run serve

ウェブサーバーによって出力されたURLにアクセスすると、動作しているウェブアプリを見ることができます。

キャッシュのため、変更後の結果を見るには、単純なリロードだけでは不十分な場合があります。リロード時にShiftキーを押して強制リロードする必要がある場合があります。

9.9.1 Visual Studio Codeでのビルド

コマンドラインからビルドする代わりに、いわゆるビルドタスクを使用して、Visual Studio Code内からビルドすることもできます。

これで、「ターミナル」メニューから「ビルドタスクの実行…」を使用してwebpackを開始できます。

9.10 ローダーなしでのwebpackの使用:`webpack-no-loader.config.js`

`ts-loader`を使用する代わりに、まずTypeScriptファイルをJavaScriptファイルにコンパイルし、それらをwebpackでバンドルすることもできます。これらの2つのステップの最初のステップがどのように機能するかは、前の章で説明されています。

これで`ts-loader`を設定する必要がなくなり、webpackの設定ファイルが簡素化されます。

const path = require('path');

module.exports = {
  entry: {
    main: "./dist/src/main.js",
  },
  output: {
    path: path.join(__dirname, 'build'),
    filename: '[name]-bundle.js',
  },
  plugins: [
    new CopyWebpackPlugin([
      {
        from: './html',
      }
    ]),
  ],
};

`entry.main`が異なることに注意してください。もう一方の設定ファイルでは、それは…です。

"./ts/src/main.ts"

バンドルする前に中間ファイルを生成するのはなぜでしょうか?1つの利点は、Node.jsを使用して一部のTypeScriptコードの単体テストを実行できることです。