本連載は分散型マイクロブログ用ソフトウェアMisskeyの開発に関する紹介と、関連するWeb技術について解説を行うものです。今回はMisskeyオフィシャルサイトであるMisskey Hubでも使用している、静的サイトジェネレーターVuePressについて紹介します。
図1 VuePressで構築されている「Misskey Hub」
静的サイトとは
静的なサイトを理解するにはまず動的なサイトを理解するのが早いと思います。
動的(dynamic)なサイトとは、簡単に言うと閲覧者のアクセスごとに内容をサーバーで生成するWebサイトのことです。例えばTwitterのようなサービスを考えると、表示されるタイムラインは閲覧者がフォローしているユーザーによって異なるため、同じtwitter.comへのアクセスでも異なる内容になります。
静的(static)なサイトとは、動的なサイトの逆で、そのWebサイトのすべてのコンテンツがあらかじめ用意されていて、それらを配信するだけのサイトです。例えばブログやWikiなどのWebサイトを考えると、誰がアクセスしても内容は同じですので静的だと言えます。
Webサイトの内容が静的だと、Webサーバーはコンテンツを生成したりする役割を持たず、あらかじめ用意されたコンテンツを送り返せば良いだけになり、非常に運営のコストが減ります。また、どのアクセスに対しても返す内容が同じでコンテンツをキャッシュできることから、そういった「コンテンツを配信する」用途に特化したサービスであるCDNとの相性が良いです。さらに、サイト内容をGitHubで管理すれば、GitHub Pagesを用いてそのままサイト公開が行えるので、自分でサーバーを用意・管理する必要さえありません。
VuePressとは
VuePressはそういった静的サイトの作成を行うソフトウェア(Static Site Generator, SSG)のひとつです。Webサイトが簡単な内容であればHTMLやCSSを手書きで作ることも可能ですが、規模が大きい場合は手動での管理は困難です。VuePressを使うことで、Markdownの使用、自動目次生成、全文検索、多言語対応、Vueコンポーネントの埋め込みなど複雑なことが簡単に行えるようになります。また、テーマが標準で用意されているのでデザインの手間が省けますし、プラグイン機能もあるため自由に拡張することもできます。
使ってみる
実際にVuePressを使ったサンプルを動かしてみます。前提として、Node.js、npmがインストールされている必要があります。
ディレクトリを作成します。
mkdir my-site cd my-site
nodeプロジェクトを初期化します。このコマンドを実行した際に出るプロンプトはすべて空欄のままで構いません。
npm init
VuePressをプロジェクトに追加します。
npm install -D vuepress@next
package.jsonのscripts
内を以下のように書き換えます。
"dev": "vuepress dev docs",
"build": "vuepress build docs"
ページを作成します。文字化けした場合はファイルの文字エンコードがUTF-8になっているか確認してください。
mkdir docs echo '# Hello VuePress' > docs/README.md
開発サーバーを起動します。
npm run dev
以上で準備は完了です。開発サーバーが起動したら、ブラウザでhttp://localhost:8080
にアクセスすることでサイトの内容が表示されます。問題なく設定できていれば、「Hello VuePress」が表示されているはずです。
図2 「Hello VuePress」
この開発サーバーにはHMR(Hot Module Replacement)の機能が備わっているため、ページの内容を変更すると自動でブラウザに反映されます。実際にdocs/README.md
を編集して動作を確かめてみてください。デフォルトでMarkdownが使えます。
なお、サイト全体を静的サイトとしてビルドするには以下を実行します。
npm run build
これにより、docs/.vuepress/dist
内にサイトが生成されます。よって、サイトを公開する際はこのディレクトリをまるごとサーバーにアップロードすれば良いわけです。
カスタマイズ
ここまでで作成したサンプルは最小限のものです。実際にはサイト設定、テーマ、プラグインなどのカスタマイズが行えます。
まず設定ファイルを編集し、サイトの設定を変更してみます。docs/.vuepress
内にconfig.js
というファイルを作成し、中身を以下のようにしてください。
import { defineUserConfig } from 'vuepress'
export default defineUserConfig({
lang: 'ja-JP',
title: 'VuePressのテスト',
})
ファイルが作成できたら開発サーバーを再起動して再度ブラウザで表示してみてください。サイトのタイトルが「VuePressのテスト」に変わっているはずです。このように、サイトの設定はconfig.js
に記述します。設定の詳細については公式ドキュメントを参照してください。
Vueコンポーネントの利用
VuePressの強みは、名前にもあるようにVueのコンポーネントを使った静的サイトを作成できることです。Vueコンポーネントを使用することで、静的サイトでありながらインタラクティブなページが実現できます。実際に試してみましょう。
まず、docs/.vuepress
内にcomponents
ディレクトリを作り、その中にMyCounter.vue
ファイルを作成します。ファイルの中身は以下のようにします。
<template>
<div>
<p class="label">回クリックしました</p>
<button @click="count++">ここをクリック!</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0)
</script>
<style lang="scss" scoped>
.label {
color: red;
}
</style>
Vueコンポーネントの書き方など詳細についてはVue公式ドキュメントを参照してください。
次に、追加の依存関係をプロジェクトにインストールします。
npm i -D @vuepress/plugin-register-components@next
設定ファイルを以下のように変更します。
import { defineUserConfig } from 'vuepress'
import { path } from '@vuepress/utils'
import { registerComponentsPlugin } from '@vuepress/plugin-register-components'
export default defineUserConfig({
lang: 'ja-JP',
title: 'VuePressのテスト',
plugins: [
registerComponentsPlugin({ componentsDir: path.resolve(__dirname, './components/') }),
],
})
最後に、README.md
を以下のように変更します。
# Hello VuePress
<MyCounter/>
これで完了です。開発サーバーを再起動し、ブラウザでアクセスしてみてください。上手くいけば、Vueのコンポーネントがページに埋め込まれているでしょう。
図3 カウンターが設置された
自動デプロイ
冒頭触れましたが、このVuePressプロジェクトをGitHubのリポジトリとして管理を行えばGitHub Pagesを利用してサイトをゼロコストで公開できます。GitHub Pagesの詳細についてはこの記事では省略しますが、GitHub Actionsを使うとコミットを行った際に自動でVuePressのビルドを行い、GitHub Pagesに反映させることが可能です。
以下にActionの例を示します。
name: GitHub Pages
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 16
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ~/.npm
key: npm-$
restore-keys: npm-
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: $
with:
github_token: $
publish_dir: ./src/.vuepress/dist
cname: my-site.example.com
GitHub Pagesでは独自ドメインも使用できます。
Misskey Hubでもこの技術スタック(VuePress + GitHub Pages + GitHub Actions)で管理されています。
まとめ
VuePressを使うことで、簡単にリッチな静的サイトを生成できることを紹介しました。また、リポジトリをGitHubで管理することでゼロコストでサイトを公開できることを紹介しました。
VuePressなどのSSGとGitHub Pagesの組み合わせは、ライブラリの公式ドキュメントやブログなど、幅広い用途で活用できます。ぜひSSGを使ったサイト生成を試してみてください。