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

Writing Babel Plugin

Writing Babel Plugin

YWC Programmer Meetup #7

59820ab78fcd471047491c8265a01daf?s=128

Manatsawin Hanmongkolchai

February 01, 2020
Tweet

Transcript

  1. Writing Babel Plugin YWC Programmer Meetup

  2. Why Babel?

  3. Write code that you hate to write a.k.a Syntactic Sugar

  4. Some use of Babel #connect people to good stuff •

    ES6 const A = () => {} → var A = function A() {} • JSX <div> → React.createElement("div", null); • Individually import Lodash functions import { add } from 'lodash/fp' → import _add from 'lodash/fp/add' • Generate data-qa tags for automated test selection <div> → <div data-qa="Component">
  5. Let’s write a plugin!

  6. Parsing How your computer understand your code

  7. JSON #connect people to good stuff let data = JSON.parse('{"hello":

    "world"}') data.hello
  8. XML #connect people to good stuff let data = new

    DOMParser() .parseFromString("<string>hello</string>", "application/xml"); data.documentElement.textContent
  9. Source code?? #connect people to good stuff import { parse

    } from '@babel/parser' parse('console.log("hello")') ???
  10. Abstract Syntax Tree (AST) #connect people to good stuff •

    Code is represented by AST • astexplorer.net • ⚠ Make sure you set parser to babel-eslint
  11. console.log("hello world") type: Program body: - type: ExpressionStatement expression: type:

    CallExpression callee: type: MemberExpression object: type: Identifier name: console property: type: Identifier name: log arguments: - type: Literal value: hello world * Some fields are omitted #connect people to good stuff
  12. console.log("hello world") type: Program body: - type: ExpressionStatement expression: type:

    CallExpression callee: type: MemberExpression object: type: Identifier name: console property: type: Identifier name: log arguments: - type: Literal value: hello world #connect people to good stuff
  13. console.log("hello world") type: Program body: - type: ExpressionStatement expression: type:

    CallExpression callee: type: MemberExpression object: type: Identifier name: console property: type: Identifier name: log arguments: - type: Literal value: hello world #connect people to good stuff
  14. console.log("hello world") type: Program body: - type: ExpressionStatement expression: type:

    CallExpression callee: type: MemberExpression object: type: Identifier name: console property: type: Identifier name: log arguments: - type: Literal value: hello world #connect people to good stuff
  15. console.log("hello world") type: Program body: - type: ExpressionStatement expression: type:

    CallExpression callee: type: MemberExpression object: type: Identifier name: console property: type: Identifier name: log arguments: - type: Literal value: hello world #connect people to good stuff
  16. console.log("hello world") type: Program body: - type: ExpressionStatement expression: type:

    CallExpression callee: type: MemberExpression object: type: Identifier name: console property: type: Identifier name: log arguments: - type: Literal value: hello world #connect people to good stuff
  17. Transform

  18. Babel Plugin #connect people to good stuff • Babel plugin

    is just a JavaScript file with default export export default function({ types: t }) { return { visitor: { // visitor contents } }; };
  19. Babel Plugin #connect people to good stuff • Provide visitor

    functions for interested node type export default function({ types: t }) { return { visitor: { Identifier(path, state) {}, } }; };
  20. Goal #connect people to good stuff $("id") → document.getElementById("id")

  21. Know the AST #connect people to good stuff type: Program

    body: - type: ExpressionStatement expression: type: CallExpression callee: type: Identifier name: $ arguments: - type: Literal value: id
  22. Babel Plugin #connect people to good stuff Match CallExpression export

    default function({ types: t }) { return { visitor: { CallExpression(path, state) { // ... }, } }; }; type: Program body: - type: ExpressionStatement expression: type: CallExpression callee: type: Identifier name: $ arguments: - type: Literal value: id
  23. Babel Plugin #connect people to good stuff Use t (@babel/types)

    to build nodes export default function({ types: t }) { return { visitor: { CallExpression(path, state) { // ... }, } }; }; type: Program body: - type: ExpressionStatement expression: type: CallExpression callee: type: Identifier name: $ arguments: - type: Literal value: id
  24. Babel Plugin #connect people to good stuff Match callee that

    it is $ identifier CallExpression(path, state) { if ( t.isIdentifier( path.node.callee, { name: '$' } ) ){ // ... } }, type: Program body: - type: ExpressionStatement expression: type: CallExpression callee: type: Identifier name: $ arguments: - type: Literal value: id
  25. type: Program body: - type: ExpressionStatement expression: type: CallExpression callee:

    type: MemberExpression object: type: Identifier name: document property: type: Identifier name: getElementById arguments: - type: Literal value: id Babel Plugin #connect people to good stuff Replace with document.getElementById CallExpression(path, state) { if (t.isIdentifier(path.node.callee, {name: '$'})){ path.node.callee = t.memberExpression( t.identifier('document'), t.identifier('getElementById') ) } },
  26. Running #connect people to good stuff • Put the plugin

    file in babel.config.js • Be careful of Babel cache in node_modules/.cache
  27. Uses of Babel plugins at Wongnai

  28. Babel uses at Wongnai #connect people to good stuff •

    Lodash per-function import babel-plugin-lodash • Generate data-qa tags for automated test selection babel-plugin-transform-react-qa-classes • Compile time locale split/inlining Read more on life.wongnai.com
  29. Thank You Grab this deck at https://speakerdeck.com/whs