こんにちは! @kumabook です。
僕は学生時代からJavaScriptを使い始めていて、
色々ダメなところもあるけどなんだかんだ言ってみんながいつも使っているブラウザというプラットフォームの上で動いているJavaScriptという言語が好きです。
最近はes6やtypescriptと言われていますが、便利になったなーと思う反面、
es3は覚えることは少なくてよかったなーと思うこともあります。その分、ワナも多かったわけですが。
で、es6 といえばbabel流行ってますよね。
ASTいじるツールがここ2年・3年乱立していた感ありましたが、babel 6でbabelに集約されていくのかなと思っています。
僕も前にesprimaとかを使ってASTをいじって遊んだことがありましたが、
これからはbabel-pluginだろうということで、簡単なpluginを作って入門してみたいと思います。
babel-plugin入門に当たってですが、plugin-handbook をめちゃくちゃ丁寧にまとまってました。
あと、シンプルで実際に動くpluginは ここ
に結構あったので参考になりました。
で、今回は、行番号つきでデバック出力してくる__DP__() という関数(マクロみたいなもの?)を作ってみました。chrome developer toolとかはconsole.logに行番号出してくれますが、レガシーな環境ではそうも行かないことがあるので、前から欲しいと思っていたものです。
"use strict";
module.exports = function({ types: t }) {
  return {
    name: "transform-debug-print-function",
    visitor: {
      CallExpression(path) {
        var line = path.parent.loc.start.line;
        if (isDebugPrintFunction(path.node)) {
          path.replaceWithSourceString(`console.log('[DP]: line ' + ${line})`);
        }
      },
    },
  };
  function isDebugPrintFunction(node) {
    return t.isCallExpression(node) &&
           t.isIdentifier(node.callee, { name: "__DP__" });
  }
};
__DP__を 行数付きのconsole.logにreplaceするという大変雑な作りですが、
var name = "babel plugin";
console.log("hello " + name);
__DP__();
これが
"use strict";
var name = "babel plugin";
console.log("hello " + name);
console.log('[DP]: line ' + 4);
こうなるようにできました。
簡単なbabel-pluginですが、実際に手を動かして作ってみると
完全にブラックボックスだったbabelも少しだけ理解できた気がします。
明日は @aTomoyaKubo です!