技術とかの雑なToday I Learnedメモ

暫定的にシンタックスハイライト対応をした

Prism.js を不完全ながらひとまず導入した

Prism.js でシンタックスハイライトを行うようにする by tagucch · Pull Request #30 · tagucch/random.tagucch.dev

シンタックスハイライトに関して特に何も導入していなかったので、Prism.js というシンタックスハイライトのライブラリを8/19 の記事で導入しようとしたけど、ダークモードとの切り替えで挫折してストップしていたのでなんとかしようとして進めた。

ダークモードとの切り替え

Prism.js でシンタックスハイライトを行おうとして、まず_app.tsxで使いたい Prism.js の theme の CSS ファイルを import して、実際にシンタックスハイライトを行いたいページ(このサイトでいうと各記事のページの[id].tsx)の useEffect でPrism.highlightAll()を呼び出せばよい。

今回の場合はダークモードとライトモードで使う theme の CSS を出し分けたいので、_app.tsxで import する CSS ファイルをうまいこと条件分岐してできないかというところで悩んでいた。

import - JavaScript | MDN

dynamic import という機能を使えば分岐で import するモジュールを分けられそうだったが、どうも node_modules 内のライブラリを使用する import はできなさそうだった。

そこで、今回はimport 'prismjs/themes/prism-solarizedlight.css'とだけ書いたdark.tsと、import 'prismjs/themes/prism-tommorow.css'とだけ書いたlight.tsを用意し、それぞれをダークモードかライトモードに応じて dynamic import すればいけそう!と思ってやってみた。

_app.tsxでやろうと思ったんだけど、モード切り替えにnext-themesというライブラリを浸かっていて、現在のモードを取得するconst { theme } = useTheme()がコンポーネント内でしか使えない(それはまあそう)という状況だったので諦めた。

コンポーネントの関数の内部で以下のようにコードを書いてみる。

useEffect(() => {
  ;(async () => {
    if (theme === 'light') {
      await import('../../lib/light')
    } else {
      await import('../../lib/dark')
    }
  })()
  Prism.highlightAll()
}, [theme])

そもそも import をuseEffect内でやっていいのか分からなかったが、ひとまずこれでモードを切り替えたときにシンタックスハイライトのカラーも切り替わった。

上記で解決できなかった問題

切り替わったはいいんだけど、2 回目以降の切り替えができなかった。

1 回切り替えた時点で light も dark も両方 import しているので、たぶん一度 import したものを再度 import するという動作自体が何らかおかしいのだと思う。

なのでこの案は失敗です。

まとめ

結局のところライトモードでもダークモードでもprism-solarizedlightを使っていて、特にダークモード時に見づらいと思うのだけど許してほしい。早く対策したいなあ。