Scala.js用の型定義をラクに得る scala-js-ts-importer の紹介
最近、仕事で使っている&趣味で貢献している scala-js-ts-importer というOSSの紹介をする。この記事は Qiitaで開催されているScala Advent Calendar 2017の6日目 でもある。
バックエンドを Scala でなく Scala.js にしたのは、Scala言語の良さを活かしつつ、
Scala.jsでは、以下のようなメジャーなフロントエンド用JSライブラリには型定義が公開されている。
Scala.js(およびScala)に備わっているDynamic型は、インスタンスのメンバー呼び出しの型検査が行われない型である。呼び出そうとしたメンバーが実際に存在すれば実行できるが、存在しなければ実行時エラーになる。このDynamic型を利用することで、まだ型定義のついていないJSライブラリを、危険ではあるがScala.jsから呼び出すことができる。
とはいえ、本格的に開発するときは、JSライブラリに型定義が欲しくなってくる。
しかし、JSライブラリにありがちな、奇怪なオーバーロードだらけの便利関数の挙動を調べあげ、しっかりした型定義を書くのは大変だ。ではどうするか?
TypeScriptは、Scala.jsと同じく静的型付けのaltJSだ。Microsoftが開発しており、頻繁にアップデートされている。活発なコミュニティが型定義ファイルレポジトリ DefinitelyTyped をメンテナンスしており、型定義ファイルが充実している。また近年では、JSライブラリのGithubレポジトリに、TS用の型定義ファイルが同梱されることも増えてきた。
scala-js-ts-importer を使うことで、こうしたTypeScript用の型定義資産から、Scala.js用の型定義を比較的ラクに生成できる。
ScalaとTypeScriptの型システムが完全には対応していないことから、変換は完全ではない。ただ、小一時間の手修正をすれば、実用上十分な型定義を得られる。Scala.jsを本格的に使うのであれば、scala-js-ts-importerは知っておくとよいツールだ。
そこで、チームメンバーらに気軽に試してもらえるようにscala-js-ts-importerのWebアプリを作った。TypeScript用の型定義ファイルを貼り付けるだけで試すことができる。
このアプリ自体、Scala.jsで書かれている。Scalaで実装されたパーサーコンビネータライブラリを使った、Scala.jsで書かれたパーサーが、Webブラウザで動いているのだ。なかなか愉快な時代である。
細かい工夫としては、巨大な型定義ファイルのパースと変換には数秒待たされることもあるので、ServiceWorkerに処理をオフロードしたりもしている(かなり雑だが)。Workerを勉強できてよかった。
scala-js-ts-importerを頻繁に使い出したら足りない機能が分かってきた。2017年のHacktoberfestのタイミングでプルリクを4つ出したらマージされた。
ニッチなテーマなので、参加者ゼロで筆者1人もくもくすることを想定していたが、TwitterやNGK2017Bというイベントで雑に告知したら、予想外に4人も集まった。
来栖川電算は、近年はビッグデータ処理や機械学習の分野で、さまざまな企業・団体から引き合いがある。そのため、求人面では機械学習をやりたい方からの応募が多くなっているが、実は
Scala.jsを仕事で使い始めた
今年に入って仕事で開発・運用している SaaS は、フロントエンドもバックエンドも Scala.jsで開発している。バックエンドを Scala でなく Scala.js にしたのは、Scala言語の良さを活かしつつ、
- Lambda のランタイムとして省メモリで立ち上げが速い nodejs を使い、コンピューティング料金を節約したかった
- デプロイする ZIP の50MB制限を回避したかった
静的型付けaltJSの良さ
Scala.jsを初めとした静的型付け系 altJS では、静的な型情報があることで次のような恩恵が得られる。- 関数に何を渡せばいいかが型で分かったりする。
- オブジェクトが持っているメンバーを入力補完できる。
- メソッドのシグネチャを変えたときに修正を必要とする箇所がすぐ分かる。
JSライブラリに型をつける
Scala.jsやTypescriptなどの静的片付け系 altJS では、JSライブラリに外部から型定義を与える仕組みがある。これにより、JSライブラリを静的に型検査できるようになる。Scala.jsでは、以下のようなメジャーなフロントエンド用JSライブラリには型定義が公開されている。
- UIフレームワーク:jQuery, Bootstrap, React, Angular, Vue
- 視覚化: d3.js, Three.js, highchart.js
- 補助ライブラリ: moment.js, RxJS
- 変わり種: WebRTC
型定義を書くコストをどうするか
型定義を書くのは手間だ。プロトタイピング時などは型安全を割り切って、静的型検査なしでJSを呼び出すのも一つの手だ。Scala.js(およびScala)に備わっているDynamic型は、インスタンスのメンバー呼び出しの型検査が行われない型である。呼び出そうとしたメンバーが実際に存在すれば実行できるが、存在しなければ実行時エラーになる。このDynamic型を利用することで、まだ型定義のついていないJSライブラリを、危険ではあるがScala.jsから呼び出すことができる。
とはいえ、本格的に開発するときは、JSライブラリに型定義が欲しくなってくる。
しかし、JSライブラリにありがちな、奇怪なオーバーロードだらけの便利関数の挙動を調べあげ、しっかりした型定義を書くのは大変だ。ではどうするか?
TypeScriptという巨人の肩に乗る
Scala.jsの開発者である Sebastien Doeraeneさんが、を開発し、公開されている。
TypeScriptは、Scala.jsと同じく静的型付けのaltJSだ。Microsoftが開発しており、頻繁にアップデートされている。活発なコミュニティが型定義ファイルレポジトリ DefinitelyTyped をメンテナンスしており、型定義ファイルが充実している。また近年では、JSライブラリのGithubレポジトリに、TS用の型定義ファイルが同梱されることも増えてきた。scala-js-ts-importer を使うことで、こうしたTypeScript用の型定義資産から、Scala.js用の型定義を比較的ラクに生成できる。
ScalaとTypeScriptの型システムが完全には対応していないことから、変換は完全ではない。ただ、小一時間の手修正をすれば、実用上十分な型定義を得られる。Scala.jsを本格的に使うのであれば、scala-js-ts-importerは知っておくとよいツールだ。
scala-js-ts-importerをWebブラウザで試す
scala-js-ts-importerを使うのは、cloneして、sbtビルドして……と、一手間が必要だ。そこで、チームメンバーらに気軽に試してもらえるようにscala-js-ts-importerのWebアプリを作った。TypeScript用の型定義ファイルを貼り付けるだけで試すことができる。
このアプリ自体、Scala.jsで書かれている。Scalaで実装されたパーサーコンビネータライブラリを使った、Scala.jsで書かれたパーサーが、Webブラウザで動いているのだ。なかなか愉快な時代である。
細かい工夫としては、巨大な型定義ファイルのパースと変換には数秒待たされることもあるので、ServiceWorkerに処理をオフロードしたりもしている(かなり雑だが)。Workerを勉強できてよかった。
scala-js-ts-importerに足りない機能を追加しまくった
scala-js-ts-importerを頻繁に使い出したら足りない機能が分かってきた。2017年のHacktoberfestのタイミングでプルリクを4つ出したらマージされた。- Add support for the intersection type `A & B`
- Add support for the polymorphic this type
- Add support for "export let" and "export const" for modules
scala-js-ts-importerハッカソンを開催した
雰囲気でパーサーコンビネーター使ってたらどうしようもなくなってきたので、助けを求めてハッカソンをやることにした。ニッチなテーマなので、参加者ゼロで筆者1人もくもくすることを想定していたが、TwitterやNGK2017Bというイベントで雑に告知したら、予想外に4人も集まった。
- Scala.jsとTypeScriptに強い人
- Scalaとパーサーに強い人 A
- Scalaとパーサーに強い人 B
- 筆者
スポンサーのご紹介
scala-js-ts-importerハッカソンでは、筆者の所属である来栖川電算に、- 会場
- WiFi
- ドリンク
- 寿司
- マッサージチェア
来栖川電算は、近年はビッグデータ処理や機械学習の分野で、さまざまな企業・団体から引き合いがある。そのため、求人面では機械学習をやりたい方からの応募が多くなっているが、実は
- 機械学習の研究者を助けるツール
- 機械学習をお客様のビジネス(研究だけでなく実運用)で活かすSI
- 機械学習を活かした自社製品開発
- 機械学習エンジニアはもちろん、
- フロントエンドやバックエンドに強いエンジニア
- UI/UXに強いデザイナー、エンジニア
まとめ
- scala-js-ts-importerを使うと、TypeScriptの型定義資産をScala.js用に変換できる
- scala-js-ts-importerを試せるWebアプリを作ったので、お試しあれ
- 自分が使うOSSにプルリクエスト送るハッカソン、なかなかよい


