コンパイルエラー,Lint エラーはトモダチなんだということをプログラマー初心者にこそ知ってほしい。

8 min read読了の目安(約7500字

Top
※画像がないと寂しいので自分で撮った写真を載せておきます。特に意味はないです。

エンジニアとして働き始めて3年。

ギリギリ初心者だった頃の気持ちを覚えている今、同じような悩みを抱えている人がいれば参考にしていただきたいので色々書いてみます。

今回はコンパイルエラーとlinter のお話。

最初は苦手意識を持ってしまいがちな2つですが、特に初心者の方こそトモダチになって欲しいです。

コンパイルエラーってうざいよね…

初心者がまず詰まるポイントとして、「コンパイルエラー」があると思います。

せっかく頑張って実装したのにいざ、起動しようとすると…

意味のわからない英語が無限に出てきてパニック…🤯

見た瞬間に拒否反応が出てしまうという方も多いと思います。

でもその認識は改めて欲しいです。

コンパイル・ビルドエラーはトモダチなのです。

うまく付き合えば、あなたのことをサポートしてくれます。

よく考えて欲しいコンパイルエラーが僕たちに伝えようとしていることを

うわまたエラーかよウゼェ…

と思う前に、コンパイルエラー君が言っていることに向き合ってみてほしいのです。

例えばこんな感じのエラーメッセージが出たとしましょう。(rubyの想定です)

Traceback (most recent call last):
// (省略)
sample.rb:10:in `sampleMthod': wrong number of arguments (given 1, expected 0) (ArgumentError)

うわ最悪…と思う前にちゃんと読んでみましょう。

エラーを翻訳してみます。

sample.rb:10

// sample.rbというファイル の10行目あたりに、

in `sampleMethod'

// sampleMethod でエラーがあるよ。

wrong number of arguments

// 引数の数が間違っているっぽい。

given 1, expected 0

// 1つの引数が与えられているけど、このメソットは引数0個を期待しているらしいよ。

ArgumentError

// まとめるとArgumentErrorというエラーが発生してます。

なんと読み解いてみると、

ここ間違ってますよ?ここうまく動かないですよ?と教えてくれているのですね。

実装して確認しようとした時に、実装のミスに気が付くことができます。

実装のミスに気づくタイミングは早い方がいいよね

実装のミスに気づくタイミングがもっと遅かったらどうでしょうか。

何かを新規実装した時大抵は以下の行程があります

実装→レビュー→自動テスト→手動テスト→本番リリース→公開

もし公開してからミスに気づいた場合どうなるでしょうか?

考えるだけでも恐ろしいですね…

経験がある人は嫌な記憶が蘇るかと思います…

手動テストでミスが発覚した場合を考えてみましょう。

変更がマージされ、検証環境に上がったのち、QAさんがテスト実施してくれます(開発者がやる場合もあるかも知れませんが、実装していない人だとしてください)。

テストの実施者が期待通りにならないことを発見し、実装者に確認。

実装者は再現方法などを聞き、原因調査。

原因がわかったら修正し、もう一度レビューをしてもらいます。

レビューが終わってマージしたら、再度手動テストでの確認を依頼し…

一般に行程が後ろであればあるほど

  • 開発者にFBがくるまでの時間
  • ミスの修正に着手するまでの時間
  • ミスが修正されていることを確認するまでの時間

が長くなり、手戻りコストが大きくなります。

つまり実装時に気づけると誰もが最も幸せになれるのです。

コンパイルエラーで拾えると、実装時にすぐにミスに気が付けるので

実は、とっても幸せなことだったりします。

JavaScriptは自由だ!コンパイルエラーなんてすり抜けてやる!!

さてここで問題になってくるのが、なかなかコンパイルエラーにならない言語達です。

その代表としてJavaScriptがあります。

javascriptはjavaなどの静的型付け言語と比較すると書き方の自由度が高く、一見変な書き方をしていてもコンパイルエラー、ビルドエラーになりにくい言語です。

JSでコンパイルエラーにならないラッキーと思っても

その時はうまく動いているように見えても、実際に動かしてみると…

あれ…なんか思っていた動きと違うぞ…ということがあります…

(動く環境による違いなど潜在的なバグが隠れている可能性が)

これを(コンパイルエラーの代わりに)、事前に教えてくれるのがLint君です。

Lint君は品質担保のお手伝いをしてくれる

特に初心者のうちは、どんなコードがバグになり易いかなんてわかりません。

そんな時、Lint君は「このコードバグになるかも知れないから直してね」と教えてくれる存在なのです。

他にも人によって書き方が異なっていたり、とりあえず動くけど読みづらいコードだったりも見つけて「これ直したほうがいいかもよ」と教えてくれる、なんなら代わりに直してくれることもあります。

人間のレビューでこれらのことを全てチェックし切るのは、なかなか無理があります…

初心者こそ、自分が潜在的なバグをチェックしきる自信がないならLint 君にコードの品質担保を手伝ってもらいましょう。

よしとりあえず導入しよう。何から始めようか

そう思って頂けた人に向けて、自分なりのおすすめを紹介します。

実は結構カスタマイズ性があり、

何を導入し何を導入しないかという判断は結構知識が必要だったりします。

今回初心者の方を対象としているので、気軽にLint 君とお友達になる方法を紹介します。

今回は例として、Vue.JS (ver2),scss, TypeScript は使用しないプロジェクトを想定します。

みんなのお友達。esLint君

色々なlint君がいますが、自分はこの人を推します。(自分に合うものを選べば良いと思います。)

あまりドキュメントから離れたことはしません。

どこ調べれば出てくるかもわからん…という方向けに引用元、参考リンクも掲載します。

公式ドキュメントはこちらです。

ESLint - Pluggable JavaScript linter

まずは、プロジェクトのディレクトリでインストールをしましょう。

自分のパッケージ管理ツールに応じた方法でインストールしてください。

$ npm install eslint --save-dev

# or

$ yarn add eslint --dev

次に初期設定です。

Lint 君から色々と質問がくるのでそれに答えてあげましょう。

$ npx eslint --init

# or

$ yarn run eslint --init

するとconfigファイルが追加されるはずですので確認しましょう。

ファイル形式は先ほどの選択によって変わります。

自分の場合こんな感じになりました設定の詳細はこちら

.eslintrc.js

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    "es2021": true
  },
  parserOptions: {
    parser: 'babel-eslint',
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  extends: [
    "eslint:recommended",
  ],
  plugins: [
    'vue'
  ],
  rules: {}
}

