[Tips] React で highlight.js を適用する方法

2020_12

はじめに

Reacthighlight.js を組み込もうとしたのですが、若干躓いてしまったので対処法についてメモっておきます。

また、React は既にプロジェクトにインストール済みと仮定します。

# 一応 React をインストールするためのコマンドは ↓
npm i --save react react-dom

React に highlight.js を組み込む

まずは highlight.js を NPM or Yarn でインストールします。

# NPM で highlight.js をインストールする
npm i --save highlight.js
yarn add highlight.js

その後、React ソースコードに highlight.js を組み込みます。
ソースコードの該当部分のみを載せると下記の感じになります。

import Head from 'next/head'
import styles from '../styles/Home.module.css'
import React, { useState, useEffect } from 'react';
/**
highlight.js を import する
*/
import hljs from 'highlight.js/lib/core';
/**
シンタックスハイライトしたい言語のみ import として登録する
今回は html をハイライトしたかったので xml を import した
デザインは highlight.js/styles/~ を変更することで調整可能
https://highlightjs.org/ のトップページから各種デザインについては確認可能
(コード右下にある style の右側リンククリックで各種デザインのプレビューが可能)
*/
import xml from 'highlight.js/lib/languages/xml';
import 'highlight.js/styles/github.css';
hljs.registerLanguage('xml', xml);
let inputChecker = null;
export default function Home() {
  const [user, setUser] = useState('nikaera');
  const [previewUser, setPreviewUser] = useState('nikaera');
  const [badgeCode, setBadgeCode] = useState('nikaera');
  const [style, setStyle] = useState('plastic')
  /**
  useEffect のタイミングで hightlight.js の初期化を行う。
  called プロパティを false にすることで highlight.js で、
  コードが変更された場合でも常にシンタックスハイライトすることが可能
  */
  useEffect(() => {
    hljs.initHighlighting();
    hljs.initHighlighting.called = false;
  });
  useEffect(() => {
    /**
    シンタックスハイライトしたいコード input フォームへの入力内容に応じて動的に変わる
    */
    setBadgeCode(`  <!-- highlight.js でハイライトする -->
  <div>Hello ${user}!</div>
  }`, [user, style]);
  });
  const handleChange = (event) => {
    if (inputChecker)
      clearTimeout(inputChecker);
    inputChecker = setTimeout(() => {
      clearTimeout(inputChecker);
      inputChecker = null;
      setPreviewUser(event.target.value);
    }, 1 * 1000); // 1 seconds
    setUser(event.target.value);
  };
  return (
    <div className={styles.container}>
      <Head>
        <title>Highlight</title>
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          Highlight sample
        </h1>

        <input type="text" value={user} onChange={handleChange} />

        <div>
          { /* pre -> code タグ内に highlight.js で
            シンタックスハイライトしたい内容を出力する */ }
          <pre style={{ width: '80vw' }}>
            <code className="xml">
              {badgeCode}
            </code>
          </pre>
        </div>
      </main>

      <footer className={styles.footer}>
      </footer>
    </div>
  )
}

おわりに

React に highlight.js を組み込むやり方は多々見つけたものの、中々上手くできなかったのでメモっておきました。同様のケースで悩んでいる方の助けになれれば幸いです:pray:

参考リンク