TypescriptとReactでHugoのテーマを自作する

TypescriptとReactを導入してHugoのthemeを作成してみたのでメモを残す。 hugo自体の設定をしたメモは、markdownで記事を作成して無料ブログをつくる[Github Pages+Hugo]に記載。

Hugoのテーマを初期化

hugo new themeコマンドでテーマの雛形を作ることができる。 以下は、具体的な例としてtomatohugoという名前のテーマを初期化するコマンド。

hugo new theme tomatohugo

このコマンドを実行すると、tomatohugoディレクトリが作成され、その中に様々なファイルやディレクトリが生成される。

➜  tomatohugo git:(main) tree .
.
├── LICENSE
├── README.md
├── archetypes
│   └── default.md
├── assets
│   ├── css
│   │   └── main.css
│   └── js
│       └── main.js
├── content
│   ├── _index.md
│   └── posts
│       ├── _index.md
│       ├── post-1.md
│       ├── post-2.md
│       └── post-3
│           ├── bryce-canyon.jpg
│           └── index.md
├── data
├── hugo.toml
├── i18n
├── layouts
│   ├── _default
│   │   ├── baseof.html
│   │   ├── home.html
│   │   ├── list.html
│   │   └── single.html
│   └── partials
│       ├── footer.html
│       ├── head
│       │   ├── css.html
│       │   └── js.html
│       ├── head.html
│       ├── header.html
│       ├── menu.html
│       └── terms.html
├── static
│   └── favicon.ico
└── theme.toml

15 directories, 25 files

初期化が完了したら、hugo serverコマンドを使用してローカルサーバーを起動し、シンプルなテーマが正しく動作しているか確認できる。

hugo server

初期化したコミット:https://github.com/yuhi-sa/tomatohugo/commit/695eed912b903388faf16a1791b852697811d348

Typescriptを導入

npm initコマンドを使用してpackage.jsonファイルを初期化する。

npm init -y

typeScriptts-loaderをインストールする。

npm install --save-dev typescript ts-loader

TypeScriptの設定ファイルであるtsconfig.json作成する。

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "./assets/js/",
    "strict": true
  },
  "include": [
    "./assets/ts/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

./assets/ts/ディレクトリ内にTypeScriptファイルmain.tsを作成する。

const message: string = "Hello, TypeScript!";
console.log(message);

Webpackの設定ファイルwebpack.config.jsを作成する。 Webpackは、JavaScriptアプリケーションのためのモジュールバンドラーである。複数のJavaScriptファイルやその他のアセット(CSS、画像、フォントなど)を結合し、最適化された単一のファイルを生成することができる。

const path = require('path');

module.exports = {
  entry: './assets/ts/main.ts',
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'assets/js'),
  },
};

ビルド実行する。

npx webpack

これで、``./assets/js/bundle.jsが作成される。 生成されたJavaScriptファイルをHugoのテンプレートに組み込むために、layouts/partials/head/js.html`などの適切な場所に以下のようなコードを追加する。

<!-- layouts/partials/head/js.html -->
{{- with resources.Get "js/bundle.js" }}
{{- end }}

Typescritpを導入したPR:https://github.com/yuhi-sa/tomatohugo/pull/1

Reactを導入

必要なライブラリをインストールする。

npm install --save react react-dom
npm install --save-dev @types/react @types/react-dom

以下のようにReactコンポーネントを記述する。 Reactでは、JSX(JavaScript XML)と呼ばれる構文を使用してコンポーネントを記述するため拡張子をassets/ts/main.tsxに変更する。

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  return (
    <div>
      <h1>Hello, React!</h1>
    </div>
  );
};

const appElement = document.getElementById('appElement');
if (appElement) {
  ReactDOM.render(<App />, appElement);
}

Reactコンポーネントを適当なHugoのテンプレートのhtmlファイルに組み込む。以下のようにReactコンポーネントを呼び出すコードを追加します

<main>
<div id="appElement"></div>
</main>

<!-- JavaScriptの読み込み -->
{{- partial "head/js.html" . -}}  

Reactコンポーネントをバンドルするために、Webpackの設定を更新する。 webpack.config.jsを以下のように変更します。

const path = require('path');

module.exports = {
  entry: './assets/ts/main.tsx', // ファイルの拡張子をtsxに変更
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/, // TypeScriptとJSのファイルを対象とする
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'], // 拡張子にtsxを追加
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'assets/js'),
  },
};

ローカルサーバーを起動して「Hello, React!」が表示されることを確認する。

hugo server

Reactを導入したPR:https://github.com/yuhi-sa/tomatohugo/pull/2

Tags: