Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

What is it? • An ES6 and beyond JavaScript compiler • A JSX optimising compiler • A transformation platform for JavaScript

Slide 3

Slide 3 text

Terminology • AST - A tree representation of source code. • Scope - A “boundary” that things can be bound to. • Traversal - The act of recursively visiting a root node and its children. • Traversal path - Representation of a child-parent relationship. • Transformer - Isolated transformation module with a specific goal. • Visitor - Controls a traversal.

Slide 4

Slide 4 text

Architecture

Slide 5

Slide 5 text

Architecture Parser Turns code into an AST Transformer Manipulates AST Generator Turns AST back into code

Slide 6

Slide 6 text

Parser

Slide 7

Slide 7 text

Parser • Recursive descent parser • Separate functions defined for all syntactic elements that are recursively called • Based on Acorn (https://github.com/marijnh/acorn)

Slide 8

Slide 8 text

Plugins • Modular • Each major syntax extension is separated into extensions • Supports: • ES6+ • Flow • JSX

Slide 9

Slide 9 text

AST var foo = function foo() { return bar; };

Slide 10

Slide 10 text

AST { type: "Program", body: [{ type: "VariableDeclaration" kind: "var", declarations: [{ type: "VariableDeclarator", id: { type: "Identifier", name: "foo" }, init: { type: “FunctionExpression", id: { type: “Identifier”, name: “foo” }, params: [], body: [{ type: "BlockStatement", body: [{ type: "ReturnStatement", argument: { type: "Identifier", name: "bar" } }] }] } }] }] }

Slide 11

Slide 11 text

AST Variable Declaration Program Variable Declarator Identifier Function Expression Block Statement Return Statement Identifier

Slide 12

Slide 12 text

ESTree • Collaborative AST spec from all the major consumers • Contextless definitions

Slide 13

Slide 13 text

Transformation

Slide 14

Slide 14 text

Visitors • Describes what nodes to visit. • Abstracts traversal logic from visiting logic. • Controls the traversal state - whether to stop or skip specific node trees. • Allows efficient reuse of common visitor logic.

Slide 15

Slide 15 text

Traversal • Handles visiting each node and branch in the tree. • Handles replacing nodes: • Expressions to statements etc. • Manages scope: • Tracks bindings and references.

Slide 16

Slide 16 text

Traversal paths • Node relationships are abstracted into paths. • Paths are retained between traversals. • Very powerful as path is constant, can store metadata. • A path always resolves to the same node. • Even after replacement and relocation.

Slide 17

Slide 17 text

Transformers • Each feature is split into a separate transformer. • Modular, easily toggle-able. • Good abstraction for grouping common logic. • Independent traversal for each transformer. • Easier to maintain state.

Slide 18

Slide 18 text

Demo

Slide 19

Slide 19 text

Future optimisations

Slide 20

Slide 20 text

Transformer traversal optimisation • Entire traversal for each transformer is inefficient. • Prepass the AST and check what branches each transformer actually needs. • Flexibility of having a stateful visitor without having to visit all nodes.

Slide 21

Slide 21 text

Transformer traversal optimisation function check(node) { return t.isProperty(node) && node.computed; }

Slide 22

Slide 22 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 23

Slide 23 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 24

Slide 24 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 25

Slide 25 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 26

Slide 26 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 27

Slide 27 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 28

Slide 28 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 29

Slide 29 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 30

Slide 30 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 31

Slide 31 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 32

Slide 32 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 33

Slide 33 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 34

Slide 34 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 35

Slide 35 text

Transformer traversal optimisation function createNode(type, props) { return { type: type, ["is" + type]: true, ...props }; }

Slide 36

Slide 36 text

AST diffing • Incremental builds • Store previous original and transformed AST as well as some metadata (scope tracking etc) • Diff previous original AST and current untransformed AST • Transpose differences into previous transformed AST and transform only the specific bits

Slide 37

Slide 37 text

Generation

Slide 38

Slide 38 text

Retaining original newlines • When printing a node • Get node starting token • Get previous token • Compare newlines between tokens • Add newlines

Slide 39

Slide 39 text

Generating generated node newlines • Is this a function declaration? If so, require a newline before and after. • Is it a directive? Require a newline after. • Is this an if statement with a block statement consequent? If so, insert a newline before and after.

Slide 40

Slide 40 text

JSX optimisations

Slide 41

Slide 41 text

Constant Value Types function render() { return
; } var foo =
; function render() { return foo; }

Slide 42

Slide 42 text

Constant Value Types 1. Check if JSX element is immutable. 2. Collect all references (Make sure references are “constant”. ie. never reassigned). 3. Walk up the scope tree, checking for the highest scope that contains all the references. 4. Create a declaration to save the JSX element and then insert it before the “scope block”.

Slide 43

Slide 43 text

Inline React Elements
{bar}
({ type: “div", props: { className: “foo", children: [ bar, { type: Baz, props: {}, key: "baz", ref: null } ] }, key: null, ref: null })

Slide 44

Slide 44 text

Tooling

Slide 45

Slide 45 text

Integrations • Atom • Broccoli • Browserify • Browser compiler • Brunch • Cogs • Connect • CLI • Ember CLI • ESLint • Duo • Gobble • Grunt • Gulp • Istanbul • Jade • Jest • Karma • Kraken devtools • Mimosa • Mocha • Nodemon • Meteor • Power assert • Rails/Sprockets • Require hook • Ruby • Sails • Sublime • Webpack

Slide 46

Slide 46 text

Conclusion • Write a plugin: https://babeljs.io/docs/usage/ plugins • Contribute! https://github.com/babel/babel/blob/ master/CONTRIBUTING.md • Questions?