🤮

CodeMirror(V6)をReactで使った時にハマったこと(その1)

2024/01/26に公開

はじめに

CodeMirrorというライブラリをご存知でしょうか?
CodeMirrorとはコードエディターをWeb上で扱うためのライブラリです。
プログラミング言語のPlayGroundサイトなどで使用されているところをイメージするとわかりやすいかもしれません。実際に使用している所もあります。

https://try.ruby-lang.org/playground/

これを使って遊んでみたかったので、ネットで情報を拾ってReact(TypeScript)で実装してみたのですが、思いのほかハマりました。

本記事ではそんなハマりポイントをメモがてら記事にしたいと思います。

ハマりポイント1(ライブラリの依存関係でエラー)

CodeMirrorは多くのライブラリに分かれていて、かつその依存関係が複雑なようで、適当に

npm install @codemirror/xxx

で関連ライブラリを入れていくと以下のようなエラーに悩まされます。

Unrecognized extension value in extension set ([object Object]). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks

解決策として、一度CodeMirror関係のものをすべてnpm uninstallで削除して入れ直すと解決するパターンもあるようですが、タイミングによってはすべてのライブラリを最新版にしても上記エラーになることがあります。
正直こうなると意味不明になるので、手っ取り早く動かすのであれば、@codemirror/basic-setup一本に任せても良いかもしれません。

以下実装サンプルです。
手順も何もなく、

npm install @codemirror/basic-setup

を実行し、関連コードを書いただけというシンプルなものです。

import { memo, useEffect, useRef } from "react";
import { EditorState, EditorView, basicSetup } from "@codemirror/basic-setup";

export const CodeMirrorEditor = memo(() => {
  const editorRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!editorRef.current) return;

    const state = EditorState.create({
      extensions: [basicSetup],
    });

    const view = new EditorView({
      state,
      parent: editorRef.current,
    });

    return () => {
      view.destroy();
    };
  }, []);

  return <div ref={editorRef} />;
});

Edit CodeMirror_Sample1

ここは「何はともあれ、動くものを」という段階までになります。
ここから要件に応じて色々と追加していく感じになりますね。

そもそも・・・・

次の記事で書きますが、同じようなライブラリで「Ace」というのがありますが、こっちはもっとシンプルに作ることができます。
用途にもよりますが、私はこっちでもいいかな。。

参考

https://codemirror.net/docs/guide/
https://codemirror.net/docs/ref/

Discussion