LoginSignup
2
2

More than 3 years have passed since last update.

【Deno】静的サイトジェネレータpagicを使ってお手軽サイト生成

Last updated at Posted at 2020-07-19

はじめに

この記事ではpagicというDenoモジュールを使って静的サイトを作成する方法を紹介します。

pagicとは

DenoとReact及びmarkdownを使って静的サイトを生成するツールです
https://github.com/uki00a/blog にて簡単なブログを作成してみたため、興味があればご覧ください。

注意点

pagicはまだメジャーリリースされていません。
そのため、この記事で紹介した方法は、将来的に動作しなくなる可能性があります。

前提

この記事は以下のツールを使用して動作を確認しています。

ツール バージョン
Deno v1.2.0
pagic v0.7.30

セットアップ

$ deno install --unstable --allow-read --allow-write --allow-net --name pagic -f https://deno.land/x/pagic@v0.7.30/mod.ts

基本的な使い方

以下のようなディレクトリ構成を想定して話を進めていきたいと思います。

src/
├── _deps.tsx
├── _layout.tsx
└── index.md

各依存モジュールをsrc/_deps.tsxで管理します。

src/_deps.tsx
// @deno-types="https://deno.land/x/types/react/v16.13.1/react.d.ts"
import React from "https://dev.jspm.io/react@16.13.1";
export { PagicLayout } from "https://deno.land/x/pagic@v0.7.30/mod.ts";

export { React };

次にsrc/_layout.tsxでページのレイアウトを定義します。
このファイルでdefault exportされたコンポーネントがレイアウトとして使用されます。

src/_layout.tsx
import { React, PagicLayout } from "./_deps.tsx";

const Layout: PagicLayout = ({ title, content }) => (
  <html>
    <head>
      <title>{title}</title>
      <meta charSet="utf-8" />
    </head>
    <body>{content}</body>
  </html>
);

export default Layout;

最後にsrc/index.mdを用意します。
このように、pagicでは記事をmarkdownで記述できます。

src/index.md
# Hello Pagic!

Hello

それではビルドしてみます。ビルドする際は、pagic buildコマンドを使います。--serveオプションを付与すると、ビルドの完了後、http://127.0.0.1:8000のURLからページを確認することができます。

$ pagic build  --serve

ビルドが完了すると、publicディレクトリが作成されます。

public/
├── assets/
|   ├── index.css
|   ├── reset.css
|   └── variables.css
├── _layout.js
├── _deps.tsx
├── favicon.ico
├── index.html
├── index.js
├── index_props.js
├── index.md
└── pagic.config.js

ブラウザからhttp://127.0.0.1:8000にアクセスして内容を確認してみましょう。

以下のように表示されれば成功です。

pagic-sample.png

ページを追加する

次にページを追加してみます。

まず、以下のコマンドを実行しましょう。--watchオプションを付与することで、ソースに変更があった際に自動でリビルドしてくれるため、作業効率が上がります。

$ pagic build --watch --serve

次に以下のようなmarkdownファイルを用意してみます。

src/sample-1.md
# Sample 1

テスト

ページにヘッダをつけてみます。

pagicでは画面のパーツをReactコンポーネントとして定義できます。
src/_header.tsxというファイルを作成し、ヘッダを用意します。

src/_header.tsx
import { React } from "./_deps.tsx";

const Header = () => (
  <header className="header">
    <div>
      <a href="/">TOP</a>
    </div>
  </header>
);

export default Header;

CSSファイルも用意してみます。

src/assetsディレクトリを作成し、その中にindex.cssを用意します。

src/assets/index.css
.header {
  z-index: 100;
  background-color: lightgray;
}

作成したCSSファイルとヘッダを読み込むよう_layout.tsxを変更しましょう。

src/_layout.tsx
import { React, PagicLayout } from "./_deps.tsx";
import Header from "./_header.tsx";

const Layout: PagicLayout = ({ title, content }) => (
  <html>
    <head>
      <title>{title}</title>
      <meta charSet="utf-8" />
      <link rel="stylesheet" href="assets/index.css" />
    </head>
    <body>
      <Header />
      <main>
      {content}
      </main>
    </body>
  </html>
);

export default Layout;

それではブラウザからhttp://localhost:8000/sample-1.htmlを開いて内容を確認してみましょう。(マークダウンのファイル名を元にパスが決定されます)

pagic-example2.png

