Slide 1

Slide 1 text

1 Let’s try to hack AST of JavaScript Sota Ohara 2019.7.4 Battle Conference U30

Slide 2

Slide 2 text

2 Tech Lead @ Mercari inc. Twitter: @sottar_ GitHub: @sottar Sota Ohara

Slide 3

Slide 3 text

3 - Introduce the AST - Create babel plugin Index

Slide 4

Slide 4 text

4 What’s an AST

Slide 5

Slide 5 text

5 Abstract Syntax Tree (抽象構文木)

Slide 6

Slide 6 text

6 What’s an AST An AST is the result of parsing source code. A tree data structure which extracted necessary information from the source code DOM Tree is one of them Used for analysis and processing the source code It’s using by the compiler and interpreter

Slide 7

Slide 7 text

7 It seems difficult...

Slide 8

Slide 8 text

8 JavaScript AST

Slide 9

Slide 9 text

9 JavaScript AST is not difficult We can use AST easily in JavaScript What’s a JavaScript AST?

Slide 10

Slide 10 text

10 Just a JavaScript Object which displays an architecture of code What’s a JavaScript AST?

Slide 11

Slide 11 text

11 ESTree de facto standard Parser Acorn Esprima Babylon: used by Babel, Acorn based Espree: used by ESLint, Acorn based What’s a JavaScript AST?

Slide 12

Slide 12 text

12 AST Flow Source Code AST New AST New Source Code parser traverser generator

Slide 13

Slide 13 text

13 Useful Tool AST Explorer

Slide 14

Slide 14 text

14 Let’s create a babel plugin

Slide 15

Slide 15 text

15 Create a babel plugin transform function take care the parser, traverser and generator. $ npm i -S @babel/core const { transform } = require("babel-core"); index.js

Slide 16

Slide 16 text

16 Replace var with const

Slide 17

Slide 17 text

17 Create a babel plugin index.js const { transform } = require("babel-core"); const src = "var foo = 'foooooo'" const plugin = ({ types }) => ({ visitor: { VariableDeclaration: nodePath => { if (nodePath.node.kind === "var") { nodePath.node.kind = "const"; } } } }); const { code } = transform(src, { plugins: [plugin] }); console.log(code); // -> const foo = 'foooooo'

Slide 18

Slide 18 text

18 That’s all

Slide 19

Slide 19 text

19 const { transform } = require("babel-core"); const src = "var foo = 'foooooo'" const plugin = ({ types }) => ({ visitor: { VariableDeclaration: nodePath => { if (nodePath.node.kind === "var") { nodePath.node.kind = "const"; } } } }); const { code } = transform(src, { plugins: [plugin] }); console.log(code); // -> const foo = 'foooooo' Create babel plugin index.js Original source code Generated source code

Slide 20

Slide 20 text

20 const { transform } = require("babel-core"); const src = "var foo = 'foooooo'" const plugin = ({ types }) => ({ visitor: { VariableDeclaration: nodePath => { if (nodePath.node.kind === "var") { nodePath.node.kind = "const"; } } } }); const { code } = transform(src, { plugins: [plugin] }); console.log(code); // -> const foo = 'foooooo' Create babel plugin index.js Call transform function with src and defined plugin

Slide 21

Slide 21 text

21 const { transform } = require("babel-core"); const src = "var foo = 'foooooo'" const plugin = ({ types }) => ({ visitor: { VariableDeclaration: nodePath => { if (nodePath.node.kind === "var") { nodePath.node.kind = "const"; } } } }); const { code } = transform(src, { plugins: [plugin] }); console.log(code); // -> const foo = 'foooooo' Create babel plugin index.js Kind of visitor pattern

Slide 22

Slide 22 text

22 Create babel plugin index.js const { transform } = require("babel-core"); const src = "var foo = 'foooooo'" const plugin = ({ types }) => ({ visitor: { VariableDeclaration: nodePath => { if (nodePath.node.kind === "var") { nodePath.node.kind = "const"; } } } }); const { code } = transform(src, { plugins: [plugin] }); console.log(code); // -> const foo = 'foooooo' Kind of visitor pattern This function will be fired when this label is found in the AST

Slide 23

Slide 23 text

23 Understand, but how to write it?

Slide 24

Slide 24 text

24 Useful Tools AST Explorer

Slide 25

Slide 25 text

25 Create babel plugin

Slide 26

Slide 26 text

26 Create babel plugin var foo = 'foooooo'

Slide 27

Slide 27 text

27 Create babel plugin var foo = 'foooooo'

Slide 28

Slide 28 text

28 Create babel plugin index.js const { transform } = require("babel-core"); const src = "var foo = 'foooooo'" const plugin = ({ types }) => ({ visitor: { VariableDeclaration: nodePath => { if (nodePath.node.kind === "var") { nodePath.node.kind = "const"; } } } }); const { code } = transform(src, { plugins: [plugin] }); console.log(code); // -> const foo = 'foooooo'

Slide 29

Slide 29 text

29 If you have any question or feedback, please get in touch with twitter (@sottar_) Thank you~

Slide 30

Slide 30 text

30 AST Explorer https://astexplorer.net/ Acorn https://github.com/acornjs/acorn Esprima https://github.com/jquery/esprima Babylon https://github.com/babel/babel/tree/master/packages/babel-parser Espree https://github.com/eslint/espree Appendix