SUBMONTANE STUDIOができるまで(選定編)

JavaScript

前回から少し間が空いてしまい、申し訳ありません…。
気を取り直して、前回に引き続き、「SUBMONTANE STUDIOができるまで」と称して今回のサイト立ち上げに際してのあれこれをご紹介していきます。
今回で最後まで書き終わる予定だったのですが、思った以上に長くなったため、どんな技術を使ったのかと、それを選んだ理由を説明する部分で一旦区切ることにしました。

採用した技術

以下の文章はその技術を採用した理由を説明するものであり、他の技術を否定するものではありません。

ディレクション時からJavaScriptフレームワークとしてReactNext.jsを採用することを前提としていました。以前試験的には導入していたTypeScriptも今回から本格的に導入しました。

なぜReactとNext.js?

近しいJavaScriptフレームワークには、GoogleのAngular、コミュニティ主導のVue.js + Nuxt.jsがあります。特にVue.jsとNuxt.jsはフレームワークの性質としてかなり似ているので、比較対象になりやすいです。

では、なぜReact + Next.jsを採用したのか、まず以下のグラフをご覧ください

圧倒的ではないか…React軍は…

上記のグラフは、Node.jsというJavaScript実行環境上で動作するパッケージマネージャーnpmでのパッケージのダウンロード数を表したグラフ(参照 : npm trends)です。ここ5年で指定して表示してみましたが、一部を除いて終始Reactが優勢となっていることがわかります。
(2022年12月ごろに急にVueのダウンロード数が上がり、年末にまた下がっているように表示されているようですが、これはnpm trendsのバグだそうです)

Googleによる検索数を表したGoogle Trendsの結果を見ても、

世界の検索数で見るとnpm trendsとほぼ同じ、 日本に絞ってみても

2021年の終わりごろからReactが優勢な状況が続き、現在はその差が開いているように見えます。

このように、利用者数が圧倒的にReactの方が多いことが今回の採用の決定的要因になりました。 中・長期的に使えるフレームワークとしても、Reactは頭一つ抜けている印象です。

React Hookの導入

私がReactについて学び始めた最初期辺りかその直前だと思いますが、ReactにReact Hookという機能が導入されました。

従来クラスコンポーネントでしか利用できなかった入力やstate(現在の状態)の管理、変数の受け渡しなどの機能を関数コンポーネントで利用できるようにする機能です。

クラスコンポーネントはJavaScriptのclassという構文をベースとしたコンポーネント(部品)の記述方法で、関数コンポーネントに比べ、とっつきにくい・長文になりがちな記述方法で、React Hookの導入によってクラスコンポーネントを書かなくてはならない場面がほぼなくなり、Reactそのものへのとっつきやすさがかなり高まりました。

もともと、Vue.jsに比べてReactは難しいというイメージだったのですが、この機能によって敷居がぐっと低くなっています。

AstroではなくNext.jsにした理由

Next.jsの競合として、Astroがあります。 AstroはNext.jsのようにReactに依存するのではなく、Vue.jsやSvelteのようなフレームワーク上で動く上、ウェブコンポーネントとして直接ブラウザ上で動かすこともできます。
Next.jsとの比較として、ReactのJSX構文ではなく、フロントエンドの分野で慣れ親しんだHTMLの構文を使用することができます。
その上、より簡易的な書き方のMarkdown構文を使用することもでき、テンプレートエンジンの柔軟性はNext.jsより一歩、二歩進んでいます。

じゃあなぜAstroではなくNext.jsを採用したかというと、歴史の長さです。

Next.jsとAstroの歴史

Next.jsは7年前の2016年10月26日に1.0.0がリリースされていますが、Astroは2年ほど前の2022年8月9日のリリースです。
より新しいのはAstroですが、npm trendsを見ても、高い水準をキープしているNext.jsに比べ、着実にDL数を増やしてはいるようですが、まだまだ横ばい気味で本格的な普及期に入っているとは言えなさそうです。

関連書籍もAstroはまだ決して多くはありません。 個人的な印象としては、現段階ではNext.jsをマスターした上で学ぶべき技術であり、もう少し成長の様子を見たいフレームワークです。

TypeScriptを導入した理由

これについては、最初期には導入するつもりはありませんでした。

