TypeScript
webpack
babel
TSLint
prettier

TypeScript + TSLint + Prettier + Webpack環境を作成したときのメモ

More than 1 year has passed since last update.

TypeScriptは以前からちょくちょく触っていましたが、この度本格的に学習を始めたので、設定周りのメモを残しておきます。

TypeScriptReactを書き、TSLint + PrettierをかけつつWebpackでバンドルしたときの設定です。

各バージョンは以下のとおりです。

バージョン

TypeScript
2.8.3

Webpack
4.8.1

TSLint
5.10.0

Prettier
1.12.1


TypeScript

babelでいう.babelrcであるところのtsconfig.jsonで、コンパイルオプションを指定できます。

使っているTypeScriptのバージョンは2.8.3ですが、以下の記事がとても参考になりました。

tsconfig.json で指定できる全 compilerOptions をまとめた (TypeScript v2.5 版)

最終的に、tsconfig.jsonは以下のように設定しました。


tsconfig.json

{

"compilerOptions": {
"outDir": "./public/",
"module": "commonjs",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"removeComments": true,
"sourceMap": true,
"target": "es5",
"jsx": "react",
"lib": [
"es5",
"es6",
"dom"
]
},
"files": [
"@types/images.d.ts"
],
"include": [
"./src/**/*"
],
"exclude": [
"node_modules"
]
}

せっかくのTypeScriptなので、恩恵を受けるためにも基本的に厳しめのルールを設定しています。

また、TS内で画像をimportしてWebpackでバンドルするために、独自のd.tsファイルを定義しています。


@types/images.d.ts

declare module '*.png'


これを読み込むため、tsconfig.jsonfilesプロパティでファイルを指定しています。


TSLint + Prettier

LintにはTSLintを使い、フォーマッタとしてPrettierを併用します。

tslint.jsonに設定を記述していきます。

JavaScript Standard Styleを採用するため、tslint-config-standardを使用します。

また、Prettierと連携するためにtslint-plugin-prettierを、TSLintとPrettierのルール衝突を避ける(Prettierのルールを優先させる)ためにtslint-config-prettierを使います。


tslint.json

{

"rulesDirectory": [
"tslint-plugin-prettier"
],
"extends": [
"tslint-config-standard",
"tslint-config-prettier"
],
"rules": {
"prettier": [
true,
{
"singleQuote": true,
"semi": false
}
]
}
}

READMEにも書いてますが、tslint-config-prettierextendsプロパティの末尾に入れます。

個別に設定したいルールは、rulesプロパティに記述します。

Prettierのデフォルトでは、文字列リテラルはダブルクォーテーション使用、文末にセミコロンを記述する設定になっているので、それぞれ上書きしています。


Webpack

TypeScript-Webpack連携にawesome-typescript-loader、TSLint-Webpack連携にtslint-loaderを使います。


webpack.config.js

const webpack = require('webpack');

const path = require('path');

module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: {
bundle: path.join(__dirname, '../../src/typescript/index.tsx'),
},
output: {
path: path.join(__dirname, '../../public'),
filename: '[name].js',
},
module: {
rules: [
{
enforce: 'pre',
test: /\.tsx?$/,
use: [
{
loader: 'tslint-loader',
options: {
typeCheck: true,
fix: true,
},
},
],
},
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'awesome-typescript-loader',
},
{
enforce: 'pre',
test: /\.js$/,
use: 'source-map-loader',
},
{
test: /\.(jpg|png)$/,
use: 'url-loader',
},
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
devServer: {
host: 'localhost',
port: 9000,
contentBase: path.join(__dirname, '../../public'),
},
};


tslint-loaderのオプションでfix: trueとすることで、lint時に自動修正してくれます。

また、typeCheck: trueとしておかないと、tslint-config-standard使用時に以下のようなWarningが表示されます。

Warning: The 'await-promise' rule requires type information.

Warning: The 'no-unused-variable' rule requires type information.
Warning: The 'no-use-before-declare' rule requires type information.
Warning: The 'return-undefined' rule requires type information.
Warning: The 'no-floating-promises' rule requires type information.
Warning: The 'no-unnecessary-qualifier' rule requires type information.
Warning: The 'no-unnecessary-type-assertion' rule requires type information.
Warning: The 'strict-type-predicates' rule requires type information.

ただ、TSLint本家のtype check機能はdeprecatedなので、この辺りはまた変更されるかもしれません。


雑感


  • やはり型があると些細なミスに気付けて安心感がある

  • 上記設定でwatchしてるときにVimでコード書いてると、保存時に裏でtslintのfixが走って再読込しないといけないのでちょっと面倒


    • lint+フォーマットはWebpackに含めず、別のnpm scriptsにして任意のタイミングで走らせた方がやりやすいかも?