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

Hiking Through the JavaScript Forest

Hiking Through the JavaScript Forest

A talk about Abstract Syntax Trees (ASTs) in JavaScript and how to use them to create codemods and eslint rules

Jamund Ferguson

January 27, 2016
Tweet

More Decks by Jamund Ferguson

Other Decks in Technology

Transcript

  1. Syntax Highlighting Code Completion Static Analysis Code Coverage • Minification

    • JIT Compilation in the Browser • Source Maps • Transpilers (CoffeeScript, Babel) Interesting Things
  2. { "type": "Program", "body": [{ "type": “VariableDeclaration", "kind": "var" "declarations":

    [{ "type": "VariableDeclarator", "id": { "type": “Identifier", "name": "seattle" }, "init": { "type": "BinaryExpression", "left": { "type": “Identifier", "name": “rain" }, "operator": "+", "right": { "type": “Identifier", "name": “trees" } } }] }] }
  3. { "type": "Program", "body": [{ "type": “VariableDeclaration", "kind": "var" "declarations":

    [{ "type": "VariableDeclarator", "id": { "type": “Identifier", "name": "seattle" }, "init": { "type": "BinaryExpression", "left": { "type": “Identifier", "name": “rain" }, "operator": "+", "right": { "type": “Identifier", "name": “trees" } } }] }] }
  4. { "type": "Program", "body": [{ "type": “VariableDeclaration", "kind": "var" "declarations":

    [{ "type": "VariableDeclarator", "id": { "type": “Identifier", "name": "seattle" }, "init": { "type": "BinaryExpression", "left": { "type": “Identifier", "name": “rain" }, "operator": "+", "right": { "type": “Identifier", "name": “trees" } } }] }] }
  5. Tree Wrangling 1. Use ESLint to perform static analysis 2.

    Use jscodeshift for one-time code migration (codemods) 3. Use Babel for build-time transformation
  6. Types of AST Tools Most use something called the visitor

    pattern Some tools prefer a “jQuery-like” API
  7. Visitor Pattern You’re climbing the tree, but you stop and

    visit certain parts that seem really nice.
  8. { "type": "Program", "body": [{ "type": “VariableDeclaration", "kind": "var" "declarations":

    [{ "type": "VariableDeclarator", "id": { "type": “Identifier", "name": "seattle" }, "init": { "type": "BinaryExpression", "left": { "type": “Identifier", "name": “rain" }, "operator": "+", "right": { "type": “Identifier", "name": “trees" } } }] }] }
  9. Fix a bug. Write an ESLint Rule. Prevent that entire

    class of bugs from entering your codebase ever again.
  10. ESLint Rules! module.exports = function(context) { return {
 “VariableDeclaration”: function(node)

    {
 if (node.kind === “var”) {
 context.report(node, “You’re var-y bad!”);
 }
 }
 }}
  11. Tools like jscodeshift and babel give you an API to

    manipulate an AST and then convert that back into source code.
  12. Babel Plugins module.exports = function(babel) {
 return {
 visitor: {


    “VariableDeclaration”: function(path){
 if (path.node.kind === “const”) {
 path.node.kind = “var”;
 }
 }
 }
 }}
  13. export default function(file, api) { const j = api.jscodeshift; return

    j(file.source) .find(j.VariableDeclaration) .replaceWith( p => j.variableDeclaration(“const”, p.value.declarations) ) .toSource(); }; JSCodeshift Transform