Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Babel - Facebook April 2015

sebmck
April 17, 2015
2.5k

Babel - Facebook April 2015

sebmck

April 17, 2015
Tweet

Transcript

  1. What is it? • An ES6 and beyond JavaScript compiler

    • A JSX optimising compiler • A transformation platform for JavaScript
  2. 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.
  3. Parser • Recursive descent parser • Separate functions defined for

    all syntactic elements that are recursively called • Based on Acorn (https://github.com/marijnh/acorn)
  4. Plugins • Modular • Each major syntax extension is separated

    into extensions • Supports: • ES6+ • Flow • JSX
  5. 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" } }] }] } }] }] }
  6. 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.
  7. Traversal • Handles visiting each node and branch in the

    tree. • Handles replacing nodes: • Expressions to statements etc. • Manages scope: • Tracks bindings and references.
  8. 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.
  9. 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.
  10. 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.
  11. 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
  12. Retaining original newlines • When printing a node • Get

    node starting token • Get previous token • Compare newlines between tokens • Add newlines
  13. 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.
  14. Constant Value Types function render() { return <div className="foo" />;

    } var foo = <div className="foo" />; function render() { return foo; }
  15. 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”.
  16. Inline React Elements <div className="foo">{bar}<Baz key="baz" /></div> ({ type: “div",

    props: { className: “foo", children: [ bar, { type: Baz, props: {}, key: "baz", ref: null } ] }, key: null, ref: null })
  17. 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