Babelでカスタムpresetを作る


TL; DR;

babel preset/pluginインストール&設定('A`)マンドクセって人は自分用のpreset作ると幸せになれるよ

はじめに

フロントエンドのプロジェクトを量産していると、毎回初回の環境構築が面倒になってきます。
特にbabelのpresetとかplugin周り。いちいちインストールして.babelrc書いてっていう作業が毎回面倒です。
ボイラープレート作っても良かったんですが、まずは作業楽にする1st Stepとしてbabelのsetupを楽にする方法について調査しました。(※ 公式を見ると超簡単そうだったので..

もともとの構成

package.json
  "devDependencies": {
    "babel-plugin-root-import": "^5.1.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-preset-env": "^1.6.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
  }
.babelrc
{
  "env": {
    "development": {
      "presets": [["env", {"targets": {"browsers": ["last 2 versions"]}, "modules": false}], "react", "stage-0"],
      "plugins": [
        "transform-decorators-legacy",
        [ "babel-plugin-root-import", [{
          "rootPathPrefix": "~",
          "rootPathSuffix": "src/js/"
        }]],
        "import-glob",
      ]
    },
    "test": {
      "presets": [["env", {"targets": {"browsers": ["last 2 versions"]}, "modules": "commonjs"}], "react", "stage-0"],
      "plugins": [
        "transform-decorators-legacy",
        [ "babel-plugin-root-import", [{
          "rootPathPrefix": "~",
          "rootPathSuffix": "src/js/"
        }]],
        "import-glob",
      ]
    }
  }
}

たったこれだけなんですが、毎回面倒なのでpreset作ります。

作ってみる

公式ではmodule.exports書くだけで良さそうだったのですが、いろいろ見てみたらAirbnbのpresetの構成が良さげだったので丸パクリ参考にしました。

準備

mkdir babel-preset-xxxx && cd $_
npm init -y

# 使用するpreset, pluginのインストール
npm i -S babel-preset-env
npm i -S babel-preset-react
npm i -S babel-preset-stage-0
npm i -S babel-plugin-transform-decorators-legacy
npm i -S babel-plugin-root-import
npm i -S babel-plugin-import-glob

実装

実装はこんな感じ。

index.js
'use strict';

module.exports = function buildXXXXPreset(context, options) {
  var modules = (options && (typeof options.modules === 'boolean' || typeof options.modules === 'string')) ? options.modules : false;
  return {
    presets: [
      [require('babel-preset-env').default, {
        targets: { browsers: ['last 2 versions'] },
        modules: modules
      }],
      require.resolve('babel-preset-react'),
      require.resolve('babel-preset-stage-0')
    ],
    plugins: [
      require.resolve('babel-plugin-transform-decorators-legacy'),
      [require('babel-plugin-root-import').default, [{
        rootPathPrefix: '~',
        rootPathSuffix: 'src/js/'
      }]],
      require.resolve('babel-plugin-import-glob')
    ]
  };
};

modulesオプションを受け取ってbabel-preset-envにわたすようにしています。

ちょっとハマった点として、公式とかAirbnbの実装を見ると

require('babel-plugin-hogehoge')

の形で書いてたんですが、↑の実装を見てもらっても分かる通り

// optionあり
[require('babel-plugin-hogehoge').default, { options }]

// optionなし
require.resolve('babel-plugin-hogehoge')

の形にしないと動きませんでした。

publish

あとはgitにpushして、 npm publishで終わりです。この辺の手順は今回関係ないので割愛。

使ってみる

作成したpresetの使い方は、他のpresetと同じく、

npm i -D babel-preset-xxxx

して、.babelrc

.babelrc
"presets": ["xxxx"]

と書けばOKです。超楽ですね。