Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
ESLintの独自ルール作成にチャレンジした話
Search
meijin
January 19, 2022
Technology
900
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ESLintの独自ルール作成にチャレンジした話
https://rakus.connpass.com/event/232039
meijin
January 19, 2022
More Decks by meijin
See All by meijin
Technical Decisions and Reflections on "Test Maker" After Two Years of Development
texmeijin
1
140
弊社の「意識チョット低いアーキテクチャ」10選
texmeijin
5
27k
DDDを志して3年経ったら「DDDの皮を被ったクリーンアーキテクチャ」になった話【デブサミ2024夏】
texmeijin
4
4.5k
サービス黎明期にNuxt.js v2からNext.js移行を決めた理由と進め方
texmeijin
0
550
スタートアップCTOが個人開発で収益化・年13本記事発信・5件登壇を平行するための時間管理
texmeijin
4
1.3k
個人開発がおすすめな理由
texmeijin
3
1.1k
弊社の開発体験の良いところは?メンバーに訊いてみた!
texmeijin
0
510
初めてESLintプラグインにコントリビュートした話
texmeijin
0
280
先生と一緒に プロダクトを良くする アナリティクス機能の開発
texmeijin
0
150
Other Decks in Technology
See All in Technology
WAF 運用改善の承認サイクル/SRE_BizReach_MIXI_1
visional_engineering_and_design
2
420
Claude Code本って、 読む必要あるの?
oikon48
2
380
When Does a Local Qwen Start to Break
morshoto
0
200
Oracle Cloud Infrastructure IaaS 新機能アップデート 2026/6 - 2026/8
oracle4engineer
PRO
0
140
Webとヘルスデータ
yukukotani
1
350
AI 駆動 Terraform 開発/SRE_BizReach_MIXI_2
visional_engineering_and_design
3
2k
アリアドネの糸と、20年ごとの建て替え ── 長尾真『電子図書館』を、伊勢で読み直す / Rereading Makoto Nagao’s "Electronic Library" in Ise
ykiyota
0
150
「重なり」は迎える側がつくる ― 人もAIエージェントも歓迎するプロダクトエンジニアリング ―
go0517go
PRO
0
280
作品が生態系になった ─ Mini Tokyo 3D から世界へ
nagix
0
150
Amazon S3 Tablesに全部任せてみた結果——コンパクション/スナップショット管理は本当に手放せるか
shigeruoda
1
460
プロダクト思考 × 基盤思考を AIで実現する Compound Engineering
tkc66buzz
1
310
GuardDuty 検知対応を DevOps Agent で効率化しようとしている話 / GuardDuty Investigations with DevOps Agent
masahirokawahara
1
350
Featured
See All Featured
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
240
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
840
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
570
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
590
Accessibility Awareness
sabderemane
1
210
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
The browser strikes back
jonoalderson
0
1.7k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Odyssey Design
rkendrick25
PRO
2
800
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
440
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Transcript
ESLint の独自ルール作成に チャレンジした話 株式会社 NoSchool meijin
目次 独自ルールを作ろうと思ったきっかけ 作って適用する手順 独自ルールの作りかた テストの書きかた 補足① TypeScript 対応 補足② 運用手段の候補
余談 勉強会の主催 まとめ
自己紹介 ニックネームは「名人」 Twitter: @Meijin_garden Web エンジニア6 年目 株式会社NoSchool CTO オンライン家庭教師マナリンク
-> https://manalink.jp 好きな分野はWeb フロントエンド 最近はWYSIWYG ライブラリのSlate.js に感動した 趣味は将棋(アマチュア二段くらい)
独自ルールを作ろうと思ったきっかけ ESLint って気軽にコードの品質を統一できて便利やな〜 業務上で、「今後はこのライブラリは使わないで欲しい」とか「この便利関数作ったからみんな使ってね」とい ったローカルルールを、レビューではなくLint で縛れたらいいな〜 でも、ESLint のルールって字句解析の知識とかないと作るの大変そう… → ちょっと作ってみるか!
独自ルールの大まかな手順 今回は以下の手順で独自ルールを動作させることができた。 独自ルールを記述したJavaScript(or TS) ファイルを作成して、 rules ディレクトリに置く npm scripts で
"lint": "eslint --rulesdir rules" のように記述して実行 ※ --rulesdir オプションはDeprecated なので、他の方法が有力(後述) https://eslint.org/docs/user-guide/command-line-interface
独自ルールの記述方法
本家のドキュメント 「Working with Rules 」 https://eslint.org/docs/developer-guide/working-with-rules 英語かつものすごく長く、(個人的には)理解に時間がかかるので、日本語の文献や巷のライブラリのコードを読み つつ進めるのが良いと思う。ある程度理解すると、公式ドキュメントが割と手にとるようにわかる(当社比)。 以後、これを分かっていれば公式ドキュメントの言っていることがなんとなくわかると思う知識をザッと書いていき ます。
ルールを記述する JS ファイルの構造 meta と create から構成される大きなオブジェクトをexport する 1 module.exports
= { 2 meta: { 3 type: "suggestion", 4 // ... 5 }, 6 7 create(context) { 8 return { 9 VariableDeclaration(node) { 10 // ... 11 } 12 }; 13 14 } 15 };
meta その名の通りルールのメタ情報(fix できる?suggest はある?) を表現するオブジェクト ESLint v8 から必要となるプロパティが追加されたみたいなので、昔の日本語記事など一部参考にならないものがあ るかも。要注意。 https://eslint.org/docs/user-guide/migrating-to-8.0.0#rules-require-metahassuggestions-to-provide-
suggestions 1 module.exports = { 2 meta: { 3 hasSuggestions: true 4 }, 5 create(context) { 6 // your rule 7 } 8 };
create create は context を受け取る関数で、AST のノードに対応してLint ルールを実装したオブジェクトを返す プログラム中のこの種類のノードに対しては、このチェックをする!という考えで実装する なのでLint に関係ないノードについては実装しなくてよい
ここで疑問に思ったことが2 つ AST ってなに?AST のノードってなに? どうやってLint ルールを実装するか?
AST とはなにか ( 広義には) 文字列で表現されたプログラムから演算子や変数など、文法的に意味のある情報のみを取り出して、 木構造で表現したもの プログラムは、【プログラム全体-> 複数のクラス-> 複数の関数-> 複数の変数宣言や代入など】といったように木構造で表現できる
分解した各部品のことをノードという プログラムを木構造で表現すると、プログラムから扱いやすくなる ESLint などの「プログラムを意味的に解釈して何らかの動作をするもの」を実装しやすくなる( 他にもbabel とか、Prettier とか、 esbuild とかも多分そう)
AST を覗いてみる https://astexplorer.net/ で簡単な式のAST 表現を見てみると、文字列のコードが巨大なJSON として表現される ことがわかる。超絶雑に図解すると以下の感じ
create に Lint ルールを実装する 引数 context に含まれる、エラーや警告をレポートする report() 関数や、node から変数名を取得できる
getDeclaredVariables() 関数を活用して、便利にルールを実装できる 1 // 変数名が _ から始まっていたらエラーになる独自ルールの例 2 create(context) { 3 return { 4 VariableDeclaration(node) { 5 context.getDeclaredVariables(node).forEach(variable => { 6 const name = variable.name; 7 if (name.charAt(0) === "_") { 8 context.report({ 9 node, 10 messageId: "unexpected", 11 data: { name } 12 }); 13 } 14 }); 15 } 16 }; 17 } VariableDeclaration が変数宣言ノードの種類名. context.getDeclaredVariables() で変数名を全取得. context.report() でLint 結果をレポート.
リファレンス リファレンスがあるので丸暗記をしなくてもOK context の仕様 https://eslint.org/docs/developer-guide/working-with-rules#the-context-object VariableDeclaration などのAST のノードの種類名 ESTree https://github.com/estree/estree/blob/master/es5.md
@types/eslint https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/eslint/index.d.ts#L438
テストの書きかた 1 const rule = require("../no-underscore-prefix"), 2 RuleTester = require("eslint").RuleTester;
3 const ruleTester = new RuleTester(); 4 ruleTester.run("no-underscore-prefix", rule, { 5 valid: [ 6 "'hoge'", 7 // ... 8 { code: "const obj = { _name: 'hoge' };", env: { es6: true } }, 9 ], 10 invalid: [ 11 { 12 code: "var _hoge = 'hoge';", 13 errors: [{ messageId: "unexpected", data: { name: "_hoge" }, type: "VariableDeclaration", 14 }, 15 // ... 16 { code: "let x,_y = 'hoge';", env: { es6: true }, errors: [{ messageId: "unexpected", data: { 17 // ... 18 ] 19 }); RuleTester を使ってテストを実装. valid / invalid キーで正常系と異常系を書く. RuleTester のコンストラクタでオプションも色々 設定できるらしい.
補足① TypeScript 対応 @types/eslint を使う 以下の記事が詳しい(厳密にはESLint7 時代の記事なので少しだけ注意が必要) https://blog.sa2taka.com/post/custom-eslint-rule-with-typescript ESLint 自体はts
を読み込んでくれないので、コンパイルフェーズを自前で組むことに注意
補足② 運用手段 冒頭で示した --rulesdir オプションはDeprecated あくまで外部プラグインとして、ローカルフォルダを読み込めるプラグインとしてのアプローチがいくつかある eslint-plugin-rulesdir https://github.com/not-an-aardvark/eslint-plugin-rulesdir eslintrc.js を使っている前提だが最も最新か?
https://github.com/cletusw/eslint-plugin-local-rules 使い方の癖があるように見えるが、任意のeslintrc の形式で対応できそう
余談 勉強会の主催 今回ESLint の独自ルールを調べるにあたって、勉強会を企画してみました https://connpass.com/event/232064/ 2021/12/13 に開催し、共催の RyoKawamata さんと2 時間作業してなんとか形にできた(ありがとうございました)
勉強会駆動開発(Meetup Driven Development, MDD ?)よさそう 勉強会企画したい方、一緒に主催できるので声かけてくださいw
まとめ ESLint の独自ルールを書くために難しい知識は必要ない ドキュメントは丁寧だが、概念をつかむまで少々大変なのと、 @types/eslint などを見たほうが理解が早く 進むところがあるので、手を動かして学ぶのが一番早そう 簡単なルールだったら業務でも作れそうな気がした(まだ作ってない) 勉強会駆動開発おすすめ
告知
Twitter フォローしてね @Meijin_garden だいたいWeb 開発の話か将棋の話してます 絶賛エンジニア採用中です! オンライン家庭教師のスタートアップです! 2020 年リリースで、これから塾や家庭教師や通信教育 を置き換える教育スタイルを広げていきます
少しでも興味があればカジュアル面談歓迎なので、DM やMeety でお声がけください!!
ご清聴ありがとうございました