LoginSignup
6
4

More than 5 years have passed since last update.

babel-register を通して手動実行スクリプトの手軽さと flowtype の恩恵を両立させる

Last updated at Posted at 2018-08-18

これまで require をフックしてしまう babel-register はなんとなく邪道ではと思って使っていなかったのですが、最近はよく flowtype を利用するようになり、いっぽうプロジェクト内の小さなツールを node で書くことが増えたこともあって、突然 register しましょうかという気持ちになりました。

いちいち型定義情報削除するために babel 通すのは面倒だし、コメント記法や別ファイル定義も flowtype の手軽さをスポイルしてしまうと感じていて、それであれば都度ビルド走ってもいいかなという。ただ、 node -r babel-register のようにコマンドラインに現れるのをやめたかったので、require("babel-register") で進めることにしました。

コードは以下で確認しています。

  • node v10
  • babel 7
  • flow 0.79

※ babel 7 がリリースされました。

構成

インストールする。

$ npm init -y
$ npm install -D @babel/core @babel/register @babel/preset-flow \
                 @babel/preset-env flow-bin
$ npx flow init

手動実行するエントリポイントを bin/ 以下に配置し、 実際のスクリプトの機能実装本体は src/ 以下に置くとして、

$ tree . -I node_modules
.
├── bin
│   └── app.js
├── package-lock.json
├── package.json
└── src
    └── scripts
        └── app
            └── index.js

4 directories, 4 files

実装

エントリポイントとなるファイルは node 準拠で書く。require("@babel/register") 以降の require で babel での動的なコンパイルが行われます。ここでは、 ../src/scripts/app.js が babel で処理されます。

bin/app.js
// @flow
require("@babel/register");
const { app } = require("../src/scripts/app")

app()

src 以下のファイルは babel を通す前提で型定義もそのまま書いてしまう。普通のJSとしてはエラーになりますが、 @babel/preset-flow を通すことで型定義が無視されて素直に実行できるようになる寸法。

src/scripts/app/index.js
// @flow
type LogicResult = {
  code: string
}

function logic(): LogicResult{
  return {
    code: "Success"
  }
}

export function app(){
  console.log(logic())
}

.babelrc には preset-env と preset-flow だけとりあえず設定している。

.babelrc
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-flow"
  ]
}

.flowconfig は生成されたときのまま。

.flowconfig
[ignore]

[include]

[libs]

[lints]

[options]

[strict]

これでいつでも node bin/app.js できますし、flowtype の型チェックの恩恵も受けられます。

なお、flowによるチェックはコンパイル時に自動で走るわけではないので npx flow check 手動で叩く必要があります。このあたりは typescript の方が確実にチェックされるという意味では確実かなという気も。

なお、requireをフックしてビルドしている関係上遅いです。上記くらいの小さなコードでも

$ time node bin/app.js
{ code: 'Success' }

real    0m0.329s
user    0m0.295s
sys 0m0.051s

user 0.3秒くらいかかります。あくまでも「シェルスクリプトよりちょっとボータブルな自動化スクリプトを、静的型付けで書きたい or 業務ロジックとモデル共通化したい」みたいなケースで使える構成上の小技として考えたほうがよさそう。

本番系で使うバッチとか、npmモジュールの実行エントリポイントとして書くならちゃんとビルドしたものを使いましょうということで一つ。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4