Slide 1

Slide 1 text

ESLintϓϥάΠϯͰASTೖ໳ ৽ ೔ग़ւ / @ooDEMi

Slide 2

Slide 2 text

- Profile - Atarashi Hidemi Frontend Engineer @oodemi

Slide 3

Slide 3 text

JavaScript AST

Slide 4

Slide 4 text

Babel Webpack ESLint

Slide 5

Slide 5 text

AST ?

Slide 6

Slide 6 text

Abstract Syntax Tree ந৅ߏจ໦

Slide 7

Slide 7 text

! ?

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

! ??

Slide 10

Slide 10 text

ASTͱ͸Կ͔

Slide 11

Slide 11 text

AST 4 ίʔυΛจ๏తʹղऍ͠໦ߏ଄Ͱදݱͨ͠΋ͷ 4 JavaScript AST͸JSONͰදݱ͞ΕΔ 4 ESTree ͕ίϛϡχςΟඪ४

Slide 12

Slide 12 text

JavaScript → AST AST Explorer

Slide 13

Slide 13 text

JavaScript var message = "Hello AST";

Slide 14

Slide 14 text

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" }

Slide 15

Slide 15 text

1 lines → 44 lines

Slide 16

Slide 16 text

!

Slide 17

Slide 17 text

Ͱ΋େৎ෉ɺා͘ͳ͍

Slide 18

Slide 18 text

Կͱͳ͘෼͔Δ 4 Ұ෦ൈਮ "type": "VariableDeclarator" // ม਺એݴ "kind": "var" // "var"Ͱએݴ͞ΕͯΔ "name": "message" // ม਺໊͸"message" "range": [4, 11] // 4จࣈ໨~11จࣈ໨ "value": "Hello AST" // த਎͸"Hello AST"

Slide 19

Slide 19 text

AST͕Ͳ͏͍͏΋ͷ͔Կͱͳ ͘ཧղͰ͖ͨ !

Slide 20

Slide 20 text

Ͱ΋͜ΕΛԿʹ࢖͏ͷʁ

Slide 21

Slide 21 text

ESLint

Slide 22

Slide 22 text

ESLint 4 ASTΛݕূ͠ϧʔϧʹ౰ͯ͸·Δ΋ͷ͕͋Ε͹ ܯࠂΛग़͢ 4 ESLintͷϧʔϧ͸શͯϓϥάΠϯ 4 eslint/lib/rules 4 ࣗ࡞ϧʔϧ΋ϓϥάΠϯΛ࡞Ε͹ಈ͘ 4 Working with Plugins

Slide 23

Slide 23 text

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."); } } }; } };

Slide 24

Slide 24 text

ਅࣅͯ͠࡞ͬͯΈΔ

Slide 25

Slide 25 text

no-nemui-comment.js 1. ίʔυ಺ʹίϝϯτͰ[຾͍]͕ଘࡏͨ͠Β 2. [✘ ;͚ͨ͟ίϝϯτ͸ॻ͔ͳ͍ͰԼ͍͞.] ͱ͍͏ΤϥʔΛग़͢ 4 NGίʔυ: //຾͍ let status = "Nemui";

Slide 26

Slide 26 text

JavaScript → AST //຾͍ var status = "Nemui";

Slide 27

Slide 27 text

{ "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 ] } ] }

Slide 28

Slide 28 text

"comments": [ ίϝϯτͰ... { "type": "Line", छྨ͸LineComment "value": "຾͍", த਎͕ʮ຾͍ʯ "range": [ 0, 5 ] } ]

Slide 29

Slide 29 text

no-nemui-comment.js 'use strict'; module.exports = { create: (context) => { return { // 1. LineCommentͷ࣌ʹ "LineComment": (node) => { // 2. த਎͕ʮ຾͍ʯͩͬͨΒ if (node.value === "຾͍") { context.report(node, "✘ ;͚ͨ͟ίϝϯτ͸ॻ͔ͳ͍ͰԼ͍͞."); } } }; } };

Slide 30

Slide 30 text

.eslintrc { "extends": "eslint:recommended", "rules": { "no-nemui-comment": 2 } }

Slide 31

Slide 31 text

࣮ߦ 4 ESLint CLI $ eslint -c .eslintrc ./nemui.js --rulesdir ./rules

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

!

Slide 34

Slide 34 text

৽͍͠ϧʔϧͷ࣮૷ 4 ৽͍͠ϧʔϧΛద༻͍ͨ͠ίʔυΛAST ExplorerͰݟͳ͕Β࣮૷͢Δͱ؆୯ʹϧʔϧ Λ࡞Δ͜ͱ͕ग़དྷΔ 4 ͍ͭͰʹASTͷษڧ΋ग़དྷΔ

Slide 35

Slide 35 text

ศརͳϧʔϧΛ୔ࢁ ࡞ͬͯΈ·͠ΐ͏ʂ

Slide 36

Slide 36 text

͋Γ͕ͱ͏͍͟͝·ͨ͠ :) @ooDEMi