Spring BootでSPAとAMPの併用
Spring Bootでは基本的にフロント側はThymeleafを使用し、サーバサイドで取得した変数を活用して描画させますが、HTMLの組み方によってはAMPページもThymeleafで作成することができます。
一方SPAはSingle Page Application(シングルページアプリケーション)の名の通り、基本的にはどのURLからのアクセスでもindex.htmlなどの固定のhtmlファイルでページを開いてから、Ajaxなどの非同期通信で情報を取得してJavascriptで描画させることになります。
まったく別の技術を使用している両者ですが、URLによる切り分けで共存させることは可能です。
方法としては、サーバサイド(Spring Boot)側のコントローラーでURLによって呼び出すテンプレートを切り分けることで、両者の併用は可能になります。
ちなみにフロント側では、AMPページは一部を除いてJavascriptが動作しないため、SPAの実装の中にAMPを導入するという方法を取ることはできません。
あくまでサーバサイドのコントローラーで切り分けてください。
以下に実装方法を記載しますが、サーバサイドはJavaのSpring Bootを使い、フロントはvue-cliによるVue.jsを使用しています。
Thymeleafの文法チェックが難点
対応に当たって一番詰まった点としては、Thymeleafの厳しい文法チェックエラーです。
ThymeleafではnekoHTMLというライブラリを使えば厳しい文法チェックエラーを避けることができますが、nekoHTMLを使えば今度はAMPページのバリデーションチェックで以下のようなエラーが出続けます。
AMP validation had errors: The tag 'head > style[amp-boilerplate]' appears more than once in the document. (see https://github.com/ampproject/amphtml/blob/master/spec/amp-boilerplate.md) The tag 'noscript > style[amp-boilerplate]' is missing or incorrect, but required by 'head > style[amp-boilerplate]'. (see https://github.com/ampproject/amphtml/blob/master/spec/amp-boilerplate.md) The mandatory tag 'noscript > style[amp-boilerplate]' is missing or incorrect. (see https://github.com/ampproject/amphtml/blob/master/spec/amp-boilerplate.md)
よって、nekoHTMLは使えないのですが、そうなると今度はVue.js側でThymeleafの文法エラーで引っかかります。
例えばVue.jsでコンパイル後に作成されるindex.htmlでは以下の記述がありますが、
<link href="/static/css/app.xxxxxxxxxxxxxxxxxxxxxxxx.css" rel="stylesheet">
このあたりなどはlinkの閉じがないために以下のような文法チェックエラーになってしまいます。
org.xml.sax.SAXParseException: The element type "link" must be terminated by the matching end-tag "</link>".
よって面倒ですが以下のように閉じなければいけません。
<link href="/static/css/app.xxxxxxxxxxxxxxxxxxxxxxxx.css" rel="stylesheet" />
ただ、これをコンパイルのたびに閉じ直すのは、面倒な上に忘れてしまいがちです。
replace-in-fileで解決
ここで便利なのが、「replace-in-file」というnpmのパッケージです。
その名の通り、ファイルを指定して文字を置換してくれるパッケージです。
本当はこのような無理矢理のやり方でなくてもいい方法があるのかもしれませんが、1つの手段として参考にしていただければと思います。
使う時はnpmでインストールしてください。
npm install replace-in-file --save
まずbuild.jsで、「rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {...」と記述がある前に以下の一行を入れてインポートしてください。
var replace = require('replace-in-file')
そして「console.log(chalk.cyan(' Build complete.\n'))」の記述の前には以下を入れてください。
const options = { files: '../resources/templates/index.html', from: 'rel="stylesheet">', to: 'rel="stylesheet" />' } try { replace(options) } catch (error) { console.error('Error occurred:', error) }
これでindex.htmlファイルの「rel="stylesheet">」の部分が「rel="stylesheet" />」に置換されるのです。
サーバサイドで切り分け
あとはSpring Bootのコントローラーで切り分けをすれば完了です。
SPAで開きたいURLの方はindex.htmlを、AMPで開きたい時にはそのhtmlファイル(今回は例としてamp-index.htmlとします)を開くようにしてください。
@Controller public class TestPageController { // SPAで開きたいURLの場合 @RequestMapping(value = "spa"}, method = RequestMethod.GET) String indexSpa() { return "index"; } // AMPで開きたいURLの場合 @RequestMapping(value = "amp"}, method = RequestMethod.GET) String indexAmp() { return "amp-index"; } }
- 作者: mio
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))
- 作者: 渡邊達明
- 出版社/メーカー: インプレスR&D
- 発売日: 2018/07/13
- メディア: Kindle版
- この商品を含むブログを見る
- 作者: 掌田津耶乃
- 出版社/メーカー: 秀和システム
- 発売日: 2017/05/09
- メディア: Kindle版
- この商品を含むブログを見る
はじめてのSpring Boot―スプリング・フレームワークで簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槙俊明
- 出版社/メーカー: 工学社
- 発売日: 2016/09/01
- メディア: 単行本
- この商品を含むブログ (1件) を見る