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
Google's AI Overviews - The New Search
badams
0
1k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
200
30 Presentation Tips
portentint
PRO
1
330
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
780
The SEO identity crisis: Don't let AI make you average
varn
0
490
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
How to make the Groovebox
asonas
2
2.2k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
My Coaching Mixtape
mlcsv
0
150
BBQ
matthewcrist
89
10k
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