• 作成:
  • 更新:

npm scriptを使ってtypescript-eslint環境で複数のlintをターミナルで常に動かして成功をわかりやすくする

typescript-eslintは型エラーを報告しない

typescript-eslintはtscが警告するような型エラーを報告しないため, lintはeslintとtscの両方で行う必要があります. 場合によってはstylelintも行うでしょう.

よってnpm scriptのlintコマンドは以下のようになります.

{
  "scripts": {
    "lint": "run-p --print-label lint:*",
    "lint:eslint": "eslint --ignore-path .gitignore .",
    "lint:tsc": "tsc --noEmit"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^1.7.0",
    "eslint": "^5.16.0",
    "eslint-config-airbnb-base": "^13.1.0",
    "eslint-config-prettier": "^4.2.0",
    "eslint-plugin-import": "^2.17.3",
    "eslint-plugin-mysticatea": "^4.2.4",
    "eslint-plugin-prettier": "^3.0.1",
    "npm-run-all": "^4.1.5",
    "prettier": "^1.17.0",
    "typescript": "^3.4.5",
  }
}

watchで常に報告させる

毎回起動するのは鬱陶しいのでディレクトリの変更を見て起動してほしいものです.

私は watch - npm を使っています.

ネイティブならinotifywaitでも使いますが, 他人の環境に入っているとは限りませんので…

もっと良いのがあったら知りたい.

"watch:lint": "watch 'yarn lint' src",

これEmacsのロックファイルを有効にしてると大量起動して大変なことになるので, 今どき複数ユーザで同じファイルをEmacs同士で編集とかしてる人でもなければEmacs側の設定を切った方が良いです.

(custom-set-variables
 '(create-lockfiles nil)                ; ロックファイルとしてシンボリックリンクを作らない.parcelが大変なことになるので.
 )

成功したか終了を確認したい

エラー時はエラーが出てくれてわかりやすいですが, 成功時に成功してるのかまだ処理中なのかわからないという問題が発生しました.

run-sで解決しようと思いましたがタスクじゃないとダメなのでrun-pを入れづらいという問題があり面倒臭さにやめようかと思いましたが, post系でコマンドの実行後にコマンドを使えることを思い出しました.

"postlint": "echo -e '\\e[32mSuccess\\e[m'",

せっかくなので緑色で出したいのでそう書きました. zshだともっと簡単に書けるようですがターミナルのechoやprintfに256色で色をつける 完全版 - vorfee's Tech Blog そもそもnpm scriptのshellはデフォルトでbashなので使えないですね.

postによる解決策には冗長という問題点がありました

npm scriptの仕様で実行しているscriptが表示されるので, successを表示するscriptが表示されてしまい以下のように2重に表示されてしまいます.

% yarn lint
yarn run v1.16.0
$ run-p --print-label lint:*
[lint:eslint] $ eslint --ignore-path .gitignore .
[lint:tsc   ] $ tsc --noEmit
$ yarn success
$ echo -e '\e[32mSuccess\e[m'
Success
Done in 2.42s.
"success": "echo -e '\\e[32mSuccess\\e[m'",

のようにsuccessコマンドをまとめてしまうとさらに二重になってしまいますね…

私はpostによる解決を放棄することにしました.

"lint": "run-p --print-label lint:* && yarn --silent success",

yarn --silentで問題なくなりました.

% yarn lint
yarn run v1.16.0
$ run-p --print-label lint:* && yarn --silent success
[lint:eslint] $ eslint --ignore-path .gitignore .
[lint:tsc   ] $ tsc --noEmit
Success
Done in 2.51s.

watchパッケージ使わないほうが良いのでは

確かに. tscはwatchオプションありますがeslintはビルドインしてなくて敬遠してましたが eslint-watch - npm は使ってみたらなんてことはない簡単なパッケージでした. というわけで現在のpackage.jsonはこうです.

{
  "license": "MIT",
  "scripts": {
    "start": "web-ext run --firefox-profile goodbye-rfc-2822-date-time",
    "build": "parcel build src/main.ts",
    "package": "yarn build --no-source-maps && web-ext build --config web-ext-config.js",
    "watch:lint": "run-p --print-label watch:lint:*",
    "watch:lint:eslint": "esw --watch --color --cache --ext ts src",
    "watch:lint:tsc": "yarn lint:tsc --watch",
    "clean": "git clean -d --interactive -x",
    "lint": "run-p --print-label lint:*",
    "lint:eslint": "eslint --ignore-path .gitignore --ext .ts .",
    "lint:tsc": "tsc --noEmit",
    "fix": "run-p --print-label fix:*",
    "fix:eslint": "yarn lint:eslint --fix"
  },
  "dependencies": {
    "moment": "^2.24.0"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^1.7.0",
    "eslint": "^5.16.0",
    "eslint-config-airbnb-base": "^13.1.0",
    "eslint-config-prettier": "^4.2.0",
    "eslint-plugin-import": "^2.17.3",
    "eslint-plugin-mysticatea": "^4.2.4",
    "eslint-plugin-prettier": "^3.0.1",
    "eslint-watch": "^5.1.2",
    "npm-run-all": "^4.1.5",
    "parcel-bundler": "^1.12.3",
    "prettier": "^1.17.0",
    "typescript": "^3.4.5",
    "web-ext": "^3.0.0"
  }
}