Freshで静的サイトを作る
はじめに
ただ、少し工夫をすると、静的なWebページを作れるのではないかと思い、試してみました。
前提
やりたいこと
Markdownのレンダリングはroutes/index.tsxでカスタムハンドラを用意して行っています。 code:routes/index.tsx
import { Head } from "$fresh/runtime.ts";
import type { Handlers, PageProps } from "$fresh/server.ts";
const gfmStyle = `
.markdown-body ul { list-style: disc }
.markdown-body a { color: teal }
${CSS}`;
export const handler: Handlers = {
async GET(req, ctx) {
// README.mdをHTMLへ変換します。
const url = new URL("../README.md", import.meta.url);
const markdown = await Deno.readTextFile(url);
const content = renderGFM(markdown, {});
// 下記のIndexコンポーネントをレンダリングします。
return ctx.render(content);
},
};
export default function Index(props: PageProps<string>) {
return (
<>
<Head>
<title>Awesome Fresh</title>
<style id="gfm">{gfmStyle}</style>
</Head>
<main
data-color-mode="auto"
data-dark-theme="dark"
class="p-4 mx-auto max-w-screen-md markdown-body"
dangerouslySetInnerHTML={{ __html: props.data }}
/>
</>
);
}
code:build.ts
// Fresh v1.1.5時点では、DENO_DEPLOYMENT_IDの有無によって本番or開発環境の判断が行われます。
// ここでは、本番環境と同様の方法でレンダリングを行ってほしいため、手動でDENO_DEPLOYMENT_IDを設定しています。
const { stdout: gitOutput } = await new Deno.Command("git", {
}).output();
const revision = new TextDecoder().decode(gitOutput).trim();
Deno.env.set("DENO_DEPLOYMENT_ID", revision);
// Freshのサーバを起動します。
import("./main.ts");
await new Promise((ok) => {
setTimeout(ok, 100);
});
// HTMLを取得するために、FreshのサーバへHTTPリクエストを送信します。
if (!res.ok) {
console.error("Failed to fetch /");
Deno.exit(1);
}
// 取得したHTMLをbuildディレクトリへ出力します。
const html = await res.text();
const buildDir = new URL("./build", import.meta.url).pathname;
await Deno.mkdir(buildDir, { recursive: true });
await Deno.writeTextFile(${buildDir}/index.html, html);
Deno.exit(0);
code:yaml
# 省略...
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.event_name == 'push' }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
その他、工夫した点
code:lint.js
import { default as awesomeLint } from "npm:awesome-lint@0.18.2";
await awesomeLint.report({ filename: "README.md" });