埼玉在住エンジニアのナレッジ帳

webのエンジニアをやっており、日頃の開発で詰まったことについて残していきたいと思っています。https://ikujip.jpの開発も行っているため、そこで使った知識なども載せられればと思います。

SPAとAMPを共存させたサイト

私が個人的に運営しているサイトで、ページごとにSPAとAMPページを切り替えています。
技術はサーバサイドはJavaのSpring Bootを使い、フロントはvue-cliによるVue.jsを使用しています。

詰まった点としては、Thymeleafの厳しい文法チェックエラーの対応です。
通常AMPを使わないのであれば、nekoHTMLを使い文法チェックエラーを避けることができますが、それだとAMP実装時に文法エラーが出てしまうのです。

よって、Vue.jsでコンパイル後に作成されるindex.htmlをThymeleafの文法チェックが通るようにする必要があります。
例えば、

<link href="/static/css/app.xxxxxxxxxxxxxxxxxxxxxxxx.css" rel="stylesheet">

のあたりなどはlinkの閉じがないために文法チェックエラーになってしまいます。
この部分は以下のように閉じなければいけません。

<link href="/static/css/app.xxxxxxxxxxxxxxxxxxxxxxxx.css" rel="stylesheet" />

ただ、これをコンパイルのたびに書き直すのは、面倒な上に忘れてしまいがちです。
ここで便利なのが、「replace-in-file」です。
その名の通り、ファイルを指定して文字を置換してくれるパッケージです。
本当はこのような無理矢理のやり方でなくてもいい方法があるのかもしれませんが、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" />」に置換されるのです。

あとはVue.js側(SPA側)は今まで通り実装し、AMPもThymeleafなどを使いながら文法に気をつけて実装すれば共存ができます。

参考までにSPAとAMPを共存させたサイトを紹介します。

<SPA>
https://ikujip.jp/mother/thread/1

<AMP>データベースの値を取り出して、動的にコンテンツを表示させています。
https://ikujip.jp/column/1