明日役に立たない個性派Babelプラグインの紹介


半年くらい下書きのまま放置されているので推敲なしで公開しちゃいます。

Babelプラグイン

6to5がBabelに名称変更して以来、Babelは「新しいJSのコードを古い環境でも動くようにするツール」から、「JSコードを別のJSコードに変換するツール」として生まれ変わりました。Babelはpresetやpluginを通した機能の拡張システムが非常に優秀で、これまでのエコシステムと比べると非常に簡単にJSコードを変換する処理を書くことができるようになりました。

babel-plugin-locals

localsというグローバルオブジェクトをローカル変数の一覧に変換してくれます。

In:

var x;
let y = 42;
function z() {}

locals;

Out:

var x;
let y = 42;
function z() {}

({
  x,
  y,
  z
});

babel-plugin-log-deprecated

JSDocでdeprecatedとされた関数を実行した時にWarningを出力するようにします。

In:

/**
 * @deprecated Deprecated in favour of fuga.
 */
const hoge = () => {
  fuga();
};

Out:

/**
 * @deprecated Deprecated in favour of fuga.
 */
const hoge = () => {
  console.warn("Deprecated: Function \"hoge\" is deprecated in /unknown on line 5", {
    functionName: "hoge",
    message: "Deprecated in favour of fuga.",
    packageName: "tonic-evaluator",
    packageVersion: "0.0.1",
    scriptColumn: 13,
    scriptLine: 5,
    scriptPath: "unknown"
  })

  fuga();
};

babel-plugin-tcomb

Flowによる静的型チェックのアノテーションを、tcombによる動的型チェックに変換してくれます。モジュール外部に公開する関数を安全にするのに便利。個人的に重宝してます。

In:

module.exports.sum = (a: number, b: number) => a + b;

Out:

import _t from "tcomb";

module.exports.sum = (a, b) => {
  _assert(a, _t.Number, "a");

  _assert(b, _t.Number, "b");

  return a + b;
};

function _assert(x, type, name) {
  if (false) {
    _t.fail = function (message) {
      console.warn(message);
    };
  }

  if (_t.isType(type) && type.meta.kind !== 'struct') {
    if (!type.is(x)) {
      type(x, [name + ': ' + _t.getTypeName(type)]);
    }
  } else if (!(x instanceof type)) {
    _t.fail('Invalid value ' + _t.stringify(x) + ' supplied to ' + name + ' (expected a ' + _t.getTypeName(type) + ')');
  }

  return x;
}

babel-plugin-implicit-return

Rubyライクな暗黙の戻り値を実現してくれます。やばい。

In:

const spaceship = (n) => {
  if (n > 0) {
    1;
  } else if (n < 0) {
    -1;
  } else {
    0;
  }
};

Out:

const spaceship = n => {
  if (n > 0) {
    return 1;
  } else if (n < 0) {
    return -1;
  } else {
    return 0;
  }
};

babel-plugin-unassert

プログラム中のassertをとにかく徹底的に消してくれる。

In:

const assert = require('assert');

const add = (a, b) => {
    console.assert(typeof a === 'number');
    assert(!isNaN(a));
    assert.equal(typeof b, 'number');
    assert.ok(!isNaN(b));
    return a + b;
}

Out:

const add = (a, b) => {
    return a + b;
};

babel-plugin-api-over-console

CLIで記述したコードをHTTPサーバーに変換するプラグイン。控えめに言って意味がわからないけど動く。なんだこれ。

詳細記事: https://qiita.com/akameco/items/36e803bc552573ca18c6

In:

console.log('hoge');

Out:

const express = require('express');

const cors = require('cors');

const app = express();
const port = process.env.PORT || 3000;
app.use(cors());
app.get('/', (req, res) => {
  res.json('hoge');
});
app.listen(port, () => {
  console.log('listening on %s', port);
});