Spring Boot + NuxtJSによるSPA構築
はじめに
この記事では、各プロジェクトの作成方法などについては触れません。 NuxtJS で生成した SPA をどのようにしたら Spring Boot でホスティングできるのかという説明になります。
各バージョンにより設定が異なる(変わってくる)可能性があります。 この記事では以下のバージョンで検証しています。
- Spring Boot 2.5.5
- NuxtJS 2.5.17
NuxtJS
SPA を構築するため、nuxt.config.js
のssr
とtarget
が以下であることが前提です。
export default {
ssr: false,
target: 'static',
//...
}
Spring Boot 側でコンテキストパスを設定する場合は、以下で同じものを設定します。
export default {
//...
router: {
base: '/context-path',
},
//...
}
あとは以下コマンドで、ビルドして SPA を生成します。
デフォルトだとdist
フォルダに生成されます。
$ npm run generate
今回は仮に、ホーム(/
)と About(/about
)のページがあることとします。
Spring Boot
生成した SPA をsrc/main/resources/static
に配置します。
サーバーを起動してルートパスにアクセスすれば、ホームのページが表示されると思います。
ページリンク(<nuxt-link>
)であれば、About ページも表示されます。
問題はページリロードです。
About ページでリロードすると、404
として「Whitelabel Error Page」が表示されるかと思います。
ページリンクでは、SPA のためあくまで JavaScript でページを構築したに過ぎません。 つまり、サーバー側にリクエストを送信していません。
一方ページリロードは、/about
に対してリクエストを送信するため、対象のリソースがないと判断されています。
これを解決するために、以下の設定クラスを作成します。
@Configuration
public class SpaResourceConfig implements WebMvcConfigurer {
@Autowired
private Resources resource;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**")
.addResourceLocations(resource.getStaticLocations())
.resourceChain(false)
.addResolver(new SpaPageResourceResolver());
}
private static class SpaPageResourceResolver extends PathResourceResolver {
@Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
Resource resource = super.getResource(resourcePath, location);
return resource != null ? resource : super.getResource("index.html", location);
}
}
}
細かい説明は省きますが、リクエストした際に対象のリソースがない場合、ホームのページ(src/main/resrouces/static/index.html
)を表示するような設定になります。
例えば/about
にリクエストを送信した場合、リソースとしてはindex.html
が返ってきますが、/about
というパスはそのまま残るため、パスから SPA が対象のページを構築します。
注意点として、@EnableMvc
を付与した@Configuration
クラスが存在するとルートパスでホームページが表示されません。
なぜそのようなことが起こるかまではわかりませんが、ご参考までに。