TypeScript
は以前からちょくちょく触っていましたが、この度本格的に学習を始めたので、設定周りのメモを残しておきます。
TypeScript
でReact
を書き、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
は以下のように設定しました。
{
"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
ファイルを定義しています。
declare module '*.png'
これを読み込むため、tsconfig.json
のfiles
プロパティでファイルを指定しています。
TSLint + Prettier
LintにはTSLintを使い、フォーマッタとしてPrettierを併用します。
tslint.json
に設定を記述していきます。
JavaScript Standard Styleを採用するため、tslint-config-standardを使用します。
また、Prettierと連携するためにtslint-plugin-prettierを、TSLintとPrettierのルール衝突を避ける(Prettierのルールを優先させる)ためにtslint-config-prettierを使います。
{
"rulesDirectory": [
"tslint-plugin-prettier"
],
"extends": [
"tslint-config-standard",
"tslint-config-prettier"
],
"rules": {
"prettier": [
true,
{
"singleQuote": true,
"semi": false
}
]
}
}
READMEにも書いてますが、tslint-config-prettier
はextends
プロパティの末尾に入れます。
個別に設定したいルールは、rules
プロパティに記述します。
Prettierのデフォルトでは、文字列リテラルはダブルクォーテーション使用、文末にセミコロンを記述する設定になっているので、それぞれ上書きしています。
Webpack
TypeScript-Webpack連携にawesome-typescript-loader、TSLint-Webpack連携にtslint-loaderを使います。
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にして任意のタイミングで走らせた方がやりやすいかも?