Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
JavaScript ASTことはじめ /JavaScript AST
Medley Inc.
June 22, 2018
Technology
1
12k
JavaScript ASTことはじめ /JavaScript AST
メドレー開発本部の社内勉強会「TechLunch」で、JavaScript ASTについて紹介させていただきました。
発表者:平木聡
Medley Inc.
June 22, 2018
Tweet
Share
More Decks by Medley Inc.
See All by Medley Inc.
組織の急成長を実現するための メドレーの人事戦略と Workday の活用
medley
0
200
FY22 新卒研修 Quality Assurance 〜「QA」「品質」「テスト」とは?〜
medley
1
1.1k
これからのDX時代のエンジニアに求められること ~医療業界へのアプローチを通じて~
medley
2
4.1k
業界特化型プロダクトを開発するために必要なこと
medley
3
1.5k
メドレー エンジニア採用資料/ Medley Engineer Guide
medley
3
5k
メドレー 会社説明資料/ Medley Company Guide
medley
12
30k
クラウド診療支援システム CLINICSの目指す世界
medley
3
410
開会の挨拶 - FHIR Meetup Tokyo #01
medley
1
290
電子処方箋実証事業におけるFHIRの活用 - FHIR Meetup Tokyo #01
medley
2
390
Other Decks in Technology
See All in Technology
Raspberry Pi Camera 3 介紹
piepie_tw
PRO
0
100
日本ディープラーニング協会主催 NeurIPS 2022 技術報告会講演資料
tdailab
0
930
NGINXENG JP#2 - 3-NGINX Plus・プロダクトのアップデート
hiropo20
0
160
アムロは成長しているのか AIから分析する
miyakemito
1
340
Optimizing your Swift code
kateinoigakukun
0
1.3k
データエンジニアを助けてくれるFivetranとSnowflakeの仕様&機能のご紹介
sagara
0
430
GraphQLスキーマ設計の勘所
yukukotani
26
5.9k
PHPのimmutable arrayとは
hnw
1
140
CUEとKubernetesカスタムオペレータを用いた新しいネットワークコントローラをつくってみた
hrk091
0
230
2022年に起きたフロントエンドの変化
sakito
29
17k
LINE iOSエンジニアの日々 / LINE iOS Engineer Days
line_developers
PRO
1
130
20230123_FinJAWS
takuyay0ne
0
110
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
69
7.5k
How GitHub Uses GitHub to Build GitHub
holman
465
280k
Testing 201, or: Great Expectations
jmmastey
25
5.7k
Teambox: Starting and Learning
jrom
124
7.9k
Automating Front-end Workflow
addyosmani
1351
200k
The Language of Interfaces
destraynor
149
21k
Making Projects Easy
brettharned
102
4.8k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
22
1.7k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
120
29k
Put a Button on it: Removing Barriers to Going Fast.
kastner
56
2.5k
BBQ
matthewcrist
75
8.1k
10 Git Anti Patterns You Should be Aware of
lemiorhan
643
54k
Transcript
JavaScript AST͜ͱ͡Ί
Agenda • JavaScript ASTͱԿ͔? • JavaScript ASTͷجૅࣝ • JavaScript ASTͬͯԿ͔ͯ͠ΈΔ
JavaScript ASTͱԿ͔?
ͦͦASTͱ ͦͦASTநߏจͷӳޠ໊Ͱ͋Δabstract syntax treeͷུ শʹͳΓ·͢ɻίϯύΠϥͱ͔ΠϯλϓϦλͳͲͷݴޠॲཧܥͷ தؒॲཧʹྑ͘ΘΕΔख๏Ͱ͢ɻ(ͳ͓؊ػೳͷʹಉ͡ ASTͱ͍͏ུশ͕͋Δ༷) h"ps:/ /en.wikipedia.org/wiki/Abstractsyntaxtree
ͦͦASTͱ ΩϞͱͯ͠ॻ͔Ε͍ͯΔϓϩάϥϜΛߏจղੳͯ͠ߏԽʹෆ ཁͳ෦আͯ͠ɺߏͱͯ͠දݱ͍ͯ͠Δσʔλʹ͢Δͱ ͍͏ͱ͜ΖͰ͢ɻ
ͦͦASTͱ ͜ͷASTࣗମಛʹJSݻ༗ͷͷͱ͍͏Θ͚Ͱͳ͘ɺ৭ʑͳݴ ޠͰΘΕ͍ͯ·͢ɻྫ͑JavaͰΘΕΔIDEͷEclipseͰJava ͷߏจղੳʹͬͯͨΓ͢ΔͬΆ͍Ͱ͢ɻ h"p:/ /www.eclipse.org/ar1cles/Ar1cle- JavaCodeManipula1on_AST/index.html ͜ͷASTʹ͍ۙख๏Ͱ(ݫີʹҧ͏)ߏங͞Ε͍ͯΔͷ͕ۙͰ͍ ͏ͱDOMͩͬͨΓ͠·͢ɻ
JavaScript ASTͲ͜ͰΘΕ͍ͯΔͷ͔? • React • Babel • UglifyJS • ESLint
• PowerAssert ͳͲͳͲ
JavaScript ASTͲ͜ͰΘΕ͍ͯΔͷ͔? ҰྫͰ͕͢ݱࡏͷϑϩϯτΤϯυ։ൃʹ͔ܽͤͳ͍ϓϩμΫτ େମΘΕͯΔΜ͡Όͳ͍Ͱ͠ΐ͏͔ɻ มΘΓμωͱͯ͠ಠࣗʹJSͷϚΫϩΛ࡞ΕΔsweet-js/sweet-core ͳΜ͔ͰΘΕ͍ͯ·͢ɻ
JavaScriptք۾ͰͷASTͷաڈ JSք۾ͰͷASTͷऔΓѻ͍ͳͲͷผʹྺ࢙Λશ෦ͬͯΔΘ ͚͡Όͳ͍ΜͰ͕͢ɺ͔͍ͭ·ΉͱҎԼͷΑ͏ͳྲྀΕʹͳΔ͔ ɻ
JavaScriptք۾ͰͷASTͷաڈ • FirefoxͰΘΕ͍ͯͨSpiderMonkyͰ2010ʹParser API͕ ࡌ͞Εͨ • Parser APIͷJSϙʔτͷzaach/reflect.js͕20114݄͘Β͍ʹϦ Ϧʔε
JavaScriptք۾ͰͷASTͷաڈ • JavaScript ASTͰຊ֨తʹΘΕͩͨ͠jquery/esprima͕2011 11݄͘Β͍ʹϦϦʔε • ݩʑ࡞ऀͷAriya͞ΜͷݸਓϓϩδΣΫτ͚ͩͬͨͲɺ3 ͘Β͍લʹjQueryࡒஂʹҠ • esprima͍͗ͬͯͬͯ͢acornjs/acorn͕ొ
JavaScriptք۾ͰͷASTͷաڈ • ࠷ॳacornͬͯͨBabel͕ੜͤͯࣗ͞લͰbabel/babylonΛ 20129݄͘Β͍͔Β࡞ͬͨΓ • ༷֎ͷ͜ͱͰ͖ΔΑ͏ʹ֦ு͞ΕͯΔ • JavaScript ASTΛ࡞ΔϥΠϒϥϦ͕৭ʑग़͖ͯͯޓੑ͕͋ͬͨ Γແ͔ͬͨΓͱ͍͏ঢ়گͩͬͨͷΛ2015ʹjQueryࡒஂ
Mozillaೖͬͯestree/estreeͱ͍͏JavaScript ASTͷඪ४ن͕֨ Ͱ͖Δ
JavaScriptք۾ͰͷASTͷաڈ ͜Μͳײ͡Ͱݱࡏ৭ʑͳϓϩμΫτͰΘΕ͍ͯΔJavaScript AST ϥΠϒϥϦ͕৭ʑͰ͖͖ͯ·ͨ͠ɻ ༗໊ॴΛϐοΫΞοϓ͚ͨͩ͠ͳΜͰɺѥྲྀͷύʔα৭ʑ͋Γ ྫ͑ESLintͳΜ͔ݱࡏesprimaͱޓੑ͕͋Δeslint/espreeͱ ͍͏ύʔαΛࣗલͰ࡞ͬͯͬͯͨΓ͠·͢ɻ
JavaScript ASTͷجૅࣝ
JavaScript AST࣮ࡍͲΜͳίʔυʹͳΔͷ͔ JavaScript ASTιʔείʔυΛߏʹมͯ͠ɺ࠷ऴతʹ JSONܗࣜʹͯ͠දݱ͍͖ͯ͠·͢ɻ ԼهͷΑ͏ͳ؆୯ͳJSίʔυΛྫʹऔΓ·͢ɻ var hello = 'Hello
World'; function sayHello() { console.log(hello) }
JavaScript AST࣮ࡍͲΜͳίʔυʹͳΔͷ͔ ࠓճacornΛͬͯASTʹม͢ΔͱԼهͷΑ͏ͳJSONܗ͕ࣜ Ͱ͖·͢ɻ { "type": "Program", "start": 0, "end":
69, "body": [ { "type": "VariableDeclaration", "start": 0, "end": 26, "declarations": [ { "type": "VariableDeclarator", "start": 4, "end": 25, "id": { "type": "Identifier", "start": 4, "end": 9, "name": "hello" }, "init": { "type": "Literal", "start": 12, "end": 25, "value": "Hello World", "raw": "'Hello World'" } } ], "kind": "var" }, { "type": "FunctionDeclaration", "start": 27, "end": 69, "id": { "type": "Identifier", "start": 36, "end": 44, "name": "sayHello" }, "generator": false, "expression": false, "params": [], "body": { "type": "BlockStatement", "start": 47, "end": 69, "body": [ { "type": "ExpressionStatement", "start": 49, "end": 67, "expression": { "type": "CallExpression", "start": 49, "end": 67, "callee": { "type": "MemberExpression", "start": 49, "end": 60, "object": { "type": "Identifier", "start": 49, "end": 56, "name": "console" }, "property": { "type": "Identifier", "start": 57, "end": 60, "name": "log" }, "computed": false }, "arguments": [ { "type": "Identifier", "start": 61, "end": 66, "name": "hello" } ] } } ] } } ], "sourceType": "module" }
JavaScript AST࣮ࡍͲΜͳίʔυʹͳΔͷ͔ શવಡΊͳ͍ͱࢥ͏ͷͰɺ͔Γ͍͢Α͏ͳπϦʔܗࣜͷεΫ γϣ͕ͪ͜Βɻ
JavaScript ASTͷมϧʔϧ ͲͷΑ͏ʹม͞ΕΔ͔?ͷϧʔϧ͏ύʔαͷυΩϡϝϯτ ɺParser API - Mozilla | MDNɺestree/estree: The
ESTree Specͳ Μ͔Λࢀߟʹ͠·͢ɻ͏ͪΐ͍ಥͬ͜ΜͩͰ͍͏ͱ ECMAScriptͷ༷ॻ߹ΘͤͯಡΉͱΑ͍͔͠Εͳ͍Ͱ͢ɻ • h#ps:/ /developer.mozilla.org/en-US/docs/Mozilla/Projects/ SpiderMonkey/Parser_API • h#ps:/ /github.com/estree/estree • h#ps:/ /www.ecma-internaEonal.org/ecma-262/8.0/index.html
ύʔαͰม͞Εͨͷͨͪͷઆ໌ ͞ΒͬͱࠓճͷͷΛୈೋ֊·Ͱઆ໌͢Δͱɺ͜Μͳײ͡Ͱ͢ • Program • ϧʔτʹͳΔΦϒδΣΫτ • Կͳ͘ͱઈରʹม͢Δͱ࡞ΒΕΔ • ϓϩάϥϜશ෦͜ͷ߲ͷbodyʹߏͰ֨ೲ͞ΕΔ
ύʔαͰม͞Εͨͷͨͪͷઆ໌ • VariableDeclaration • var hello = 'Hello World';ͷ෦ •
มએݴ͜ͷ߲ʹͳΔ • kind͕มએݴͷΩʔϫʔυͷछྨʹͳΔɻ • declarations͕એݴ͞Ε͍ͯΔ༰Λ֨ೲ͍ͯ͠Δ෦ • ม໊ॳظʹԿ͕ೖ͍ͬͯΔͳͲ͕֨ೲ
ύʔαͰม͞Εͨͷͨͪͷઆ໌ • FunctionDeclaration • function sayHello() { console.log(hello) }ͷ෦
• ؔએݴ͜ͷ߲ʹͳΔ • id໊͕ؔͳͲ֨ೲ͍ͯ͠Δ෦ • paramsࠓճۭ͕ͩɺԾҾΛ֨ೲ͍ͯ͠Δ෦
ݸੑ๛͔ͳύʔαͨͪ Ͳͷύʔαʔجຊͱͯ͜͠ΕΒͷ߲ESTreeͰఆٛ͞Εͯ ͍ΔͷΛ͍ͬͯΔͷͰ͕͢ɺࡉ͔͍ҧ͍͕͋ͬͨΓɺ bablylonͷΑ͏ʹಠࣗͰ৭ʑͳ߲ΛೖΕ͍ͯͨΓ͢Δͱ͍͏ײ ͡ʹͳ͍͖ͬͯ·͢ɻ h"ps:/ /github.com/babel/babylon/blob/master/ast/spec.md
JavaScript ASTͷ͍Ͳ͜Ζ ͜͜·ͰجຊతͳΛ͖ͯ͠·͕ͨ͠ɺͰJavaScript ASTΛࣗ ୡͰ͏߹…Ͳ͏͍͏ͱ͖Ͱ͠ΐ͏͔?ͺͬͱࢥ͍ͭ͘ͱ͜Ζ ͜Μͳײ͔͡ͳ͋ͱɻ - babelͷϓϥάΠϯ࡞ - eslintͷϓϥάΠϯ࡞
- ࣗલͰιʔείʔυΛมߋ͢Δ(APIมߋͳΜ͔ͷ)πʔϧ࡞Δͱ͖
JavaScript ASTͷ͍Ͳ͜Ζ ݸਓతʹڊਓͷݞʹ͔ͬΓ͍ͨͷͰɺ༻్͕ϓϥάΠϯ࡞ ʹͳͬͨΓͯ͠·͕͢ɺJavaScript ASTͷΈΛ͑ࣗલͷτ ϥϯεύΠϥΛ࡞ͬͨΓͰ͖ΔͣͰ͢ɻ ࣮ࡍʹJavaScript ASTΛͬͯJSΛੜ͢Δʹɺհͨ͠ύʔα ͷଞʹASTΛtraverseͯ͠ॲཧ͢ΔϥΠϒϥϦ(estraverseͳͲ) AST͔ΒJSΛੜ͢ΔϥΠϒϥϦ(escodegenͳͲ)͕ඞཁʹͳΓ·
͢ɻ
JavaScript ASTͬͯԿ͔ͯ͠ΈΔ
AST Explore ࠷ޙʹͪΐͬͱ࣮ͨ͠ྫΛ͝հͯ͠ऴΘΓ·͕͢ɺͦͷલʹ JavaScript ASTΛѻ͏ͷʹແͯ͘ͳΒͳ͍πʔϧ͕͋ΔͷͰ հɻ
AST Explore AST Explore: h.p:/ /astexplorer.net/
AST Explore ͜ͷαΠτJavaScript AST͚ͩͰͳ͘ଞͷ৭ʑͳݴޠͷύʔα ίʔυδΣωϨʔλ͕ΦϯϥΠϯͰ؆୯ʹͰ͖ΔΑ͏ʹͳͬͯ ͍ΔαΠτͰ͢ɻ JSBinJSFiddleͷAST൛ͱ͍͏ײ͡ɻSave͢ΔͱύʔϚϦϯΫ࡞ ͬͯ͘ΕͨΓASTͷπϦʔ͕ݟ͔ͬͨ͢Γ͢ΔπʔϧͰ͢ɻ ͍͍ͨύʔαδΣωϨʔλ৭ʑͳछྨ͔Βબ·͢ɻࠓճ ͷྫ͜ͷπʔϧͬͯհ͠·͢ɻ
var Ͱॻ͔ΕͨJSΛconstʹॻ͖͔͑Δ ύʔα: babylon v7 / τϥϯεύΠϥ: babel7 DEMO: varΩϥΠ
Vue.js 1.xܥ͔Β2.xܥͷϚΠάϨʔγϣϯʹ͑Δ ύʔα: acorn / τϥϯεύΠϥ: jscodeshi/ h"ps:/ /vuejs.org/v2/guide/migra4on.html#a"ached-removed DEMO:
a(atchͷϚΠάϨʔγϣϯ
ऴΘΓ
ࢀߟ • h#ps:/ /speakerdeck.com/michaelficarra/spidermonkey-parser- api-a-standard-for-structured-js-representa;ons • h#p:/ /azu.github.io/slide/JSojisan/#1 • h#ps:/
/efcl.info/2016/03/06/ast-first-step/ • h#ps:/ /efcl.info/2015/02/26/recent-js-ast/ • h#ps:/ /medium.com/@jotadeveloper/abstract-syntax-trees-on- javascript-534e33361fc7
ࢀߟ • h#ps:/ /www.sitepoint.com/understanding-asts-building-babel- plugin/ • h#ps:/ /github.com/jamiebuilds/babel-handbook • h#ps:/
/github.com/facebook/jscodeshi<