TeaVMのsbt pluginを作った 〜 酢豚とお茶の出合い 〜 ScalaからWebAssemblyへの変換

Twitterでは多少Tweetしてたのですが、やっとある程度形になったので、リリースしました。 以下、簡単な説明や、関連する余談など書いておきます

https://github.com/sbt-teavm/sbt-teavm

TeaVMとは

  • 原理上、Java含めた任意のJVMのbytecodeからWebAssembly, JavaScriptなどに変換してくれるもの
  • ASMで変換する系なので、Javaに限らず、ScalaでもKotlinでも(原理上は)いける
    • 実際公式にもScalaのサンプルがある
    • つまり依存ライブラリがscala-jsやscala-nativeのように専用にpublishされていなくてもbuild可能(build出来ても実際にどの程度動くか?は別問題)
  • ただし、scala-jsやscala-nativeと同様に、Javaの標準のAPIで再実装されていないものは動かない制約はある
  • 若干興味を持って、多少試してみたくなったが、mavenやgradleのpluginは公式にあるが、sbt pluginがなさそうなので作った
  • 詳細は公式サイト見てね
  • https://github.com/konsoletyper/teavm
  • https://teavm.org

pluginの基本的な使い方や現状の制約

  • 最低限の使い方はREADMEに書いたから読んでくれ
    • addSbtPluginしてenablePluginsすれば、buildはすぐできるはず
  • example repo https://github.com/sbt-teavm/sbt-teavm-example/commit/a2495ec16d4b5b2da86d1cb70f19f7e2448a08d0
  • Scalaのversionによって、動きやすさ?が変わるので注意(おそらく2.13が一番動くが詳細未検証)
  • 新しい方式でしかpublishしてないので、おそらく古いsbtでは依存の記述を若干工夫しないと動かない
  • TeaVM自体がJDK 11でbuildされてるので、それ未満では動かないぞ
  • 現状は、公式と同様の4種類のoutputでのbuildと、3種類runができる
    • C言語の知識がなくてrunさせるの一旦諦めた
  • runとrunMainを、(Node.jsなどがinstall済みなら)コマンドで一発で全部動くようにした。標準出力もいい感じにカスタマイズ可能にしつつ、デフォルトは直接consoleに表示されるようにした。引数の指定などはsbt標準のものと同じ
    • scripted test書きたい都合でもそうしたかった
    • これのために、裏でpuppeteer経由でChrome動かしたり、unfilteredでserver自動で動かしたり、色々頑張るのが地味に大変だった
  • 公式はjunitでのtestサポートしてるが、これ書いた時点のsbt-teavm pluginでは、まだサポートしてない
    • やる気が続いたら、このあと頑張る、かも
    • その点においてはあくまで公式のgradleやmaven pluginの方がまだ現状では優れているので、あくまでsbtで気軽に試したい向けのものである
  • かなり色々オプションは選択可能にしたけど、細かく書いてられないというか、大半は公式のツールと同じなので、コードや、公式のドキュメント読んでくれ
    • 細かいオプション多いので、sbt-assemlbyの真似してcontrabandでコード生成した
  • Compile /のConfig前提で作ってるので、まだ Test/runTest/runMainTest/compile 相当すら動かない
    • 気が向いたら対応する、かも

色々作ったり試した感想

  • taskのkeyにscope付けて既存の標準のkey再利用するべきかどうするか?など、sbt plugin作るたびに毎回迷う、難しい
  • あと、1つのprojectで複数のtarget build可能にするのか、scala-jsやscala-nativeみたいに1 project 1つ固定の方が良かったのか???なども
  • 確かにJavaScalaからWebAssemblyになるのはすごいが、実装されてないJava標準classがかなり多いので、10倍以上(?)scala-jsとかscala-nativeの方が、動かないパターンに遭遇しないというか、完成度高い( = TeaVMの方が完成度低い)感がある
  • 公式のrepoにCIがなかったり、普通にgradleでbuildしたら通らなかったりで、色々本体の開発が厳しい
  • 余計な依存ついてくる問題見つけたり、色々細かい点で気づきや不満あったが、まぁ後で報告するか、まとめる・・・かも