Help us understand the problem. What is going on with this article?

発表資料: sonarish で俺がお前を叱る

More than 3 years have passed since last update.

発表資料: sonarish で俺がお前を叱る

by mizchi
1 / 18

自己紹介

  • mizchi
  • フリーランス
  • リクルートでは yosuke_furukawa の元でR&Dみたいなことをしている

飛び入りLT用(発表ないかも)


yosuke_furukawa 「コードメトリクスツール作って」


コンテキスト

  • リクルート社内に膨大なJS含むプロジェクトがある
  • JSを(僕や yosuke_furukawa ぐらいに)真っ当に書ける人が少ない
  • いろんなプロダクトを串刺しでスコアリングして可視化したい

eslint は?

  • プロジェクトごとに運用のされ方が違う || そもそもない
  • 「1件でも落とすと exit-status = 1」 なので攻めたルールを採用しにくい

どうせだったらOSSにしようぜ => はい


※ 画面は開発中のものです


sonarish (仮)

$ npm i -g sonarish-cli
$ cd your-repo
$ sonarish src

実行例

$ cd sonarish
$ sonarish --detail
--- complexity
score: 96.4/100
┌──────────────────────┬───────┬──────────┬───────┐
│ rule                 │ score │ priority │ count │
├──────────────────────┼───────┼──────────┼───────┤
│ no-shadow            │ -2.6  │ 2        │ 2     │
├──────────────────────┼───────┼──────────┼───────┤
│ mutation/no-mutation │ -0.9  │ 1        │ 1     │
└──────────────────────┴───────┴──────────┴───────┘
--- best-practice
score: 92.9/100
┌───────────────────────────────────┬───────┬──────────┬───────┐
│ rule                              │ score │ priority │ count │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ import/no-extraneous-dependencies │ -2.5  │ 3        │ 4     │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ no-console                        │ -2    │ 1        │ 22    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ no-unused-vars                    │ -1.8  │ 1        │ 18    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ compat/compat                     │ -0.6  │ 1        │ 2     │
└───────────────────────────────────┴───────┴──────────┴───────┘
--- meta-comments
score: 63.8/100
┌───────────────────────────────────┬───────┬──────────┬───────┐
│ rule                              │ score │ priority │ count │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ no-warning-comments               │ -20.2 │ 4        │ 4     │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ eslint-comments/no-use            │ -7.9  │ 1        │ 10    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ eslint-comments/no-unused-disable │ -7.9  │ 1        │ 10    │
└───────────────────────────────────┴───────┴──────────┴───────┘


babel/babel

--- complexity
score: 61.1/100
┌──────────────────────┬───────┬──────────┬───────┐
│ rule                 │ score │ priority │ count │
├──────────────────────┼───────┼──────────┼───────┤
│ no-param-reassign    │ -15.7 │ 3        │ 106   │
├──────────────────────┼───────┼──────────┼───────┤
│ no-shadow            │ -9.2  │ 2        │ 78    │
├──────────────────────┼───────┼──────────┼───────┤
│ max-lines            │ -5.5  │ 2        │ 28    │
├──────────────────────┼───────┼──────────┼───────┤
│ mutation/no-mutation │ -5.2  │ 1        │ 601   │
├──────────────────────┼───────┼──────────┼───────┤
│ no-unreachable       │ -2.9  │ 4        │ 2     │
└──────────────────────┴───────┴──────────┴───────┘
--- best-practice
score: 86.4/100
┌───────────────────────────────────┬───────┬──────────┬───────┐
│ rule                              │ score │ priority │ count │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ prefer-arrow-callback             │ -4.8  │ 2        │ 503   │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ import/no-extraneous-dependencies │ -3.6  │ 3        │ 25    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ promise/always-return             │ -2    │ 2        │ 17    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ no-console                        │ -1.2  │ 1        │ 25    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ eqeqeq                            │ -0.8  │ 1        │ 13    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ import/no-mutable-exports         │ -0.6  │ 2        │ 2     │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ no-unused-vars                    │ -0.2  │ 1        │ 1     │
└───────────────────────────────────┴───────┴──────────┴───────┘
--- meta-comments
score: 34.1/100
┌───────────────────────────────────┬───────┬──────────┬───────┐
│ rule                              │ score │ priority │ count │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ no-warning-comments               │ -49.4 │ 4        │ 75    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ eslint-comments/no-use            │ -9.2  │ 1        │ 42    │
├───────────────────────────────────┼───────┼──────────┼───────┤
│ eslint-comments/no-unused-disable │ -7.1  │ 1        │ 25    │
└───────────────────────────────────┴───────┴──────────┴───────┘


オプション

$ sonarish [--root <root-path>] [--detail] 'src/**' 'subdir/**'

sonarish の 設計

  • 空白のスタイリングなどには関与しない(prettierでやれ)
  • ルールが落ちることを前提に、エラーカウント/合計ファイル数 で減点
  • 複数のカテゴリごとにeslintのルールセットを作る
  • カテゴリ内の priority を設定

「攻めたルール」の例

  • object-rest-spread あれば代入なんていらねーよな!
  • クラス以外で this なんてつかわねーよな!
  • 二重 if / switch はダサいよな!
  • 複雑な論理オペレータのネストはダサいよな!
  • TODOコメントなんて残んねーよな!

ダサいを可視化する

  • いわゆる codesmell の検出
  • 自分でそのためのeslintルールを書いてる(既存のものにそういうルール集はあんまりない)

スコアリングルール

そのルールの (エラー数/総ファイル数) * (priority/合計priority)

(実際は細かい正規化とスレッショルドがいっぱいあって調整中)


TODO

  • 自分でスコアルールを書けるようにする
  • ソースの公開
  • eslint 以外のツール対応
    • package.json の health check
    • コピペ検出
    • etc...

わかったこと

  • no-unused-vars は結構効く
  • TODO コメントはめっちゃ残ってる
  • eslintをまともに運用してるように見えてもeslint-disableを数えると結構やばい  

 

plaid
CXプラットフォーム「KARTE」の開発・運営、EC特化型メディア「Shopping Tribe」の企画・運営、CX特化型メディア「XD(クロスディー)」の企画・運営
https://plaid.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away