理由は、いつも1人でコーディングが完結してしまうから

フリーランスで働いている特性上、小・中規模の案件であればコーディングパートは私だけ、ということが多く、「型付けしたって結局触るのは自分なんだからTypeScriptなんていらんわい!」といろいろ間違った認識でいました。

実際、試験的にWordPressのテーマ作成案件でスクリプト部分をTypeScriptで書いたりもしましたが、その時点では恩恵を感じたとは言い難かったです。

ですが、React/Next.jsを導入するにあたり、何冊か読んだものの多くがTypeScriptをベースにしたもので、ネット上にあるコードにもTypeScriptのものが多く、否応無く導入せざるを得ませんでした。

(元々ブラウザ対応の為にBabelでコンパイルしていたのが、Babelの雲行きが怪しくなってきたのも一因です)

導入した結果

快適です!なんで使ってなかった自分!?

たしかに、DOMにaddEventHandlerなどでイベントを付けていく、というイベント処理がメインだった今まではありがたみを感じにくいのです。
しかし、ReactやNext.jsのようにfetchでAPIのデータを取ってきたり、別コンポーネントにデータを渡すといった少し複雑化したコードだと、やりとりしたデータがただの配列なのか連想配列なのかわかりにくかったりする場合が多く、型を前もって指定することで「ブラウザで動かしてやっとエラーに気づく」ということが大幅に減り、書いた時点(保存した時点)でエラーを吐いてくれるようになるので、だいぶコーディングがスムーズにできるようになりました。

副操縦士どころじゃないGitHub Copilot

今回TypeScriptと共に大活躍したのが、JavaScriptの構文をチェックしてくれるESLintBiome、そしてGitHub Copilotです。 使用しているVisual Studio Codeは同じMicrosoftというだけあってか、かなりガッチリ連携しており、エラー部分のアイコンをクリックすれば、エラーの説明や修正をAIの力で簡単に行なってくれます。ぶっちゃけていうとSUBMONTANE STUDIOのコード全体の1割くらいはGitHub Copilotくんが書いてくれたといっても過言ではありません。

「こういう実装したいんだけどどういう書き方をすればいいんだ?」という時にはCopilot Chatで聞けば、だいたい答えてくれます。(その通りに書いても動かないこともままありますけども…)

個人アカウントで月々$10、ビジネス用のGitHub Copilot Businessだと月々$19払う必要がありますが、短縮できる時間を考えれば十分元が取れるお値段です。

スタイリングツール

React/Next.js上でサイトの見た目を定義するスタイリングツールとしては、

があります。

グローバルCSSは今までのノウハウがそのまま使えますが、Reactで使用するうまみはありません。

CSS in JSは

import React from 'react';

import styled from 'styled-components';

// Create a <Title> react component that renders an <h1> which is
// centered, palevioletred and sized at 1.5em
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// Create a <Wrapper> react component that renders a <section> with
// some padding and a papayawhip background
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

function MyUI() {
  return (
    // Use them like any other React component – except they're styled!
    <Wrapper>
      <Title>Hello World, this is my first styled component!</Title>
    </Wrapper>
  );
}

のような感じでHTMLタグの種類とスタイルを定義して変数名をJSXの要素として書き込みます。

Tailwind CSS

<figure class="md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-slate-800">
  <img class="w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto" src="/sarah-dayan.jpg" alt="" width="384" height="512">
  <div class="pt-6 md:p-8 text-center md:text-left space-y-4">
    <blockquote>
      <p class="text-lg font-medium">
        “Tailwind CSS is the only framework that I've seen scale
        on large teams. It’s easy to customize, adapts to any design,
        and the build size is tiny.”
      </p>
    </blockquote>
    <figcaption class="font-medium">
      <div class="text-sky-500 dark:text-sky-400">
        Sarah Dayan
      </div>
      <div class="text-slate-700 dark:text-slate-500">
        Staff Engineer, Algolia
      </div>
    </figcaption>
  </div>
</figure>

のように、クラスに専用のクラス名を書いてスタイリングするCSSフレームワークです。 昔のBootstrapをさらに細分化させたような感じですね。 @apply機能を使用することでクラスをまとめること(ただし、公式では**「多用は非推奨」**とされているようです)ができたり、tailwind.config.jsで詳細な設定を行うことが可能なのがBootstrapとの違いでしょうか。