もしコンパイルエラー等が発生し、サーバが停止していてたら、それらのファイルを修正してみてください。その後、pagic build --serveを実行すればうまく表示されると思います。

記事に作成日等のメタデータを定義したい

記事にメタデータを設定したいときは、markdownファイルの先頭で定義します(front matterというそうです)

---
publishedAt: 2020-07-18
updatedAt: 2020-07-19
---

# Sample 1

テスト

このように定義しておくと、Layoutコンポーネントにpropsとしてそれらのメタデータが渡されるようになります。

src/_layout.tsx
const Layout: PagicLayout = ({ title, content, publishedAt, updatedAt }) => (
  <html>
    <head>
      <title>{title}</title>
      <meta charSet="utf-8" />
      <link rel="stylesheet" href="assets/index.css" />
    </head>
    <body>
      <Header />
      <main>
      {content}
      </main>
      <div>作成日: {publishedAt ? publishedAt.toString() : ""}</div>
      <div>更新日: {updatedAt ? updatedAt.toString() : ""}</div>
    </body>
  </html>
);

設定

pagic.config.tsファイルを作成することで、pagicの挙動をカスタマイズできます。
pagicのデフォルトの設定は下記のようになっています。
プロジェクトルートにpagic.config.tsを作成しておくと、デフォルトの設定にマージされます。

// pagicのREADME.mdより引用
/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2017-present, xcatliu
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
 * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 
 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
export default {
  srcDir: '.',
  outDir: 'dist',
  include: undefined,
  exclude: [
    // Dot files
    '{,**/}.*',
    // Node common files
    '{,**/}package.json',
    '{,**/}package-lock.json',
    '{,**/}node_modules',
    // pagic.config.ts and pagic.config.tsx
    'pagic.config.{ts,tsx}',
    // https://docs.npmjs.com/using-npm/developers.html#keeping-files-out-of-your-package
    '{,**/}config.gypi',
    '{,**/}CVS',
    '{,**/}npm-debug.log'

    // ${config.outDir} will be added later
  ],
  root: '/',
  theme: 'default',
  plugins: ['clean', 'init', 'md', 'tsx', 'script', 'layout', 'out'],
  watch: false,
  serve: false,
  port: 8000
};

GitHub Pagesにページを公開する

pagicで作成されたページをGitHub Pagesで公開してみます。

まず、GitHubでGitリポジトリを用意します。
こちらにリポジトリを用意してみたのでそちらも参考にしてみてください。

次にGitHub Actionsの設定を行います。
リポジトリに.github/workflows/build.ymlを作成します。

.github/workflows/build.yml
name: build
on:
  push:
    branches:
      - master
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - uses: denolib/setup-deno@master
      with:
        deno-version: 1.2.0
    - name: Build
      run: |
        deno run --unstable --allow-read --allow-write --allow-net https://deno.land/x/pagic@v0.7.30/mod.ts build
    - name: Deploy
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./public

これでmasterブランチへコミットするたびにpagicによるビルド及びpeaceiris/actions-gh-pagesアクションによるgh-pagesブランチへの公開が行われるようになります。

公開されたサイトは https://<ユーザ名>.github.io/<リポジトリ名>/で確認できます。
(私の場合、https://uki00a.github.io/blog/ でした)

GitHub Pagesへの公開がうまくいかない場合

こちらのページFirst Deployment with GITHUB_TOKENに記載されているとおり、GITHUB_TOKENを使ったデプロイにはどうも制限があるようです。

私も以下の手順を踏むまではページの公開がうまく行きませんでした :sweat_smile:

  1. GitHub Actionsのセットアップ後、masterブランチへpushする
  2. リポジトリの「Settings」ページを開き、GitHub Pagesの設定欄からSourceブランチをgh-pagesからmasterへ変更する
  3. 再度masterブランチへpushする
  4. GitHub Actionsの実行完了を待つ
  5. 再度、リポジトリの「Settings」ページを開き、GitHub Pagesの設定欄からSourceブランチをmasterからgh-pagesへ変更する
  6. 再度masterブランチへpushする

この記事で紹介していない機能

この記事では紹介していませんが、pagicには他にも以下のような機能があります。

  • プラグインシステム
  • Reactコンポーネントで記事を書く

おわりに

以上、pagicとマークダウンを使ってサイトを生成する方法について紹介しました。
pagicには将来的にテーマ機能等も実装される予定のようです。
興味があれば、ぜひ試してみてください!

参考

2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2