LoginSignup
11
9

More than 5 years have passed since last update.

flowの型情報をnpmパッケージで一緒に配布する

Last updated at Posted at 2017-07-01

TL;DR;

  • flow 0.19.0 から .js.flow 拡張子がついたファイルがあればそれを見るようになった
  • npm パッケージでは型情報を消した .js ファイルと、型情報を持った .js.flow ファイルを一緒に配布する
    • 将来的に flow に特大の後方非互換な変更が入らない限り動くはず

npmパッケージも型情報を使いたい

開発時に型情報を書いても、いざ配布するときにはそれを取り外してから配布する。取り外さないと、 flow を使っていないプロジェクトで require することが困難になってしまうためだ。

しかし、そのパッケージを使うときには flow を使いたい。flowtype/flow-typed に自分のライブラリの情報を載せるのが一つの手だが、開発段階で実装が流動的だと更新が面倒なのに加えて、そもそも DRY ではない。

せっかく開発時に書いた型情報を、 npm パッケージとして require したときに使うことはできないのだろうか。

Declaration files

なぜか flow.org の標準ドキュメントで言及されていないのだが、 0.19.0 で追加された declaration files という機能を使うと簡単に実現できる。

Declaration files とは、簡単な話が foo.jsfoo.js.flow というファイルがあり、 import Foo from './foo' を実行したら flow は foo.js.flow を見に行く、というものだ。

つまり型情報を取り除いた .js ファイルとは別に、型情報が残ったままのファイルを .js.flow という名前でパッケージに入れればいい。

npm パッケージに書き込まれているということは、パッケージを使っているプロジェクトで利用している flow のバージョンによってはエラーが発生する可能性があるということだ。特に将来的に flow 本体に後方非互換な変更が入った場合、それによってパッケージを使っている側の型チェックが通らなくなってしまう。この場合は .flowconfig でそのパッケージを ignore するように設定してしのぐことになると思われる。

例: yuku-t/textcomplete

textcomplete は src ディレクトリの下に @flow プラグマが指定された .js ファイルが入っている。これを npm run build:lib でビルドすると lib ディレクトリの下に babel でトランスパイルされた .js ファイルと1、 src ディレクトリにもともとあったそのままの .js.flow ファイルが生成される。

package.json(抜粋)
{
  "script": {
    "build:lib": "babel src -d lib -s && for js in src/*.js; do cp $js lib/${js##*/}.flow; done"
  }
}

この結果 textcomplete を require すると flow は型情報にアクセスすることができるようになっている。

参考

  • Version 0.19.0 - 0.19.0 のリリースブログ。 Declaration files について説明がある。

  1. babel は babel-preset-flow を使うように設定されている。 

11
9
1

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
11
9