PrismJSのAutoloaderを使ってシンタックスハイライトを行う
PrismJSのAutoloaderを使ってシンタックスハイライトを行う
2022/09/22

Autoloaderを使ってシンタックスハイライト言語を自動追加してくれる便利なプラグインがあるにも関わらず、npmでパッケージ管理しているプロジェクトでPrismJSとAutoloaderを使ったHowto記事が見つからなかったので、挑戦してみました。

Autoloaderを使う

シンタックスハイライトしたい言語だけのファイルを自動で読み込めるように、プラグインのAutoloaderを導入する。

インストール

AutoloaderはPrismJSのパッケージの中に入っているので、PrismJSだけのインストールで済む。

$ yarn add prismjs

コードの追加

今回はReactで説明していく。

PrismJSをいつも通り使うのに加えて、autoloaderをimportしておく。
読み込むファイルはブログなら記事部分が対象になるでしょうから、Content.tsxなど記事のコンポーネントに追加すれば良い。

import 'prismjs/plugins/autoloader/prism-autoloader'
import Prism from "prismjs"

const Component: React.FC = () =>  {
  useEffect(() => {
    Prism.highlightAll();
  }, []);
  
  // ...
}

実行すると、Autoloaderが動いてシンタックスハイライト対象言語を読み込みに行こうとしているが、404エラーが返ってきている。

404エラー

対象言語用のコードの取得先を変更する必要がある。


import 'prismjs/plugins/autoloader/prism-autoloader'
import Prism from "prismjs"

if (prism.plugins.autoloader) {
	// npmで管理しているバージョンと合わせる
  prism.plugins.autoloader.languages_path =
    'https://unpkg.com/prismjs@1.28.0/components/'
}

const Component: React.FC = () =>  {
  useEffect(() => {
    Prism.highlightAll();
  }, []);
  
  // ...
}

これでシンタックスハイライトが効くようになる。

シンタックスハイライトが効く

なぜAutoloaderを使いたかったのか

ReactやVueなどでPrismJSを使ってシンタックスハイライトを行う際、PrismJSもnpmでパッケージ管理したい。

Reactを例にあげると、以下のように書くと思う。

import Prism from "prismjs";

const Component: React.FC = () =>  {
  useEffect(() => {
    Prism.highlightAll();
  }, []);
  
  // ...
}

シンタックスハイライトの対象言語を追加するとなると、importを行うか、babelを使っているならbabel-plugin-prismjs を使うと思う。

  • パターン1:importを使って対象言語を読み込む
import Prism from "prismjs";
// bashを対象言語に追加する場合
import 'prismjs/components/prism-bash'
  • パターン2:bebel-plugin-prismjsで対象言語を読み込む

.babelrc

{
  "plugins": [
    [
      "prismjs",
      {
        "languages": ["bash"]
      }
    ]
  ]
}

上記のように書けば問題なく動作する。

しかし例えばブログで使う際に、あるページではbash, tsx, jsonを使い、とあるページでは、go, graphql, yamlを使うとすると、記事ページでは6言語分のシンタックスハイライト用のコードを読み込んでおかなければならない。

使っていない対象言語用のコードを読み込んでしまうし、何十種類も対象言語を読み込むとなるとパフォーマンス的に悪影響になるのは間違いない。

1言語ごとのファイルサイズは小さいが全ファイル読み込むと・・・

なので、シンタックスハイライトする言語だけのファイルを読み込めるAutoloaderを使いたかった。