vercel/commerceのソースコードからNextjsのプラクティスを学ぶ
はじめに
昨日の記事はmizchiさんの2021年 は Fullstack Next.js 元年なので、有望な Next.js 系フレームワークを全部試したでした。
Svelte系には私個人としても興味があり、来年くらいには一度使ってみたいです。
本日の記事は、
SSRやSSG, ISRなどの盛り上がりを見せているNextjsにおいて多くの有用な記事が出ており勉強になる部分が多くあるのですが、一方でそれらをどう実装するのがよいのか、という点に関して論じている記事があまり多くはみられないと思ったため、
『公式はどう実装をしているのか』という観点から実装のプラクティスを学んでみようという記事です。
本編
Nextjsのversion10の発表に伴って紹介された、Next.js Commerceのソースコードの表示速度が爆速で、何かしら参考にできないかと思いましたので、本記事ではNextjsに関する部分を中心にいくらかをピックアップして紹介していきます。
※なお、bigcommerceに依存する部分のコードについては触れません。
Nextjs関連系
ui/context.ts
このファイルでは、
-
Link
サイドバーの開閉
,トーストの表示
,モーダルの表示
などをtype Action
で定義し、 - Link React.createContextにて状態をグローバルで管理し、
- Link uiReducerという名前で変更を実態を定義し、
- Link UIProviderから触ることができるようにしています
これにより例えば、ログインをしていない状態において『サインアップを促すモーダルやトーストを表示するということがどの画面からでもできる』ようになります。
SSG関連のコード
getStaticProps
は多くの箇所で用いられていますので、それらをご確認ください。
実は前のバージョンのコードでは、index.tsx
ではfeaturedのコードはHome関数の中に入っていたのですが、現在はgetStaticPropsの中に入っています。
これをすることにより、データフェッチに直接は関連しませんが、featuredの商品もSSGで整理されるため、毎回クライアント側でfeaturedの商品を並べることがないようにしています。
処理としては非常に負荷の小さい部分ではありますが、重要なコードであるように思います。
そのまま流用できそうなコード
MITライセンスのため、どんどんいいとこどりをしていくと良いと思います。
useCookie
Cookieを許容しますか、の部分についてのコードです。
- 定義箇所:https://github.com/vercel/commerce/blob/master/lib/hooks/useAcceptCookies.ts
- 利用箇所: https://github.com/vercel/commerce/blob/master/components/common/FeatureBar/FeatureBar.tsx
Skeleton
Skeletonとは、例えばDBからフェッチをしてくる文言や画像、広告などは読み込まれるまでに時間がかかりますが、それのプレイスホルダーのようなものです。
InstagramやTwitterで読み込み中に出てくるものというのがわかりやすいでしょうか。
- 定義箇所:https://github.com/vercel/commerce/blob/master/components/ui/Skeleton/Skeleton.tsx
- 利用箇所: https://github.com/vercel/commerce/blob/master/pages/search.tsx
色系
#ffffff => (255,255,255)
を実現するhexToRgb
やisDark
が含まれます
簡易的なSEO対策+metaタグ
const Head: FC = () => {
return (
<>
<DefaultSeo {...config} />
<NextHead>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="manifest" href="/site.webmanifest" key="site-manifest" />
</NextHead>
</>
)
}
export default Head
地味だけど知っておくとよさそうなこと
- useRouterでlocaleの設定ができる 該当コード
const { locale = 'en-US' } = useRouter()
// 他にも、urlを文字列でとるときは以下のような書き方ができる
const router = useRouter()
const { asPath } = router
- first viewでメインじゃない箇所はdynamic importをする [該当コード](###
https://github.com/vercel/commerce/blob/master/components/common/Layout/Layout.tsx#L24)
const dynamicProps = {
loading: () => <Loading />,
}
const LoginView = dynamic(
() => import('@components/auth/LoginView'),
dynamicProps
)
おわりに
実はnext10発表当日にgit cloneをしていたのですが、そこではreact-aria
などのサードパーティUIライブラリなどが使われていた(この記事の初稿には入っていた)のですが、ふとmaster branchをマージをしたところ使われていなくなっていました。
おそらく、今後も継続的によりよいコードに書き換えられていくと思いますので、公式の例はしっかりとみておこうと思いました。
あと最後に、commerce/pages/[...pages].tsxが何の役割を持っているのかがわからなかったので、分かる方はコメントにて教えていただけますと嬉しいです。
Discussion
本家のコードが移動したのか分かりませんが結構リンク死んでました。
v13へ移行のせいかもですね。