次に管理ツールに応じてショートカットが登録されているはずですので確認して見ましょう。

package.json

"scripts": {
    "lint": "eslint --ext .js,.vue",
  },

ここにコマンドがあれば成功です。

なければ自分で追加してOKです。

(もし余裕があればこの辺を参照しながらカスタマイズしましょう)

Command Line Interface

純粋なJSを使っている方はこの時点で実際に lint を走らせてみましょう

$ yarn lint

vue等を使っている場合にはもう少し設定をしましょう。

vue用設定を追加します。

$ yarn add -D eslint eslint-plugin-vue

Introduction | eslint-plugin-vue

設定ファイルにも使用する旨を追記。

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    "es2021": true
  },
  parserOptions: {
    parser: 'babel-eslint',
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  extends: [
    'plugin:vue/strongly-recommended', // これです。何を使うかは状況に応じて変えましょう
    "eslint:recommended",
  ],
  plugins: [
    'vue'
  ],
  rules: {}
}

さて、実際に lint を走らせてみましょう

$ yarn lint

もしエラーがなく、成功したらこのような表示になるはずです。

$ yarn lint
yarn run v1.22.10
$ eslint --ext .js,.vue 
✨  Done in 1.59s.

いかがでしょう。

何も設定していなければ、何も出てきませんが、