CSS Modulesは、

import styles from './styles.module.css'
 
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section className={styles.dashboard}>{children}</section>
}

のように読み込んだ上で、.module.css拡張子のCSSファイルに

.dashboard{
  padding: 24px;
}

と書くことで、

.[ページ名]_dashboard__[ランダムなハッシュ値]{
  padding: 24px;
}

のような形のユニークなクラス名に変換してくれる機能です。 この機能の何が便利かというと、

  • CSSにスコープを導入できる (そのページにだけ有効なスタイルを、スタイル衝突の心配なく使用できる)
  • コンポーネントごとにスタイルを定義することで、どのスタイルがどのコンポーネントで使用されているのか、依存関係が明確化できる
  • クラス名を再利用できるので、heading01やheading02などの連番や_primary、_secoundaryなどの命名法で気を使う必要がない

といったメリットがあります。

さらに、Next.jsが推奨しているという点が大きく、今回はCSS Modulesを採用しました。

今まで無いと困るレベルで使っていたSASSも、意識することなく組み込めます。

ヘッドレスCMSの選定

今回はブログを導入する予定だったため、ブログシステムを選定する必要がありました。

できればクライアントワークでも使えるよう、英語の苦手なクライアントにもおすすめできるよう、日本語対応なのが望ましいと思います

主なヘッドレスCMSとしては、

なとなど多くのものがありますが、Contentfulは日本語非対応なので、実質下の2つのどちらか、となります。

ちなみに、上記以外にも自分でレンタルサーバーやVPSに設置して使用するセルフ・ホスティング型のヘッドレスCMSもあります(DecapStrapiなど。CMSとして有名なWordPressもヘッドレス化できます)が、メンテナンスのコストを考えてクラウド型のものを選択してます。

結論として、今回はmicroCMSを選びました。

以前テストとして作った極シンプルなブログページで使用したヘッドレスCMSがこれで少ないながらもノウハウのあるこちらにしました。

Newtが特に劣っているから等の理由ではないので、Newtの方が魅力的らしいぞ、となれば乗り換えるかもしれませんし、Contentfulが日本語対応してくれれば乗り換える可能性もあります。(なので、今回はmicroCMS提供のSDKを使わないなど依存性を低くしてどんなCMSでも最小の変更で使えるようにしています。)

ホスティング

Next.jsで制作したサイトは、当然ながらサーバーへアップロードする必要があります。 通常のサーバーでもNode.jsの機能を使わずNext.jsで静的にエクスポートすればホスティングは可能ですが、Next.jsなどの静的サイトジェネレーターでは静的サイトホスティングサービスを使用することで、アップロードの手間を省くことができます。

静的サイトホスティングサービスとしては以下が有名です。

今回の決め手としては速度とコストです。 Netlifyは日本にノードサーバーがないらしく、比較記事などを見ても日本国内では他と比べて遅いです。 コストの点では、できるだけ初期投資のコストは低く抑えたいので、無料のプランから始めて接続量や使用量によって上のプランへ移行というのがベストと考えていましたが、AWS Amplifyは従量課金なので外しました。(従量課金だと不意に膨大な課金が来るリスクも怖い…) VercelはNext.jsの開発元で、速度的にも問題はないのですが、無料プランは商用利用不可ということなので断念。 残るはFirebase HostingとCloudflare Pagesですが、Firebase HostingはGoogleが提供しており、メール環境などもGoogle Workspaceを使っているので、あまりに依存しすぎないか?という不安からCloudflare Pagesにしました。Cloudflareの強力なCDNが無料で使えるのも魅力です。

選定した技術たち

というわけで、今回選んだのは

言語 : TypeScript
フレームワーク : React
SSG/SSR : Next.js
スタイリング : CSS Modules
ヘッドレスCMS : microCMS
ホスティング : Cloudflare Pages

とこんな感じになりました。

各技術を選び終わったので、ようやく実際のコーディングです。 次の記事ではざっくりとどんな形の実装になったかをご説明しつつ、私がつまずいて七転八倒する様もお届けします。

記事一覧へ戻る

お見積り・お問い合わせこちら

お困りの際は、お気軽にご相談ください
お問い合わせはこちらからお願いいたします

お問い合わせ