Hugo 以外の Hexo などの他の静的ブログでもこの方法を使用できます。
公式紹介#
Shiki(式、意味は「スタイル」)は、美しく強力なコードシンタックスハイライターで、VS Code のシンタックスハイライトエンジンと同様に、TextMate のシンタックスとテーマに基づいています。Shiki は、ほぼすべての主要なプログラミング言語に対して非常に正確かつ迅速なシンタックスハイライトを提供します。
カスタムの正規表現を維持する必要も、カスタムの CSS を維持する必要も、カスタムの HTML を維持する必要もありません。なぜなら、VS Code で使用しているカラーテーマを Shiki でも使用できるからです。
利点#
Hugo で Shiki コードシンタックスハイライターを設定するのに数分しかかかりません。
私が最も気に入っている点は、他のコードシンタックスハイライターのように大規模な JS リソースを導入する必要がなく、Shiki は HTML ファイルに書き込まれ、純静的です。Hugo ブログプロジェクトは、@shikijs/rehypeプラグインを利用して Shiki コードシンタックスハイライトを実現でき、ローカルまたは GitHub Actions などのビルドプラットフォームで簡単にデプロイできます。
Shiki のインストール#
Hugo ブログのプロジェクトディレクトリに移動し、次のものをインストールします:
前提条件として、Node.js
とYarn
をインストールする必要があります。Yarn
を選択するのは、GitHub Actions のキャッシュに優しいからです。
# cd my-hugo-project
npm install shiki
npm install @shikijs/rehype
npm install rehype-cli
Hugo の設定#
Hugo の config で、codeFences
をfalse
に設定する必要があります。
[markup]
[markup.highlight]
codeFences = false
.rehyperc
の作成#
Hugo ディレクトリに.rehyperc
ファイルを作成し、私の設定内容は以下の通りです:
{
"plugins": [
[
"@shikijs/rehype",
{
"themes": {
"light": "github-light",
"dark": "github-dark-dimmed"
}
}
]
]
}
Rehype には多くのプラグインがありますが、私はハイライトテーマだけを設定しました。light
モードにはgithub-light
を、dark
モードにはgithub-dark-dimmed
を使用しています。GitHub のテーマは常に信頼できます。
テーマリストはこちら: https://shiki.tmrs.site/themes
ダークモードを有効にするには、元の Hugo の CSS を適応させる必要があるかもしれません。例えば、私のブログでは<html class="dark">
の方法でダークテーマを切り替えていますので、custom.cssにテーマカラー変数を追加するだけで済みます:
html.dark .shiki,
html.dark .shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
/* オプション、フォントスタイルを定義するため */
/* font-style: var(--shiki-dark-font-style) !important; */
/* font-weight: var(--shiki-dark-font-weight) !important; */
/* text-decoration: var(--shiki-dark-text-decoration) !important; */
}
prefers-color-scheme: dark
の方法でダークモードを切り替える場合は、これらの変数を簡単に適応させるだけで済みます:
.shiki,
.shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
/* オプション、フォントスタイルを定義するため */
/* font-style: var(--shiki-dark-font-style) !important; */
/* font-weight: var(--shiki-dark-font-weight) !important; */
/* text-decoration: var(--shiki-dark-text-decoration) !important; */
}
Shiki の生成#
まず、hugo
コマンドを実行して Hugo を構築します。構築された成果物がpublic/
ディレクトリにあると仮定し、次にrehype-cli
を使用して Shiki を生成します:
# cd my-hugo-project
npx rehype-cli public -o
このコマンドを実行すると、メモリエラーが発生する可能性があります:
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
メモリ使用量を制限する必要があります:
export NODE_OPTIONS="--max_old_space_size=7168"
7168 ≈ 7G、コンピュータの構成に応じて調整できますが、GitHub Actions の無料ランナーは最大 7G です。
GitHub Actions で Shiki を使用する#
Hugo ディレクトリのpackage.json
のscripts
に次のように追加します:
"scripts": {
"shiki": "npx rehype-cli public -o"
},
GitHub Actions ワークフロー:
name: Build Hugo and Deploy With Shiki
on:
workflow_dispatch:
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Setup Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: 'latest'
extended: true
- name: Build Hugo
run: |
hugo -gc --minify
- name: Setup Node LTS
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: yarn
- name: Install and run Shiki
run: |
export NODE_OPTIONS="--max_old_space_size=7168"
yarn install
yarn run shiki || true
# または 👇
# npx rehype-cli public -o --silent || true
- name: Keep going
# 後続のプロセス
Shiki のエラーによって Hugo のデプロイプロセスが中断されるのを防ぐために、|| true
を追加することができます。エラーが発生してもデプロイプロセスは続行されます。一般的なエラーは、以前のブログ記事がサポートされていないコード名を使用している場合です。
Cloudflare Pages ではメモリ制限を設定できないため、cloudflare/wrangler-actionという Actions を使用できます:
- name: Publish to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
quiet: true
command: pages deploy public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }} --commit-dirty=true