とりあえずレコメンドされているものを入れてみました

ちなみに指摘があるとこんな感じで出てきます

$ yarn lint
yarn run v1.22.10
$ eslint --ext .js,.vue 

project/components/base/Button.vue
  10:5  warning  Prop 'name' requires default value to be set   vue/require-default-prop
  11:5  warning  Prop 'color' requires default value to be set  vue/require-default-prop
  12:5  warning  Prop 'width' requires default value to be set  vue/require-default-prop

project/components/base/Footer.vue
  270:5  warning  Prop "width" should define at least its type  vue/require-prop-types

✖ 4 problems (0 errors, 4 warnings)

✨  Done in 1.94s.

それぞれどんな理由により指摘があるかは右の方に書いてあるやつです。

気に食わなければこちら参照してよくみてみましょう。

Available rules | eslint-plugin-vue

実はlint君は指摘するだけではなく、あなたの代わりに直してくれたりします。

$ yarn lint --fix

として実行するとlint君が直せる部分は代わりに直してくれます。

優しいですね…

styleLint君

実はlintはjSだけでなくCSSにもLint君がいるのです。

それがstylelintです。

A mighty, modern style linter · stylelint

こちらも導入方法を記載しておきます。

$ npm install --save-dev stylelint stylelint-config-standard

# or

$ yarn add --dev stylelint stylelint-config-standard

こちらは自分で設定していきましょう。

.stylelintrc という名前で作成します。

何も書いてないとエラーになってしまうので適当なものつけておきましょう

{
  "extends": "stylelint-config-standard"
}

ショートカットを書きます。

先ほどのeslintと区別するためにちょっとコマンドを書き換えます。

"scripts": {
    "lint:es": "eslint --ext .js,.vue ",
    "lint:css": "stylelint './**/*.{css,scss,vue}' ",
  },

とりあえず実行してみましょう

$ yarn lint:css

成功していればこのような表示になるはずです。

$ yarn lint:css
yarn run v1.22.10
$ stylelint './**/*.{css,scss,vue}' 
✨  Done in 0.55s.

設定を何もしていないので、何も出てきません。

ここから何をエラーにするか細かく設定していくのですが、

数が多いのでよくあるスタンダードな設定を適応してみます。

stylelint/stylelint-config-standard

$ npm install stylelint-config-standard --save-dev

# or

$ yarn add --dev stylelint-config-standard 

設定ファイルも書き換えましょう。

{
  "extends": "stylelint-config-standard",
}

これで一度実行してみて、出ているエラー、ワーニングをみてみましょう。

$ yarn lint:css

もし、いやイヤイヤリント君、これは別にいいんじゃない?このファイルは別にみなくても…

と思ったらここからルールを探して、 lint 君に教えてあげましょう。

こんな感じです。

{
  "extends": "stylelint-config-standard",
  "rules": {
    "selector-list-comma-newline-after": "always-multi-line"
  },
  "ignoreFiles": ["assets/resetcss/reset.css"]
}

今回はreset.cssを使用しているのですが、自分でメンテナンスしていくものではなかったので無視してもらいました。

このルールなんなの?と思ったらこちらにリストがあるのでみてみてください

List of rules · stylelint

最後にlint を個別に回すのが面倒なので、一つにまとめたショートカットを作ってみましょう

"scripts": {
    "lint": "yarn lint:es && yarn lint:css ",
    "lint:es": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "lint:css": "stylelint './**/*.{css,scss,vue}' ",
  },

これでひとまず完成です。

いかがでしたでしょうか。

意外と簡単ですよね。

改めて まとめると

  • コンパイルエラーは実装ミスを早い段階で教えてくれている
  • Lintは潜在的なエラーを教えてくれる。
  • 書き方の統一や、読みにくいコードも教えてくれる
  • lintはトモダチ。

拒絶反応が出てしまう初心者の方が、これを機にLint君とトモダチになってあげてもいいな。

と思って頂けたら幸いです。