Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ESLintプラグインでAST入門
Search
oodemi
May 28, 2016
1.1k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ESLintプラグインでAST入門
oodemi
May 28, 2016
More Decks by oodemi
See All by oodemi
開発プロセスの改革を促進し変化を楽しむチームを作る「振り返り」
oodemi
1
180
Building Design Systems with Atomic Design
oodemi
4
5.5k
マイクロインタラクション
oodemi
0
380
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
141
7.5k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
150
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
430
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
290
WCS-LA-2024
lcolladotor
0
630
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
210
Speed Design
sergeychernyshev
33
1.8k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
Transcript
ESLintϓϥάΠϯͰASTೖ ৽ ग़ւ / @ooDEMi
- Profile - Atarashi Hidemi Frontend Engineer @oodemi
JavaScript AST
Babel Webpack ESLint
AST ?
Abstract Syntax Tree நߏจ
! ?
None
! ??
ASTͱԿ͔
AST 4 ίʔυΛจ๏తʹղऍ͠ߏͰදݱͨ͠ͷ 4 JavaScript ASTJSONͰදݱ͞ΕΔ 4 ESTree ͕ίϛϡχςΟඪ४
JavaScript → AST AST Explorer
JavaScript var message = "Hello AST";
AST { "range": [ 0, 25 ], "type": "Program", "body":
[ { "range": [ 0, 25 ], "type": "VariableDeclaration", "declarations": [ { "range": [ 4, 25 ], "type": "VariableDeclarator", "id": { "range": [ 4, 11 ], "type": "Identifier", "name": "message" }, "init": { "range": [ 14, 25 ], "type": "Literal", "value": "Hello AST", "raw": "\"Hello AST\"" } } ], "kind": "var" } ], "sourceType": "module" }
1 lines → 44 lines
!
Ͱେৎɺා͘ͳ͍
Կͱͳ͔͘Δ 4 Ұ෦ൈਮ "type": "VariableDeclarator" // มએݴ "kind": "var" //
"var"Ͱએݴ͞ΕͯΔ "name": "message" // ม໊"message" "range": [4, 11] // 4จࣈ~11จࣈ "value": "Hello AST" // த"Hello AST"
AST͕Ͳ͏͍͏ͷ͔Կͱͳ ͘ཧղͰ͖ͨ !
Ͱ͜ΕΛԿʹ͏ͷʁ
ESLint
ESLint 4 ASTΛݕূ͠ϧʔϧʹͯ·Δͷ͕͋Ε ܯࠂΛग़͢ 4 ESLintͷϧʔϧશͯϓϥάΠϯ 4 eslint/lib/rules 4 ࣗ࡞ϧʔϧϓϥάΠϯΛ࡞Εಈ͘
4 Working with Plugins
no-var.js "use strict"; module.exports = { create: function(context) { return
{ // 1. VariableDeclarationͷnodeʹ౸ୡͨ͠Β࣮ߦ͞ΕΔ VariableDeclaration: function(node) { // 2. var͕ΘΕ͍ͯͨΒΤϥʔϝοηʔδΛදࣔ͢Δ if (node.kind === "var") { context.report(node, "Unexpected var, use let or const instead."); } } }; } };
ਅࣅͯ͠࡞ͬͯΈΔ
no-nemui-comment.js 1. ίʔυʹίϝϯτͰ[͍]͕ଘࡏͨ͠Β 2. [✘ ;͚ͨ͟ίϝϯτॻ͔ͳ͍ͰԼ͍͞.] ͱ͍͏ΤϥʔΛग़͢ 4 NGίʔυ: //͍
let status = "Nemui";
JavaScript → AST //͍ var status = "Nemui";
{ "range": [ 6, 27 ], "type": "Program", "body": [
{ "range": [ 6, 27 ], "type": "VariableDeclaration", "declarations": [ { "range": [ 10, 26 ], "type": "VariableDeclarator", "id": { "range": [ 10, 16 ], "type": "Identifier", "name": "status" }, "init": { "range": [ 19, 26 ], "type": "Literal", "value": "Nemui", "raw": "\"Nemui\"" } } ], "kind": "var" } ], "sourceType": "module", "comments": [ { "type": "Line", "value": " ͍", "range": [ 0, 5 ] } ] }
"comments": [ ίϝϯτͰ... { "type": "Line", छྨLineComment "value": "͍", த͕ʮ͍ʯ
"range": [ 0, 5 ] } ]
no-nemui-comment.js 'use strict'; module.exports = { create: (context) => {
return { // 1. LineCommentͷ࣌ʹ "LineComment": (node) => { // 2. த͕ʮ͍ʯͩͬͨΒ if (node.value === "͍") { context.report(node, "✘ ;͚ͨ͟ίϝϯτॻ͔ͳ͍ͰԼ͍͞."); } } }; } };
.eslintrc { "extends": "eslint:recommended", "rules": { "no-nemui-comment": 2 } }
࣮ߦ 4 ESLint CLI $ eslint -c .eslintrc ./nemui.js --rulesdir
./rules
None
!
৽͍͠ϧʔϧͷ࣮ 4 ৽͍͠ϧʔϧΛద༻͍ͨ͠ίʔυΛAST ExplorerͰݟͳ͕Β࣮͢Δͱ؆୯ʹϧʔϧ Λ࡞Δ͜ͱ͕ग़དྷΔ 4 ͍ͭͰʹASTͷษڧग़དྷΔ
ศརͳϧʔϧΛࢁ ࡞ͬͯΈ·͠ΐ͏ʂ
͋Γ͕ͱ͏͍͟͝·ͨ͠ :) @ooDEMi