Vue.jsのプロジェクトをSpringに突っ込む
0. もう何番煎じだか
正直なところ、もう何番煎じだかわからないネタだけど、多分に自分用メモ。
今回目指したのはこんな感じのプロジェクトである。
- フロントエンド側をVue.jsによるSPAにする
- バックエンドはSpring BootによるREST APIサーバにする
- フロントエンド、バックエンドとも、Gradleマルチプロジェクトとして一括管理する
- フロントエンドの表示は、Spring BootのTomcatに同居させる
早い話、フロント用にWebサーバを用意するだけのリソースがないので一つにまとめてしまおう、というだけのことである。いうまでもないけれど、負荷分散とかを考えるならフロントとバックエンドを別のインスタンスに分離するなりの考慮は必要。
1. はじめてみる
できればIDEでちょいちょいとできればいいんだけど、やってみた感じCLIで少しずつ作っていくほうがやりやすかったので、今回はIDEを極力使わず、ターミナルとテキストエディタで対応する。
目標とするのはこういったディレクトリ構造にする。
./ → プロジェクトルート ├─backend/ -> APIサーバになるSpring Bootプロジェクト | └─build.gradle.kts -> バックエンドのguild.gradle.kts├─front-vue/ -> フロントになるVue.jsプロジェクト | └─build.gradle.kts -> フロントエンドのguild.gradle.kts└─build.gradle.kts -> ルートプロジェクトのguild.gradle.kts
1-1. 親プロジェクトを作る
ルートプロジェクトから作るわけだが、今回はマルチプロジェクトにするので、最低必要なものだけ生成する。
> gradle init --type basic --dsl kotlin --project-name vue-with-spring
ビルドタイプをbasic
にするのがミソ。こうすることで、何の設定も書かれていないbuild.gradle.kts
が生成される。
生成できたら、今後のために.gitignore
にIDE周りの無視設定を今のうちに入れておく。
また、システムに入れているGradleのバージョンが古い場合は、wrapperタスクで新しくしておくとよい。
> ./gradlew wrapper --gradle-version=6.7.1
1-2. Vue.jsのプロジェクトを作る
次にVue.jsのプロジェクトを作る。Vue CLIでvue create
すればよい。
Vue.jsのバージョンやらコンポーネントやらはお好みで。
> vue create front-vue
生成したVue.jsのプロジェクトをGradle配下に置く。これには二つの工程がある。
- ルートプロジェクトの
settings.gradle.kts
にプロジェクトのインクルード設定を書く - Vue.jsのプロジェクトに
build.gradle.kts
を書く
一つ目については、単にinclude
行を追加するだけだ。
rootProject.name = "vue-with-spring"
include("front-vue") // 追加
二つ目については、こんな感じのファイルを作った。
import com.github.gradle.node.npm.task.NpmTask
plugins {
base
// node-gradle プラグインで npm を扱う
id("com.github.node-gradle.node") version("3.0.0-rc5")
}
// ``npm run build`` を実行するタスク定義
tasks.register("npmBuild", NpmTask::class.java) {
args.add("run")
args.add("build")
}
base
プラグインを導入することで最低必要なタスクが実行できるようになるのと、node-gradleプラグインを使うことでNode.jsとnpmをGradleのタスクとして扱うことができるようになる。
後の工程でnpm run build
を実行する必要があるので、これを行うnpmBuild
タスクを用意した。
1-3. Spring Bootプロジェクトを組み込む
次に、Spring Bootのプロジェクトを作る。これはSpring Initializrで作る。最低必要なのはSpring Webだけど、プロダクション運用ならこれにデータアクセスとか、認証・認可とか、クラウド連携とかのライブラリが入るはず。
今回はプロジェクトをGradleに、言語をKotlinにした。
この状態でGenerateボタン押すとプロジェクトがZipで降ってくるんだが、この中から必要なファイルだけ取り出し、バックエンドのプロジェクトに移植する。
バックエンドのプロジェクト自体はすでにGradleプロジェクトになっていて、Spring InitializrですでにGradle Kotlin DSLになっているので、追加したSpring Bootプロジェクトをルートプロジェクトの配下にするだけでよい。
rootProject.name = "vue-with-spring"
include("front-vue", "backend") // 追加
1-4. Vue.jsのビルド成果物をSpringに取り込めるようにする
Vue.jsのプロジェクトはnpm run build
を実行すると、プロジェクト内の dist ディレクトリ内にプロダクションビルドした内容を出力する。
これをSpring側に反映すればいいのだが、毎度手でコピーしていると面倒極まりないのでビルド成果物を直接Springに出力するよう設定する。
これは、Vue.jsプロジェクト側にVue.js自体の設定ファイルであるvue.config.js
を作成する。(リファレンス
module.exports = {
outputDir: "../backend/src/main/resources/static/"
}
要は、バックエンドプロジェクトのsrc/main/resources/static/
に直接出力するわけで、SpringとしてはここにあるファイルをWebコンテナに取り込んで起動するので、これで動いてしまうわけだ。
あとはbootRunタスクを実行すれば、Vue.jsをフロントにしたサイトを表示できる。
> ./gradlew :backend:bootRun
:backend:bootRunタスクの前処理に:front-vue:npmBuildタスクを実行するような設定を書いてやるのでもいいかもしれないが、開発中はVue.jsのプロジェクトとSpring Bootのプロジェクトを独立して動かして動作確認する、といったシーンも考えられる。
そういった場合は
.PHONY: front-boot-run
front-boot-run:
./gradlew :front-vue:npmBuild
./gradlew :backend:bootRun
みたいなMakefile
を書いて、makeターゲットとしてしまうのがいいのかもしれない。
最近のコメント