KDE BLOG

Webデザインやコーディングについて書いています

【webpack速習】vol.11: TypeScript

下記ページをざっくりとまとめます。

webpack.js.org

TypeScriptとwebpackを統合する方法を学ぶ。

Basic Setup

typescript と ts-loader をインストール

yarn add --dev typescript ts-loader

ディレクトリ構成

project
  |- package.json
+ |- tsconfig.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
    |- index.js
+   |- index.ts
  |- /node_modules

▼ tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true
  }
}

▼ webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: [ '.tsx', '.ts', '.js' ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

これはwebpackに ./index.ts を介して入り、ts-loader を介してすべての .ts ファイルと .tsx ファイルをロードし、現在のディレクトリに bundle.js ファイルを出力するように指示する設定です。

Loader

他のWebアセットのインポートなど、追加のWebpack機能を有効にするのが少し簡単になるため、ts-loaderを使用

Source Maps

typescriptのsource mapを有効にするには、コンパイル後のJavaScriptファイルにインラインソースマップを出力するように、tsconfig.json に下記を追加する

{
  "compilerOptions": {
    "outDir": "./dist/",
+  "sourceMap": true,
    "noImplicitAny": true,
    "module": "commonjs",
    "target": "es5",
    "jsx": "react",
    "allowJs": true
  }
}

そしてこれらのsource-mapを抽出して最終バンドルに含めるようにwebpackに指示する必要がある

▼ webpack.config.json

// 略
module.exports = {
    entry: './src/index.ts',
+   devtool: 'inline-source-map',
    module: {
    // 略

Using Third Party Libraries

npmからサードパーティのライブラリをインストールするときは、そのライブラリの型定義を忘れずにインストールすることが重要
これらの定義は TypeSearch にある。

例えば lodashをインストールする場合であれば下記で型定義ファイルをインストールできる。

yarn add --dev @types/lodash

Importing Other Assets

TypeScriptでコード以外のアセット(画像など)を使用するには、これらのインポートの型定義を延期する必要がある。
そのためにはプロジェクト内のTypeScriptのカスタム定義を表すcustom.d.tsファイルを作成する。

▼ custom.d.ts (プロジェクト直下でもいいし、src直下でも良かった)

declare module "*.jpg" {
  const content: any;
  export default content;
}

ここでは「.jpg」で終わるインポートを指定し、そのモジュールの内容をanyとして定義することによって、jpg用の新しいモジュールを宣言する。
型を文字列として定義することで、それがURLであることをより明確にすることができる。
同じ概念が、CSS、SCSS、JSONなどを含む他のアセットにも適用される。

これによりtypescript内でjpgを使用することができるようになった。

▼ src/index.ts

import * as _ from 'lodash';
import './style.css';
import pic from './picture.jpg';

function component(): HTMLElement {
  const img: HTMLImageElement = new Image();
  const element: HTMLElement = document.createElement('div');
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  img.src = pic;
  element.appendChild(img);
  return element;
}

document.body.appendChild(component());