kanta's spike

今後ブログに検索機能などを追加したいので、Hugoに React を導入したい。

以前、HugoにVue.jsを導入する方法について学んだ。

しかし、Hugo標準でvueのテンプレートに対応していないため、テンプレートを<script type="x-template"/>内に記載するというトリッキーな方法で実現した。

一方、Reactは、js.Buildを利用すれば、Hugo標準機能で利用できるようだ。

解決策

以下の方法を採用する。

  • npmでReactを導入する
  • js.Buildを使ってjsjsxファイルを処理する

手順は以下となる。

  1. まず、reactreact-domをインストール

    npm install --save react react-dom
    
  2. 次に、Reactで作成したUIを配置する場所を作成する。

    ~~~rawhtml
    <div id="app"></div>
    ~~~
    
  3. assets/js/hello-react.jsxを作成する

    import * as React from 'react'
    import { createRoot } from 'react-dom/client';
    
    function MyButton() {
        return (
            <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded m-4">
            I'm a button
            </button>
        );
    }
    
    export default function MyApp() {
        return (
            <div className="bg-stone-200 rounded-md m-4 p-2 text-center font-bold">
            <h1>Welcome to my app!!!</h1>
            <MyButton />
            </div>
        );
    }
    
    const container = document.getElementById('app')
    const root = createRoot(container)
    root.render(<MyApp />)
    
  4. Markdown内でjs.Buildを使ってjsjsxファイルを処理する可能にするため、Shortcode(include-with-jsbuild.html)を作成する

    <!-- layouts/shortcodes/include-with-jsbuild.html -->
    {{- $jsFile := .Get "jsFile" -}}
    
    {{ $defines := dict "process.env.NODE_ENV" `"development"` }}
    
    {{ $opts := dict "defines" $defines }}
    {{ $built := resources.Get $jsFile | js.Build $opts }}
    <script type="text/javascript" src="{{ $built.RelPermalink }}" defer></script>
    
  5. Shortcode(include-with-jsbuild.html)を使って、assets/js/hello-react.jsxを読み込む

    {{< include-with-jsbuild jsFile="js/hello-react.jsx" >}}
    
  6. 実行結果は以下になる

参考

作成日: 2023/05/26