Vercel、Remix、Prismicで個人ブログを作った。
本記事で作成したブログはこちらです。
なお、この記事は作成した個人ブログの方に投稿しておりましたが、Googleになかなかクロールしてもらえず悲しくなったため、Zennの方に投稿して読んでいただこうという魂胆です。
今後は作成したブログは一旦休止して、こちらで記事を投稿していく予定です。作った意味とは...
Remixでブログを作る
はじめに
Remixでブログを作った過程の記録です。新しい技術を使いたい一心でRemixを使用したため、技術的な話はない点にご注意ください。
使ったもの
- Remix
- Typescript
- Vercel
- Prismic
Remix
NextやGatsbyに代わる新しいReactのフレームワーク。
革新的な機能があるようですが、新しいという理由で採用したため、ここでは詳細に触れません。
Vercel
今回使用したホスティングができるサービス。
Netlifyを以前使ったことがあったため、別のサービスに挑戦ということで採用しました。ロゴがシンプルで好きです▲
Prismic
ヘッドレスCMSはたくさんあって悩みました。
Contentfulを触ったことがあるのですが、自分にはリッチすぎました。また、動作が少しもっさりな印象があったので別のサービスを探しました。
オープンソースであるGhostには惹かれましたが、別でホストするか有料プランを使う必要があります。今回は無料で済ませたかったため見送りましたが、今後使ってみたいです。
結果的に見た目がシンプルで、無料の範囲内で使用できるPrismicを使うことになりました。
本題
まずはプロジェクトを作ります。
npx create-remix@latest blog
作成するアプリケーションについて聞かれるので、答えていきます。
? **Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployment targets.**
> Vercel
? **TypeScript or JavaScript?**
> TypeScript
? **Do you want me to run `npm install`?**
> Yes
プロジェクトフォルダーに移動し、実行してみます。
Remix App Server started at <XXX> と表示されるので、XXXにアクセスすると作成されたアプリを見ることができます。
cd blog
npm run dev
gitの初期設定もしておきます。
git init
リント系(オプション)
個人の趣味のためのブログなので全く必要なかったかもしれませんが、とりあえず導入してみました。
commitlint
# Install commitlint cli and conventional config
npm i -D @commitlint/{config-conventional,cli}
# Configure commitlint to use conventional config
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
# Install Husky v6
npm i -D husky
# Activate hooks
npx husky install
# Add hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
eslint
npm i -D eslint
npx eslint --init
再びアンケートに答えます。
? **How would you like to use ESLint?**
❯ To check syntax, find problems, and enforce code style
? **What type of modules does your project use?**
❯ JavaScript modules (import/export)
? **Which framework does your project use?** …
❯ React
✔ **Does your project use TypeScript?**
❯ Yes
✔ **Where does your code run?**
❯ browser, node
? **How would you like to define a style for your project?**
❯ Use a popular style guide
✔ **Which style guide do you want to follow?**
❯ airbnb
? **What format do you want your config file to be in?**
❯ YAML
? **Would you like to install them now with npm?**
❯ Yes
Prettier
npm i -D prettier eslint-config-prettier
lint-staged
npm i -D lint-staged
"scripts": {
"lint-staged": "lint-staged",
...
},
"lint-staged": {
"*.{js,ts,jsx,tsx}": [
"npm run fix"
]
},
設定ファイル
設定は好みですが、ログのために自分の設定を残しておきます。
env:
browser: true
es2021: true
node: true
extends:
- plugin:react/recommended
- airbnb
- prettier
parser: "@typescript-eslint/parser"
parserOptions:
ecmaFeatures:
jsx: true
ecmaVersion: latest
sourceType: module
plugins:
- react
- "@typescript-eslint"
rules:
arrow-body-style: ["error", "always"]
prefer-template: "off"
import/extensions:
[
"error",
"ignorePackages",
{ "js": "never", "jsx": "never", "ts": "never", "tsx": "never" },
]
react/jsx-filename-extension: ["error", { "extensions": [".jsx", ".tsx"] }]
react/jsx-uses-react: "off"
react/react-in-jsx-scope: "off"
リンティング用のコマンドを追加
"scripts": {
"prepare": "husky install",
"format": "prettier --write 'app/**/*'",
"lint": "eslint --fix 'app/**/*'",
"fix": "npm run format && npm run lint",
"lint-staged": "lint-staged",
"build": "remix build",
"dev": "remix dev",
"postinstall": "remix setup node",
"start": "remix-serve build"
}
コミットの前にリントしてくれるように設定します。
npx husky add .husky/pre-commit "npm run fix"
本体の作成
Remixのチュートリアルページに、ブログの作り方が書いてあるので基本的にそれに従って進めていきました。
https://remix.run/docs/en/v1/tutorials/blog
但し、チュートリアルページでは、マークダウンファイルをそのまま読み込んでいるのでCDNを使ったやり方に書き換える必要があります。
Prismicの導入
Prismicはドキュメントがとても丁寧で、Next.jsやNuxt.js、Svelteなど、それぞれに対するチュートリアルが用意されています。なお、RemixはないのでReact.js用のチュートリアルを参考に導入します。
チュートリアルとは別に、Prismic関連のヘルパーもインストールしました。
npm i -S @prismicio/helpers
チュートリアル通りにprismic.ts(prismic.js) が書けたら、Remixのチュートリアルで作成したpost.tsを書き換えます。
import * as prismicH from "@prismicio/helpers";
import { client } from "./prismic";
export type Post = {
uid: string;
title: string;
};
export type PostMarkdownAttributes = {
title: string;
};
export async function getPost(uid: string | undefined) {
if (!uid) return { slug: "undefined", title: "undefined", text: "undefined" };
const document = await client.getByUID("post", uid);
const title = prismicH.asText(document.data.title);
const text = prismicH.asText(document.data.text);
const slug = document.slugs[0];
return { slug, title, text };
}
export async function getPosts() {
const documents: Array<any> = await client.getAllByType("post");
return documents.map((document) => {
return {
uid: document.uid,
title: prismicH.asText(document.data.title)
};
});
}
ここでの注意点です。
Remixのチュートリアルではslugが記事に対するユニークな値になっていますが、Prismicは一つの記事に対して複数のslugをつけることができます。そのため、uidというパラメータを代わりに使っています。それに伴い$slug.tsx
も$uid.tsx
に書き換えました。
Vercelへのデプロイ
RemixにはVercelにデプロイする方法が書かれているのでそれに従います。ただ、私はここで少しハマりました。
https://vercel.com/guides/deploying-remix-with-vercel
"Vercel for Git" と題して、GitHubにあるリポジトリをそのままVercelにデプロイする手順がありましたが、いくら試行錯誤しても404エラーでサイトが表示されませんでした。そのため、”Vercel CLI" という題で書かれている手順で行うと上手くできました。
その後は、GitHubにプッシュすると変更が反映されたので、まずは”Vercel CLI" に書かれている手順から順にする必要があったのかもしれません。
おわりに
これで「Remixでブログを作る」は以上となります。Remixの真価に何一つ触れていませんが、このブログを公開するだけで私は満足してしまいました。気が向いたらRemixと他のフレームワークとの比較についての記事も書こうと思います。最後に私がRemixに興味を持ったきっかけの動画を紹介します。
Discussion