[Playframework, Scala]フロントエンドとの分離を頑張る(1) playプロジェクトからフロントエンドのプロジェクトを分離する

やりたいこと

1つのプロジェクトでフロントエンドとサーバサイドをできるだけ分離させたい

フロントエンド関連のリソース(画像、CSS、Javascript)がapp/assets/やpublic以下に
分散したり、それをsbtで管理したりを避けたい

端的にいうと

  • サーバサイドはsbtプロジェクト
  • フロントエンドはnodeプロジェクト

で、それぞれ管理して、いい感じに使いたい

(最終的にはgulp入れたり、いい感じにminifyしたりbabel使ったり、とか
色々やってみて、それ全部まとめてブログ書こうと思ったんだけど
思ったよりとっ散らかったので、飽きなければ細かく分けて書くことにしました)

こんな感じにしたいと思ってます。

Javascriptを置く場所をpublic、app/assets以外にする

参考記事 Play FrameworkのアセットコンパイルをGulpにすべておまかせ Qiita

ほとんど参考記事にあるものそのままです。
違う点は

  • 参考記事はindex.htmlも静的ファイルを参照させてますが、ここでは省いてます。
  • Playframework2.4からオブジェクトではなくクラスになったのでそのためのクラス定義と
    @Singletonアノテーションを付与

だけです。

後述しますが、CSS,画像,Javascriptをpublic, app/assets
を自分の好きなディレクトリにするだけなら、もっともっと簡単にもできます。
が、とりあえず色々あって自分が使った方のうち、最もシンプルなものが以下です。

app/controllers/FrontendAssets.scala

このクラスを定義してconf/routesに

を追加します。/assets/*fileの定義が既にある場合は置き換えてください。
これによって

viewのhoge.scala.htmlで

とすることで、frontend/dist/javascript/hoge.jsを参照させることができます。

後で教えてもらったんですが上記の色々をやらなくても
以下だけでもpublic以外のディレクトリを参照させることは実現できます。

build.sbt(project/build.scala)に

と書けば参照させることが可能です。
(AssetsBuilderを自分で書くといろいろいじれる点でいいかも)

あとは。。。

frontend/以下をnodeプロジェクトでいい感じにすればOK。
そこに関しては、長くなるので別記事で。

とりあえずは、これでplayから(publicやapp/assetsから)フロントエンド部分を切り出しました。
(もちろんfrontend/も含めて全部でplayプロジェクトとも言えるんですが)

ちょっと注釈

上記の変更を行って、そのまま$activator distして
どこかの環境にデプロイしたとしても動作します。

僕が最初に試したときの疑問として、各種フロントエンド用のリソースを
frontend/distに移したのに

FrontendAssets.scalaの

でも何故動作するのか。
これがAssets.at("/public", file)でも動くのは
$ activator stageを実行してみることで確認できます。

$ activator stageはアプリケーションで利用される色々なものを
あらかじめコンパイルしてjarに固めてくれるタスクです。

これで、各種フロントエンド用リソースがどのように固めるか確認できます。

固められたjarファイルは
[project-name]/target/scala-2.11/[project-name]_2.11-1.0-SNAPSHOT-web-assets.jar
です。これを展開してみましょう。

して、どのようにフロントエンド用リソースが格納されているか確認してみてください。
publicディレクトリに全て纏められています。

ので、本番用はpublic/ディレクトリが基底となっていても参照が問題なくできます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です