UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Next.js】styled-componentsからcss-modulesに書き換えてみた

先日、Next.jsで styled-components から linaria に書き換えてみることを行なったが、本番環境での利用は不安だったの一時中断した

uga-box.hatenablog.com

なので、今度はNext.jsがサポートしている css-modules に書き換えることを試してみた

nextjs.org

公式にサポートしているので特にインストールは不要

私はIntelliJを使っているからか、補完も特に設定なしでされているので導入はすぐだった

sassへの対応は以下を参照した

Styling: Sass | Next.js

next.config.js に次の記述を追記する

module.exports = {
  ...
  sassOptions: {
    includePaths: [path.join(__dirname, "styles")],
  }
}

これで sass への対応も完了した

マイグレーション

styled-componentsで書かれた既存のスタイルはあるので、これをうまく置換してsass に変換する

行なった手順はまず、styled-componentsでは以下のように書かれているので、

export const Container = styled('div', props)`
   color: red;
`

これを以下の正規表現を使って置換した

function convert2Kebab(val) {
  return String(val)
    .match(
      /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g
    )
    .map(x => x.toLowerCase())
    .join('-')
}

function convert2Css(val) {
  return String(val)
    .replace(/export const (.*) = styled.*`/g, (x, p1) => `.${convert2Kebab(p1)} {`)
    .replace(/`$/g, "}")
}

そして、置換したものを style.module.scss に記載するようにした(ある程度自動化)

css側はうまくいったが、jsx側は<Wrapper>だったものを<div>にする必要があり、これはうまいやり方が思いつかなかった

結局、元のやつを参照しながら手で移植したのだがミスがありそうで怖い(テストをしっかりやらねばと思う)

とりあえずこれでマイグレーションは完了した

参考

Next.js+TypeScript+CSS Modules+SCSS環境(2022.01)

WAI-ARIA 準拠には CSS Modules が最適という話