使うパッケージ
- TypeScript » コンパイルするため
- TSLint » lint するため
-
husky »
git commit
時にnpm run precommit
とか実行させるため。npm run precommit
が正常に終わった時だけ実際にcommit
とかする。 - lint-staged » 対象ファイルを適当なコマンドへ渡すため
準備
まずは上記のパッケージをインストール。
npm init -y # package.json 作成
npm i -D typescript tslint husky lint-staged
そして、tsconfig.json
とtslint.json
を作っておきます。
npx tsc --init
npx tslint --init
また、こんな感じのエラーが起きる.ts
ファイルも作っときます。
const foo: number = 'foo';
tree -I node_modules # node_modules は非表示
.
├── index.ts
├── package-lock.json
├── package.json
├── tsconfig.json
└── tslint.json
lint-staged
の設定
package.json
のlint-staged
プロパティへ設定を書きます。
インデックスされてるファイルの中にkey
(ファイルのパターン)にマッチするものがあれば、それをvalue
(run-scripts)に書かれたすべてのタスクに渡して実行します。
key
のパターンはminimatch
というのを使ってるらしく、迷ったら
https://npm.runkit.com/minimatch 辺りでマッチするか試しながらやるといいかも。
設定をこのようにすると、インデックスされているindex.ts
をnpm run typescript -- index.ts && npm run tslint -- index.ts
で実行する感じにできます。
{
"lint-staged": {
"*.{ts,tsx}": [
"typescript",
"tslint"
]
}
}
run-script
にtypescript
とtslint
を登録
run-scripts
はscripts
プロパティに書いていきます。
以下のtsc --project .
やtslint --project .
は、tsconfig.json
の設定を使って色々処理できるやつで、まぁCLIではそんな感じで使ってると思います。
--noEmit
を使うと.js
ファイルがアウトプットされなくなります。
ということで、こんな感じに書けば良さそうに思えます。が、これはエラーで終わります。
{
"scripts": {
"precommit": "lint-staged",
"typescript": "tsc --project . --noEmit",
"tslint": "tslint --project .",
}
多分tsc --project . foo.ts
のようなコマンドが実行されてるのですが、--project
フラグとfoo.ts
のようなファイル指定は一緒にはできない感じのようです。
error.log
Option 'project' cannot be mixed with source files on a command line.
なので、`typescript`へは`tsconfig.json`の`compilerOptions`で必要な設定すべてをフラグにして渡す必要があります。
> [`json-flag`](https://github.com/nju33/json-flag)という`npm`パケを作りました。こんな感じで`compilerOptions`をフラグに変換したものをコンソールに出せます。
>
> ```bash
> npx json-flag -p compilerOptions tsconfig.json
> # --target es5 --module commonjs --strict true
> ```
なので、先ほどをこんな感じに書き換えます。
```json
{
"scripts": {
"precommit": "lint-staged",
"typescript": "tsc --target es5 --module commonjs --strict true --noEmit",
"tslint": "tslint --project .",
}
}
追記(2017-12-05)
上のtypescript
についてです。全部対象になりますが、"typescript": "tsc -p . --noEmit #"
というように最後に#
を置いて渡ってきたファイル名をコメント扱いにするほうが簡単でした。
準備できたので成果をCommitする
上記のindex.ts
を使ってれば、git commit
して時こんな感じになってコケます。
たまに何故か
precommit
ホック動かない時があるので、再度npm i -D husky
してください😱
git init
git add index.ts
git commit -m 'Commit'
# husky > npm run -s precommit (node v8.5.0)
#
# ❯ Running tasks for *.{ts,tsx}
# ✖ typescript
# → index.ts(1,7): error TS2322: Type '"foo"' is not assignable to type 'number'.
# tslint
#
# ✖ typescript found some errors. Please fix them and try committing again.
# index.ts(1,7): error TS2322: Type '"foo"' is not assignable to type 'number'.
# husky > pre-commit hook failed (add --no-verify to bypass)
(上記の工程でやってるとして)typescript
を修正してもtslint
でもコケます。
index.ts
- const foo: number = 'foo';
- const foo: string = 'foo';
```bash
# husky > npm run -s precommit (node v8.5.0)
#
# ❯ Running tasks for *.{ts,tsx}
# ✔ typescript
# ✖ tslint
# → ERROR: /Users/nju33/test/hogeaaa/index.ts[1, 21]: ' should be "
# ✖ tslint found some errors. Please fix them and try committing again.
#
# ERROR: /Users/nju33/test/hogeaaa/index.ts[1, 21]: ' should be "
#
# husky > pre-commit hook failed (add --no-verify to bypass)
index.ts
- const foo: string = 'foo';
- const foo: string = "foo";
`tslint`を修正してようやく成果を`commit`できました〜。
```bash
# husky > npm run -s precommit (node v8.5.0)
#
# ✔ Running tasks for *.{ts,tsx}
# [master (root-commit) 789b35b] Commit
# 1 file changed, 1 insertion(+)
# create mode 100644 index.ts
ci
でlint
がコケまくってるプロジェクトにいいと思います😇