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

Writing Babel Plugin

Writing Babel Plugin

YWC Programmer Meetup #7

Manatsawin Hanmongkolchai

February 01, 2020
Tweet

More Decks by Manatsawin Hanmongkolchai

Other Decks in Programming

Transcript

  1. 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">
  2. XML #connect people to good stuff let data = new

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

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

    Code is represented by AST • astexplorer.net • ⚠ Make sure you set parser to babel-eslint
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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 } }; };
  12. Babel Plugin #connect people to good stuff • Provide visitor

    functions for interested node type export default function({ types: t }) { return { visitor: { Identifier(path, state) {}, } }; };
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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') ) } },
  18. Running #connect people to good stuff • Put the plugin

    file in babel.config.js • Be careful of Babel cache in node_modules/.cache
  19. 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