
2025.02.12
職員一人あたり52時間の残業削減に成功 kintone導入がもたらした富士吉田市の自治体DX“変革”ハウツー
リンクをコピー
記事をブックマーク
Taro L. Saito氏:じゃあ今度はクライアントサイドについて見ていきます。Scala.jsというのは基本的にScalaのコードをJavaScriptに変換するものなので、基本的にScalaのコードしか使えない。例えばJavaのコードが紛れ込んでいるとコンパイルがエラーになってしまいます。なので、依存関係にあるライブラリもすべてScalaになるように注意する必要があります。
Airframeでは、Scala以外のコードが紛れ込まないように、dependencyを最小にして、すごく非常に気を遣ってデザインされています。あとアノテーションが使えなかったりとかランタイムリフレクションが使えないなどの制約があります。
一方、コンパイルタイムに行われるもの、例えばScala Macrosによるコード展開などは、実はScala.jsではなにも問題なく使えます。
またRPCの実装では、常に非同期実行になります。Scala Futureベースの非同期実行になっていて。ただ問題なのが、Futureを待つ方法というのがないんですね。というのも、JavaScriptはブラウザ上でシングルスレッドで動いているものなので、バックグラウンドで処理を待つということはありません。だから結局レスポンスを受け取ってFutureのチェインでmap、flatMap、resqueなどを駆使して操作を連結することが必要になってきます。
Scala.jsのコードはブラウザ上で動くのでデバッグがなかなか大変になってくるんですけれども、Chromeなど最近のブラウザにはDeveloper Consoleというのがあって、そこに対してログを表示してあげると、非常にデバッグしやすくなります。
Scalaのコードは1回JSにコンパイルされているんですけれども、airframe-logというモジュールを使うと、デバッグが非常にしやすくなります。例えばdebugというメッセージをここで表示すると、ここのデバッグログのメッセージだけじゃなくて、ソースコードのファイル名や行数までも表示されます。
また、Scala.jsでWeb UIを作るための手法も実はすごくいろいろあるんですね。ただ、基本的にはDOMを生成すればいい。DOMというのは例えば
例えばXMLリテラルのScalaの機能を使ってDOMを表示するなど。monadic-html、Binding.scala、そういうライブラリがありましたけれども、どうしてもこのXMLをScalaの中に書くのは、ちょっと書きにくいところもあります。Dotty(Scala 3.0)ではXMLリテラルが廃止されるので、このアプローチというのはどうも筋がよくない。
現在のベストプラクティスは、Scalaの関数を使ってDOMをどんどん構成していく。例えばScalaTagsでは、このHTMLというのが関数で定義されています。「html」「head」「body」「h1」「div」、これらのタグが全部関数で定義されている。今から紹介するAirframe RxもすべてHTMLのタグに対応するものを関数で定義しています。
この2つの大きな違いは、DOMのelementとattributeを区別するかどうか。例えばScalaTagsでは、ここがattributeで、ここはtext部分なんですけど、この両者を区別するのに括弧を入れています。一方、もっと最近のアプローチだと、この2つを区別しないで、両方とも1つの括弧の中に入れてしまおうという。
実は後者のほうがScalaの関数型のシンタックスに非常にマッチしていて、実際に書いてみると、ScalaTagsはすごく括弧をたくさん書かなくてはいけなくてすごく大変な書いていてつらいライブラリですが、最近のscalajs-reactとかAirframe Rxでは、よりScalaで書きやすい形になっています。
関数をネストさせることでより複雑なDOMの要素も生成できます。Airframe RXではrenderというインターフェイスを提供することで、DOMのエレメントをネストしたりとか、あとからスタイルを設定したりとか、そういうことが可能になるようにデザインされています。
また例えばこういう凝ったテーブルのレイアウトを表示したいときに、Scalaのコレクションを間に埋め込んだり、テーブルの1行1行を表示したり、イベントに応じてDOMを書き換えたり、そういうことができるようになっています。
また、リアクティブにユーザーのクリックなどの動作に反応してUIを書き換えなくてはいけないので、例えばRx.variableというものがありまして……。これは何をするかというと、変数に変更があるとイベントをどんどん後ろのオペレーターに伝播、すなわち影響を伝播させていくという実装になっています。
例えばRx.variableを定義して、実際にマップをして、文字列を作って、subscriberでprintする。そうすると、最初は「World」という値が入っているので「Hello World!」が表示されるんですけれども、このRxの変数の中身を書き換えてあげると、今度は同じコードが実行されて、今度「Hello Rx!」が表示される。そういう仕組みになっています。
こういう仕組みはMonixとかScala.rxなどいろいろなライブラリでも実装されていて、monadic-htmlでも同様な実装になっています。
重要なのは、最終的にsubscriptionをキャンセルしてDOMのリフレッシュができることです。Airframe Rxは、Monixだったりとかmonadic-htmlのいいところを取って、このダイナミックにDOMを書き換えるインターフェイスが定義されています。
また、このRxの実装の背景にあるのがReactiveXというストリームを処理する実装です。これは基本的にはmap、flatMap、filterなどのオペレーションが使えて、ScalaのコレクションのAPIとほぼまったく一緒なんですね。なので、Scalaのコレクションの使い方さえ知っていれば、こういうストリームの情報、すなわちイベントの情報を受け取って、その都度DOMの要素を書き換えていくというのは、実はすごく簡単にできる。
また、このリアクティブのRxの抽象化を使うことで、例えばgRPCではクライアントストリーミング、サーバーストリーミング、あとは双方向での通信を適宜行うようなアドバンスドな通信もサポートされているんですけれども、そういうのもどんどん実装することができます。
では、まとめです。Airframeを使うことでScala中心の開発をすることが可能になっています。このアプローチのメリットは、もうScalaさえ学べばクライアント・サーバーの実装というのを全部済ませてしまう。非常にラーニングコストが下がるんですね。 Protocol Bufferについて学ばなくてもいいし、FinagleとかgRPCのWebサーバー側の技術についても最初は学ばなくてもよくなるというところがすごく大きなところ。 結論です。Scalaは非常に強力なプログラミング言語です。いいところは、最初はすべての技術を蹴散らすような書き方をしたんですけれども、実際にはいろいろな技術のいいところをScalaにどんどん集約することができます。ラーニングコストを最小化してScalaファーストなアプローチを可能にしているのがAirframeのライブラリです。 以上で終わりです。ありがとうございました。
Scalaはラーニングコストが下がる
2025.02.06
すかいらーく創業者が、社長を辞めて75歳で再起業したわけ “あえて長居させるコーヒー店”の経営に込めるこだわり
2025.02.03
「昔は富豪的プログラミングなんてできなかった」 21歳で「2ちゃんねる」を生んだひろゆき氏が語る開発の裏側
2025.02.03
手帳に書くだけで心が整うメンタルケアのコツ イライラ、モヤモヤ、落ち込んだ時の手帳の使い方
2025.02.04
日本企業にありがちな「生産性の低さ」の原因 メーカーの「ちょっとした改善」で勝負が決まる仕組みの落とし穴
PR | 2025.02.07
プロジェクトマネージャーは「無理ゲーを攻略するプレイヤー」 仕事を任せられない管理職のためのマネジメントの秘訣
2025.02.05
「納得しないと動けない部下」を変える3つのステップとは マネージャーの悩みを解消する会話のテクニック
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.02.06
落合陽一氏や松尾豊氏の研究は社会に届いているか? ひろゆき氏が語るアカデミアの課題と展望
2025.02.05
エンジニアとして成功するための秘訣とは? ひろゆき氏が語る、自由な働き方を叶えるアプリ開発とキャリア戦略
2025.02.04
生成AI時代に差をつける思考法とは? ひろゆき氏が語る「真のエンジニア像」