QLITRE DIALY

チュートリアルを書く時に考えること

2022年07月19日

さいきん、Next.jsのブログ作成をするのが楽しい。

Next.jsについて

Next.jsはReactがベースとなったフレームワークだ。

この日記サイト自体も以前はNuxt.jsで運営していたのだけど、最近になってNext.jsベースに作り替えた。

React自体は触ってみて、ちょっと、とっつきにくいよなぁ、という感想だったのだけど、Next.jsは非常に分かりやすいというか、気持ちよく開発を進めることができる。恐らくそのとっつきにくさは、Vueでのコーディングに慣れてる自分にとって、あまりにもReactが違いすぎるから。

Nextが開発を気持ちよくできるのは、それがフレームワーク化した時に、枠組みの部分がNuxtのやり方と似ているため、すっと入ってくる部分があったんだろう。

どちらもJamstack構成でのデプロイが可能で、例えばページング処理をした場合の静的生成の記述が似ている。

Nuxt.jsでは、nuxt.config.jsに以下のように書く。

generate: {
  fallback: true,
    async routes() {
    const limit = 10
    const range = (start, end) => [...Array(end - start + 1)].map((_, i) => start + i)
    // 一覧のページング
    const pages = await axios
      .get(`${API_URL}/post?limit=0`, {
        headers: {
          'X-MICROCMS-API-KEY': API_KEY
        },
      })
      .then((res) =>
        range(1, Math.ceil(res.data.totalCount / limit)).map((p) => ({
          route: `/page/${p}`,
        }))
      )
  }
}

Next.jsではgetStaticPaths関数を使用して以下のようにすることで、静的ルートが生成される。

export const getStaticPaths: GetStaticPaths = async () => {
    const repos = await client.getList({ endpoint: "post" });
    const range = (start: number, end: number) => [...Array(end - start + 1)].map((_, i) => start + i);
    const paths = range(1, Math.ceil(repos.totalCount / BLOG_PER_PAGE)).map((repo) => `/page/${repo}`);
    return { paths, fallback: false };
};

記述方法に違いがあるが、本質的には同じことで、有りうる全てのpathを与えよ、なんである。

ReactとVueに違いは大きいけれど、こういった枠組みの考え方は似ている部分が多いので、すっと入ってくる。

チュートリアルを書くことついて

というわけで、Next.jsでのブログがある程度形になってきたので、チュートリアル形式でプログラミングブログにまとめている。

【まとめ】Next.js, microCMS, Chakra UIで作るブログ

自分がチュートリアルを書く時はまずサービスを作って、次にそのサービスを手順通りにまとめていくという流れで行う。

サービスというと少し大げさな気がするが、この場合はブログサイトのことを指す。

チュートリアルという表現も少し仰々しいというか、おこがましいという感じがしていて、レベル的には備忘録と言った方が近いかもしれない。

当然、レベルという物はあるのだけど、この一連の営みの中で気づかされることも多い。

言ってしまえば、「同じものをもう一回つくる」ということなのだが、不特定多数を意識した記事にまとめることで「ちょっとカッコよくみせたいな」という気持ちが生まれる。

プログラミングでいえば、変数の命名とかを考え直すことが多い。自分で作っていると、どうしても名前付けが適当になってしまうからだ。

例えば以下の処理は、チュートリアルで紹介しているページネーションコンポーネントの記述だが、getPaginationItem関数は当初getElement

という命名にしていた。

export const Pagination = ({ totalCount, tagId, currentPage = 1 }: Props) => {
    const getPath = (p: number) => {
        if (tagId) return `/tags/${tagId}/page/${p}`
        return `/page/${p}`
    }
    const getPaginationItem = (p: number) => {
        if (p === currentPage) {
            return <Text fontSize="3xl" color="gray.700">{p}</Text>
        }
        return <Link href={getPath(p)} fontSize="3xl" color="gray.400">{p}</Link>
    }
    const range = (start: number, end: number) =>
        [...Array(end - start + 1)].map((_, i) => start + i)
    return (
        <HStack spacing='10' justifyContent="center">
            {range(1, Math.ceil(totalCount / BLOG_PER_PAGE)).map((number, index) => (
                <Box key={index}>
                    {getPaginationItem(number)}
                </Box>
            ))}
        </HStack>
    );
};

別にgetElementでもコードは動くし何も問題がないのだけど、この名前だと、getElementByIdが想起されて DOMの中から特定の要素を探しているような印象を受ける。

チュートリアルを書いていて、こういうことを考えて、もう少し具体的にgetPaginationItemという名前に変えた経緯がある。

他にも、ここの部分はコンポーネントとして切り出した方がいいかな、とか、でも、そこまでの塊ではないかな、とかいろいろなことを考える。

一見同じことを繰り返しているだけだが、テキストで、人に伝える形でまとめ直すことで、ソースコードについて再考、再認識をすることができるわけだ。

これはプログラミングに限らずあらゆる事象にも適用できるメソッドかもしれない。

仕事の手順でも、自分のルーティンとなっている生活についてでもいい。

ある完成されていると思われているもの、そう錯覚しているもの、それをもう一回やり直しながら、文字に書き起こしていく。

その中で新しい考えや改善が生まれるかもしれない。