8
7

More than 5 years have passed since last update.

TypeScriptコードのコンパイルや TSLint 時にエラーが出る状態なら Commit できないように

Last updated at Posted at 2017-10-02

使うパッケージ

  • 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.jsontslint.jsonを作っておきます。

npx tsc --init
npx tslint --init

また、こんな感じのエラーが起きる.tsファイルも作っときます。

index.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.jsonlint-stagedプロパティへ設定を書きます。
インデックスされてるファイルの中にkey(ファイルのパターン)にマッチするものがあれば、それをvalue(run-scripts)に書かれたすべてのタスクに渡して実行します。

keyのパターンはminimatchというのを使ってるらしく、迷ったら
https://npm.runkit.com/minimatch 辺りでマッチするか試しながらやるといいかも。

設定をこのようにすると、インデックスされているindex.tsnpm run typescript -- index.ts && npm run tslint -- index.tsで実行する感じにできます。

{
  "lint-staged": {
    "*.{ts,tsx}": [
      "typescript",
      "tslint"
    ]
  }
}

run-scripttypescripttslintを登録

run-scriptsscriptsプロパティに書いていきます。

以下の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.jsoncompilerOptionsで必要な設定すべてをフラグにして渡す必要があります。

json-flagというnpmパケを作りました。こんな感じでcompilerOptionsをフラグに変換したものをコンソールに出せます。

npx json-flag -p compilerOptions tsconfig.json
# --target es5 --module commonjs --strict true

なので、先ほどをこんな感じに書き換えます。

{
  "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';
# 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できました〜。

# 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

cilintがコケまくってるプロジェクトにいいと思います😇

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7