この記事を書いた理由
どんなフロントエンドのフレームワークを使って開発するにせよ、現代のモダンフロントエンド開発にTypescriptはもはや必須といっても過言ではないわけですが、Typescript含めそれらの周辺のエコシステムを使用するための設定ファイルが多く、初学者にとってとっつきにくいものとなっています。
そのため、雰囲気で使用するとうまく動作していなかったり意図していない動作になったりする危険性があります。
そこで、本記事ではTypescript、Webpack、ESLint、Jest、Prettierの設定サンプルと主要な各設定項目とその内容を列挙していますので、これらを参考にしていただければ、いきなりフロントエンドの開発を任されてもある程度は対応できると思いますし、雰囲気で設定を記述するということも減り、適切な開発環境を構築することができるのではないかと思います。
環境
- node 16.17.0
- npm 8.15.0
- typescript 4.8.4
- webpack 5.74.0
- eslint 8.27.0
- jest 29.2.2
- prettier 2.7.1
Typescript
ツールの役割
- 型システムを活用することで、コードの品質を向上させる
- エディタ上で型補完が効くので、開発効率が向上する
設定ファイル
以下のコマンドにより、tsconfig.jsonが初期生成される
npx tsc --init
デフォルトの設定は以下の通り(typescript 4.8.4)
tsconfig.json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
分類 | 項目 | 内容 |
compiler Options | target |
|
module |
| |
esModuleInterop | CommonJS形式のモジュールをESModuleでimportする際などに、モジュールシステムの互換性を保つための設定 | |
forceConsistent CasingInFileNames | import時にファイルパスの文字列について大文字小文字を区別するかどうか | |
strict | コンパイル時の様々な厳格な型チェック機能を有効にする。Ex. noImplicitAny(any型が推論されたらエラーになる) https://www.typescriptlang.org/tsconfig/#strict | |
skipLibCheck | *.d.ts ファイルに対する型チェックをスキップする |
上記以外でよく使用する設定は以下の通り
分類 | 項目 | 内容 |
compiler Options | rootDir |
|
| outDir |
|
sourceMap | trueを指定することで、出力されたJavaScriptファイルに対応する元のTypeScriptソースを表示できるようになる | |
importsNotUsedAsValues | interfaceやtypeなど型の定義だけを持つのtsファイルのインポートは、import type の形式での記述を強制できる(コンパイルエラーにする) | |
resolveJsonModule |
| |
baseUrl | 相対パスによるimportを行う際の起点となるパス | |
paths |
| |
declaration |
| |
include | - |
|
exclude | - | コンパイルの非対象ファイルを指定(node_modulesなど) |
node.js(ver16)の環境かつ、フロントエンドでstrictモードで使用するという前提に立つと、以下のようになった
tsconfig.json
{
"compilerOptions": {
"target": "es2021",
"module": "esnext",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"rootDir": ".",
"outDir": "./dist", //明示的に記載
"sourceMap": true,
"importsNotUsedAsValues": "error",
"moduleResolution":"node",
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": [
"src/**/*.ts",
"tests/**/*.ts", // testsディレクトリのファイルからのimportがmodule not foundになるため
],
"exclude": [
"node_modules"
]
}
ちなみに、毎回設定ファイルを記載するのは面倒であれば、厳密な方チェックモードでtsconfigを自動生成してくれる便利なパッケージもあります @tsconfig/strictest
Jsプロジェクトに部分的にTsを導入したい
このような場合、以下の設定が必要となります。
分類 | 項目 | 内容 |
compilerOptions | allowJs |
|
compilerOptions | checkJs |
|
Webpack
ツールの役割
- 現代のフロントエンド開発には欠かせないモジュール(主にjsファイル)のバンドラー
- 開発用サーバーやホットリロードが実現できる
- 便利なプラグインやローダーを適用させることで、画像やcssも処理することが可能
設定ファイル
webpack.config.js
const path = require('path')
const ESLintPlugin = require('eslint-webpack-plugin')
module.exports = {
entry: {
bundle: path.join(__dirname, 'src', 'index.ts'),
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js', // [name]はentryで記述した名前(=bundle)
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js'],
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader',
},
],
},
plugins: [
new ESLintPlugin({
extensions: ['.ts', '.js'],
exclude: 'node_modules',
}),
],
devServer: {
hot: true,
host: 'localhost',
port: 8009,
static: {
directory: path.join(__dirname, 'dist'),
},
open: true,
},
}
主要な設定
分類 | 項目 | 内容 |
entry | bundle |
|
output | path | バンドル後のファイルを出力するファイルパスの指定 |
| filename | バンドル後のファイルを出力するファイル名の指定 |
devtool | - |
|
resolve | extensions | import文でファイル拡張子を省略して名前解決するための設定 import @/hoge/foo/bar.ts ↓ import @hoge/foo/bar |
| alias | 特定のディレクトリをエイリアスで表現できる(@など)ので、相対パスのimport(../../../)地獄を解消してくれる |
module | rules |
|
plugins | - | webpackビルドプロセスをカスタマイズするためのプラグインを指定する |
devServer | - |
|
| hot | HMRが有効になる(ソースコードを一部修正した場合に、ブラウザリロードなしに変更内容を反映させる) |
| open | trueを指定すると、初回ビルド完了時にブラウザを自動起動する
|
static | directory | webpack-dev-serverの公開フォルダ(ドキュメントルート) |
余談ですが、babel-loaderがなくても、ts-loaderのみで、Typescriptのトランスコンパイルは可能です。また、webpackでビルド時にeslintを走らせるためには、別途以下のライブラリが必要です。(後述します
npm install --save-dev eslint eslint-webpack-plugin @typescript-eslint/eslint-plugin @typescript-eslint/parser
ESLint
ツールの役割
- コードの静的解析が可能になる
- 一定のコーディング規約に沿ってコードが書かれているかどうか自動でチェックすることができる
- 規約に沿っていない場合にはエラーが表示され、 コードの一貫性を高めながら、バグを回避できる
設定ファイル
.eslintrc.js
module.exports = {
root: true,
plugins: ['@typescript-eslint'], //eslint-plugin-prettier非推奨のため指定しない
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
parser: '@typescript-eslint/parser',
parserOptions: {
sourceType: 'module',
project: './tsconfig.json',
},
env: {
browser: true,
es2021: true,
},
rules: {
'no-console': 'warn',
'no-var': 'error',
'@typescript-eslint/adjacent-overload-signatures': 'warn',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
},
};
主要な設定
分類 | 項目 | 内容 |
root | - |
|
plugins |
|
|
extends | - |
|
parser |
| ESLintは標準でJavaScriptのパースに対応していますが、TypeScriptも扱えるように(構文解析できるように)するには、@typescript-eslint/parserが必要 |
parserOptions | sourceType |
|
| project |
|
env | browser |
|
| es2021 | すべての ECMAScript 2021の構文や組込みオブジェクトを追加し、parserOptionsのecmaVersion: 2021に設定してくれる(ESLint のデフォルトパーサーは ECMAScript 5 の構文で記述されたコードを想定している) ※parserOptionsのecmaVersionの指定は不要になる |
rules | - |
|
余談ですが、eslint-plugin-prettierの使用は、非推奨となっています。(2020年6月以降)
ESLintで静的解析を行い、ESLintのフォーマットは無効にしつつ、Prettierでフォーマットを行うというのが一般的なすみ分けかと思いますが、eslint-plugin-prettierは、
ESLintとPrettierを一緒に使う場合にeslintの実行時にprettierの実行も行ってくれるようにするものです。
(prettierの実行をeslintが行うので、prettierのエラーもeslintのエラーとして出力される仕組み)
※なお、eslint-config-prettierは従来通り、eslintの設定ファイルのextendsにprettierとして指定する必要があります(ESLintにもフォーマット機能があり、prettierと競合しないようにするための機能なので、一番最後に指定すること)
eslintの設定とprettierのルールが衝突していないかどうかは以下のコマンドで確認可能
npx eslint-config-prettier 'src/**/*.{js,ts}'
一括修正コマンド
npm scriptsを活用して、eslintのエラー箇所を一括で修正することが可能です
masayan
上述の通り、これまでは、eslint-plugin-prettierによりeslint実行時にprettierが自動処理されていましたが、このプラグインを使用しないので、別途prettierも併せて実行するように指定してあげる必要があります
"scripts": {
"lint:fix": "eslint --cache --fix src && prettier --write src",
・・・
上記を追加し、以下を実行すると、
npm run lint:fix
eslintのルールに反しているコードは、自動で修正してくれます。ただし、自動で修正されるものとされないものがあり、arrow-body-styleやno-varなどのルールは自動で修正されますが、no-consoleなどは自動で修正されないので注意が必要です。
エディタの設定
なお、上記のようなコマンドを毎回実行するのは手間なので、VsCodeでコードを保存したタイミングでeslintの修正とprettierを実行したい場合は拡張機能のインストール後、setting.jsonに以下を追加します
※フォーマットはprettierが担うので、eslint.format.enableがtrueになっている場合はfalseにすること。
https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode", // prettierを使用する場合に必要な設定
"editor.codeActionsOnSave": [
"source.fixAll.eslint"
]
},
Prettier
ツールの役割
- コードフォーマッター。プロジェクト単位でコードのフォーマットを統一できるので、レビューの際などに人によってセミコロンがないとかで論争になる必要がなくなる
設定ファイル
.prettierrc
{
"printWidth": 120,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"endOfLine": "lf"
}
主要な設定
分類 | 項目 | 内容 |
printWidth | - | 折り返す行の長さ(def:80) |
tabWidth | - | インデントのスペースの数 |
semi | - | ステートメントの最後にセミコロン |
singleQuote | - | ダブルクォートの代わりにシングルクォート |
trailingComma | - | オブジェクト、配列などの末尾にカンマを自動的に追加 |
endOfLine | - | 改行の文字コードLFとする |
エディタの設定
VsCodeでコードを保存したタイミングでprettierを実行したい場合は拡張機能のインストール後、setting.jsonに以下を追加します
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
- formatOnSaveをtrueにして保存時にフォーマットが効くように
- フォーマッターにprettierを指定
以下のように、言語ごとに指定するのがおすすめ
{
"editor.formatOnSave": true,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
}
Jest
ツールの役割
- js, tsの単体テストが可能になり、コードの品質が向上する
設定ファイル
jest.config.js
module.exports = {
roots: ['<rootDir>/tests'],
testMatch: ['**/tests/**/*.test.ts'],
preset: 'ts-jest',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};
主要な設定
分類 | 項目 | 内容 |
roots | - |
|
testMatch | - |
|
preset | - |
|
moduleNameMapper | - |
|
eslintの適用
eslint-plugin-jestをインストールして、eslintの設定ファイルに追記することでテストの書き方などに対して、一定のルールを強制することが可能
module.exports = {
root: true,
plugins: ['@typescript-eslint', 'jest'],
extends: [
・・・
'plugin:jest/recommended', //Jestの書き方に関する推奨ルール一式
'plugin:jest/style', //Jestのスタイルルール系
],
・・・
rules: {
・・・
// jest関連
'jest/consistent-test-it': ['error', { fn: 'it' }], //testとitのうち、itを使うように強制する
'jest/require-top-level-describe': ['error'], //describe内に必ず配置するようにする(itやtestをむき出しで配置しない)
},
};
インストールしたライブラリと用途
package.json
{
・・・・
"devDependencies": {
"typescript": "^4.8.4",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"ts-loader": "^9.4.1",
"eslint": "^8.27.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^27.1.4",
"eslint-webpack-plugin": "^3.2.0",
"@typescript-eslint/eslint-plugin": "^5.42.0",
"@typescript-eslint/parser": "^5.42.0",
"jest": "^29.2.2",
"@types/jest": "^29.2.2",
"ts-jest": "^29.0.3",
"prettier": "^2.7.1",
}
}
項目 | 内容 | リポジトリ |
typescript | typescript本体 | |
webpack | webpack本体 | |
webpack-cli | webpackを実行するためのコマンドラインインターフェイス | |
webpack-dev-server | webpackを使用した開発用ローカルサーバー | |
ts-loader |
| |
eslint | eslint本体 | |
eslint-config-prettier | ESLintのルールの内、Prettierのルールと競合するものをOffにするライブラリ | |
eslint-plugin-jest | jestを用いたテストファイルに関してeslintのルールを適用できるライブラリ | |
eslint-webpack-plugin | webpackの処理時に、eslintを実行できる | |
@typescript-eslint/eslint-plugin | typescript用のeslintルールセット | |
@typescript-eslint/parser | typescriptの構文をeslintが解析できるようにするためのパーサー | |
jest | js, tsの単体テストツール | |
@types/jest | jestの型定義 | |
ts-jest | jestでtypescriptを扱えるようにするためのライブラリ | |
prettier | コードフォーマッター |
インストール手順
Typescript、Webpack、ESLint、Jest、Prettierを使用したモダンフロントエンド開発環境の構築手順をざっと紹介します。
初期化
- プロジェクト用のディレクトリ作成
- npm初期化
- indexファイル作成
$ mkdir frontend-package-sample cd frontend-package-sample
$ npm init -y
$ mkdir src && touch src/index.ts
TypeScript, Webpack
関連パッケージ・設定ファイル追加
$ npm install -D typescript ts-loader webpack webpack-cli
$ touch tsconfig.json webpack.config.js
※tsconfig.jsonおよびwebpack.config.jsの内容は割愛します。
ビルド
package.jsonにbuildコマンドを追加
"scripts": {
"build": "webpack --mode=development",
ビルドおよびバンドルされたjsを実行し問題なく動くことを確認する
$ npm run build
$ node dist/bundle.js
ESlint
Eslint関連のパッケージ・設定ファイル追加
※.eslintrc.jsの内容は割愛します。
$ npm install -D eslint @typescript-eslint/eslint-plugin eslint-config-prettier
$ touch .eslintrc.js
Prettier
Prettier関連のパッケージ・設定ファイル追加
※.prettierrcの内容は割愛します。
$ npm install -D prettier
$ touch .prettierrc
Lint用コマンド追加
package.jsonにコマンドを追加
"scripts": {
"lint": "eslint --ext .js,.ts --ignore-path .gitignore",
"lint:fix": "eslint --cache --fix src && prettier --write src",
Lintの実行
$ npm run lint
Lintエラーの修正とフォーマット
$ npm run lint:fix
Jest
Jest関連のパッケージ・設定ファイル追加
※jest.config.jsの内容は割愛します
$ npm install -D jest ts-jest @types/jest eslint-plugin-jest
$ touch jest.config.js
テスト用コマンド追加
package.jsonにコマンドを追加
"scripts": {
"test": "jest",
テストファイルを書いて、実行
$ touch tests/hoge.test.ts
$ npm run test
以上です。
まとめ
いかがでしたでしょうか。本記事では、Typescript、Webpack、ESLint、Jest、Prettierの設定サンプルと主要な各設定項目とその内容を列挙しています。この辺りの情報が体系的にまとまった記事等があまりないので、これらを参考にしていただければ、適切な開発環境を構築・設定することができるのではないかと思います