GitHub Pages をローカルで動作確認する
目的
素の HTML / CSS / JavaScript で書かれたサイトを GitHub Pages でホスティングし、コードを書くときにローカルで確認したい。[1]
ローカルで動かすハードル
- index.html を直接開くと Fetch API が使えない
- GitHub Pages のルートが
/<repository>
なのでローカルと本番でパスが合わない
HTML と CSS だけなら index.html をダブルクリックしてブラウザで開いて確認できます。
しかしルートを指定した /path/to
のようなパス指定は使えませんし、 JavaScript を使って自サイトのファイルを取得しようとすると Fetch API が URL scheme file
に対応していないため下記のエラーが出ます。
Fetch API cannot load file:///C:/path/to/anime-info/docs/data/2020-Q3.json. URL scheme "file" is not supported.
ローカルサーバーを建てる
今回は Node.js の Express を使用します。[2]
Express インストール
リポジトリの直下で以下のコマンドを実行します。
npm init
npm install express --save-dev
github-pages.js 作成
リポジトリの直下に github-pages.js
を作成します。
コードは anime-info/github-pages.js にも置いてあります。
const express = require('express');
const path = require('path');
const hostname = 'localhost';
const port = 8000;
const repository = path.basename(__dirname);
const folder = '/docs';
const app = express();
app.listen(port, () => {
console.log(`Server running at http://${hostname}:${port}/${repository}/`);
});
app.use(`/${repository}`, express.static(path.join(__dirname, folder)));
app.use((req, res) => {
res.status(404).sendFile(path.join(__dirname, `${folder}/404.html`));
});
起動
node github-pages.js
GitHub Pages に対応するためのポイント
Fetch API
サーバーを建てることで Fetch API が使えます。
const express = require('express');
const app = express();
const port = 8000;
app.listen(port, () => {
});
ルーティング
/<repository>
でアクセスされたときに /docs
へルーティングします。
リポジトリ名はディレクトリ名を取得します。
const repository = path.basename(__dirname);
const folder = '/docs';
app.use(`/${repository}`, express.static(path.join(__dirname, folder)));
404 Not Found
GitHub Pages では 404.html
を置くと 404 Not Found のページをカスタマイズできます。
このルーティングにも対応します。
app.use((req, res) => {
res.status(404).sendFile(path.join(__dirname, `${folder}/404.html`));
});
課題
GitHub Pages をそれっぽく再現してますが完全に同じ動作をしているわけではないと思います。
またパラメーターはコマンドからも受け取れるようにすればスクリプトの使いまわしがしやすそうな気はしてます。(特に port
と folder
の部分)
-
Jekyll を使う場合は Jekyll を使用して GitHub Pages サイトをローカルでテストする - GitHub Docs が参考になりそうです。 ↩︎
-
雑に
/docs
直下でphp -S localhost:8000
を実行して建ててもそれっぽくは動くのですがパスの解決ができないのと 404 の挙動が違いそう。 ↩︎
Discussion