##はじめに
表題の通りですが、Babel 7でTypeScriptをトランスパイルをするための、webpack 4 + Babel 7 + TypeScript + TypeScript ESLint + Prettierの開発環境構築に関しての備忘録です。
記事本文に記載している開発環境はGitHubに置いてあります。
hira777/webpack-babel7-with-typescript
webpackやPrettierなどを理解していることを前提とした記事ですので、基礎知識を習得したい方は以下の記事をご覧ください。
開発環境の特徴
- Babel(webpackのbabel-loader)でTypeScriptをトランスパイルする。そのため、ts-loaderは利用しない。
- Babelでは型チェックはできないため、型チェックはTypeScript(
tsc
)でする。 - 構文チェックにはTSLintではなく、TypeScript ESLintを利用する。
- TypeScript ESLintをPrettierと併用して、コード整形もできるようにする。
Babel 7からTypeScriptのトランスパイルが可能になりました。少し前にJestがバージョンアップし、TypeScriptをサポートしましたが、それも BabelでTypeScriptをトランスパイルすることで実現しています。
しかし、型チェックはできないため、型チェックのためにTypeScriptが必要になります(Jestも同様で、テスト実行時に型チェックをするためにはts-jestが必要です)。また、ネームスペースなどの一部の TypeScipt 構文はトランスパイルできないです。
そして、TypeScript ESLintのversion1.x系もリリースされているので、それらを取り入れてみた開発環境になります。
そもそもBabelでTypeScriptをトランスパイルする意味はあるのか?
以下のような理由でBabelのエコシステム上でTypeScriptのコードを扱いたい状況でなければ、TypeScript単体の利用で良く、無理に併用する必要はないと思っています。
- Babelを利用したビルド環境がすでに存在し、環境を一から構築することはできないがTypeScriptを利用したい。
- 開発、もしくは利用しているライブラリなどが特定のBabelプラグインに依存している。
- 何らかの理由で、TypeScriptでトランスパイルしたJavaScriptをBabelでトランスパイルしており、トランスパイルをBabelだけで済むようにしたい。
また、以下の記事のようにBabelからTypeScriptに移行する手段もあるため、本記事のようなBabelとの併用はあくまで手段の1つとして認識していただければ良いと思います。
ディレクトリ構成
本記事での開発環境のディレクトリ構成は以下を前提とする(.babelrc
や.eslintrc
などの設定ファイルの詳細は後述)。
.
├── .babelrc
├── .eslintrc
├── package.json
├── public
│ └── bundle.js
├── src
│ ├── app.ts
│ └── modules
│ └── add.ts
├── tsconfig.json
└── webpack.config.js
package.json
パッケージをローカルインストールするため、package.json
は以下のコマンドで生成しておく。
npm init -y
# もしくは
# yarn init
app.ts
(エントリーポイント)
import add from './modules/add';
console.log(add(10, 5));
add.ts
export default function add(number1: number, number2: number): number {
return number1 + number2;
}
開発環境のセットアップ
- Babelのセットアップ
- webpackのセットアップ
- TypeScriptのセットアップ
- TypeScript ESLintとPrettierのセットアップ
Babelのセットアップ
ますはBabelを利用するために最低限必要なパッケージをインストールする。
npm i @babel/core @babel/preset-env -D
# もしくは
# yarn add @babel/core @babel/preset-env -D
BabelでTypeScriptをトランスパイルするためには以下のパッケージも必要なのでインストールする。
npm i @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/preset-typescript -D
# もしくは
# yarn add @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/preset-typescript -D
.babelrc
の設定
上記でインストールしたパッケージ(プリセットとプラグイン)を利用するため、設定は以下のようになる。
{
"presets": ["@babel/env", "@babel/typescript"],
"plugins": ["@babel/proposal-class-properties", "@babel/proposal-object-rest-spread"]
}
webpackのセットアップ
webpackを利用するために必要なパッケージをインストールする。前述の通りts-loaderはインストールしない。
npm i webpack webpack-cli babel-loader -D
# もしくは
# yarn add webpack webpack-cli babel-loader -D
webpack.config.js
の設定
BabelでTypeScriptをトランスパイルするため、以下のように拡張子が.ts
のファイルに対してbabel-loader
を実行するように設定する。
const { resolve } = require('path');
module.exports = {
// エントリーポイントの設定
entry: './src/app.ts',
// 出力の設定
output: {
// 出力するファイル名
filename: 'bundle.js',
// 出力先のパス(絶対パスを指定する必要がある)
path: resolve(__dirname, 'public')
},
resolve: {
extensions: ['.ts']
},
module: {
rules: [
{
// ローダーの処理対象ファイル
test: /\.ts$/,
// 利用するローダー
use: 'babel-loader',
// ローダーの処理対象から外すディレクトリ
exclude: /node_modules/
}
]
}
};
TypeScriptのセットアップ
型チェックを行うためにTypeScriptをインストールする。
npm i typescript -D
# もしくは
# yarn add typescript -D
tsconfig.json
の設定
include
は開発環境に応じて変更。
{
"compilerOptions": {
/* トランスパイル後のECMAScriptのバージョン */
"target": "esnext",
/* 相対パスではないモジュールは node_modules 配下を検索する */
"moduleResolution": "node",
/* 今回、トランスパイルは Babelが行うので、`tsc`コマンドでJavaScriptファイルを出力しないようにする */
"noEmit": true,
/* 厳格な型チェックオプション(noImplicitAny、noImplicitThis、alwaysStrict、
strictBindCallApply、strictNullChecks、strictFunctionTypes、
strictPropertyInitialization)を有効化する */
"strict": true,
/* 各ファイルを個々のモジュールとしてトランスパイルする。
Babel では技術的制約で、ネームスペースなどのファイルを跨いだ構文を解釈してトランスパイルできない。
このオプションを有効にすれば、Babel でトランスパイルできない TypeScriptの構文を検出して警告を出す */
"isolatedModules": true,
/* ES modules 形式以外の、CommonJS 形式などのモジュールを default import 形式で読み込める
例)const module = require('module') -> import module from 'module' */
"esModuleInterop": true
},
"include": ["src/**/*"]
}
TypeScript ESLintとPrettierのセットアップ
TypeScript ESLintを利用するために必要なパッケージをインストールする。
npm i eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin -D
# もしくは
# yarn add @typescript-eslint/parser @typescript-eslint/eslint-plugin -D
次に、PrettierとTypeScript ESLintを併用するために必要なパッケージをインストールする。
npm i prettier eslint-plugin-prettier eslint-config-prettier -D
# もしくは
# yarn add prettier eslint-plugin-prettier eslint-config-prettier -D
.eslintrc
の設定
以下のようにprettier/@typescript-eslint
を記述することで、plugin:@typescript-eslint/recommended
のコードフォーマット関連のルールが無効になり、Prettierとの競合を避けられる。
{
"parser": "@typescript-eslint/parser",
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"prettier/@typescript-eslint"
],
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true
}
]
}
}
動作確認
上記のセットアップが完了すれば、
- Babel(webpackのbabel-loader)でTypeScriptのトランスパイル
- TypeScript(
tsc
)で型チェック - TypeScript ESLintとPrettierを併用した状態でESLintの実行
が可能になるので、それぞれの処理を実行していく。
それぞれの処理を実行するために、package.json
に以下の記述を追加する。
"scripts": {
"check-types": "tsc",
"dev": "webpack --mode development",
"lint": "eslint --fix --ext .ts ./src"
}
Babel(webpackのbabel-loader)でTypeScriptのトランスパイルをする
npm run dev
# もしくは
# yarn dev
# 以下のような実行結果が出力される。
Hash: 91172258ce54870de710
Version: webpack 4.29.6
Time: 740ms
Built at: 2019-04-08 21:39:45
Asset Size Chunks Chunk Names
bundle.js 4.83 KiB main [emitted] main
Entrypoint main = bundle.js
[./src/app.ts] 173 bytes {main} [built]
[./src/modules/add.ts] 92 bytes {main} [built]
Babel(webpackのbabel-loader)でTypeScriptファイル(app.ts
、add.ts
)をトランスパイルできた。
TypeScript(tsc
)で型チェックをする
前述の通り、Babelは型チェックをしないため、以下のように変更をしてもトランスパイルできてしまう。
import add from './modules/add';
console.log(add(10, '5'));
TypeScript(tsc
)で型チェックをする。
npm run check-types
# もしくは
# yarn check-types
# 以下のような実行結果が出力される。
src/app.ts:5:36 - error TS2345: Argument of type '"5"' is not assignable to parameter of type 'number'.
5 console.log(add(10, '5'));
~~~
Found 1 error.
型チェックできた。
監視したい場合はnpm run check-types -- --watch
を実行する。
TypeScript ESLintとPrettierを併用した状態でESLintを実行する
npm run lint
# もしくは
# yarn lint
エラー出力とコード整形をできた。
終わり
本記事で記載した通り、BabelでTypeScriptのトランスパイルは簡単にできます。
状況によっては不要ですが、手段の1つとして覚えておくと役に立つかもしれません。
参考
お知らせ
Udemy で webpack の講座を公開したり、Kindle で技術書を出版しています。
Udemy:
webpack 最速入門(10,800 円 -> 2,000 円)
Kindle(Kindle Unlimited だったら無料):
React Hooks 入門(500 円)
興味を持ってくださった方はご購入いただけると大変嬉しいです。よろしくお願いいたします。