posted: 2019/12/02

Gatsby + netlify から next.js + zeit/nowに乗り換えようと試みて(未遂)得られた知見

※ この記事はNext.js Advent Calendar 2019 二日目の記事です

現在ご覧のブログは Gatsby で動いているのだが、色々とカスタマイズしていくうちにちょっとずつしんどくなってしまいそうな気配もあり、next.js への移行を検討してみた。
今の所サスペンドしてしまってるものの、色々と知見は溜まったのでここに供養としたい。
なお、一部はすでに記事化しており単なるリンクになっていることはご了承いただきたい。

ビルド周り

@babel/envを外す

<Document>を利用するとClass constructor Document cannot be invoked without 'new'が出た。
これの回避として@babel/envを外した

build コマンド

ビルドコマンドは下記のように変更
"build": "next build && nex export"
outディレクトリが吐き出し先になったので、netlify.tomlなども下記のように変更している
[build]
  publish = "out"

ForkTsCheckerWebpackPlugin を外す

個人的にビルド時に型チェックされる挙動がどうにも気持ち悪かったので外した。
詳しくはこの記事を参照

環境編

Gatsby -> now.sh への載せ替え

asset ファイルの取り扱い

static ファイルを移動するのが筋っぽいが、とりあえず今回はnext-imagesを使った。

アプリ編

gatsby-transformer-remark を react-markdown へ置き換え

gatsby-link -> next/link

予めLinkコンポーネントをラップしておくと以降が楽で良い
内容としてはこういう変更
// before
import Link from "gatsby-link"
<Link to={"/"}>
// after
import Link from "next/link"
<Link href={"/"}>
あと、styledしていた部分は変更の必要があった
// before
const Logo = styled(Link)
<Logo to={"/"}>
// after
const Logo = styled.span
<Link href={"/"}>
  <Logo>

styled-components のままnext.jsに対応する(ボツ)

dev で hot reload 時に styled-components が死ぬので
with-styled-componensの例を見ながら追加した
$ yarn add babel-plugin-styled-components
  "plugins": [["styled-components", { "ssr": true }]]
styled-components で next.js 対応をする場合、_document.jsに手を加えないと初期レンダリングがされなかった。
const getSheet = async ctx => {
  const sheet = new ServerStyleSheet()
  const originalRenderPage = ctx.renderPage

  try {
    ctx.renderPage = () =>
      originalRenderPage({
        enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
      })

    return sheet.getStyleElement()
  } finally {
    sheet.seal()
  }
}

class AppDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    const sheet = await getSheet(ctx)
    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          {sheet}
        </>
      )
    }
  }
  // ...

styled-components から emotion にする

と、上記をやって「いやこれシンドい・・・・」という気持ちになり、emotion に載せ替えた
SSR はキレイに処理してくれた。置換は必要だが@emotion/styledにすればほとんどそこだけで済むのでちょっと手間という程度で済んだ。
また、babel plugin は下記のように追加した
 "plugins": [
    "emotion"
  ]

まとめ

現状、おそらく切り替えようと思えばできる、という状況だが、下記の理由などで頓挫している
  • Canonical処理などいくつかのプラグインの引き継ぎがめんどい
  • わりと色々やったおかげでGatsbyのペインがマシになった
  • staticに吐くのが面倒
  • staticに吐かなかったら吐かなかったでnow.sh依存になるのが判断悩ましい
ただ今回のGatsbyへの依存を減らす試み自体は結果としてdevelop時/release時のビルドスピート向上にも繋がり、とても有意義だったと感じる。
また、最近Gatsbyを触るとまた重さを感じることが増えてきたので、気が向いたら再度トライしてみたい
Edit on Github