「訳」Ace、CodeMirror、Monaco:Webコードエディタの比較

✍🏼 作成日 2022年01月16日    💡 更新日 2022年05月29日
❗️ 注意:この記事が作成されてから既に 日が経過しています。情報の鮮度にご注意ください
🖥  説明:最近この外国語の記事を見て、良いと思いました。ここで比較されているのは「コードエディタ」であり、リッチテキストエディタとは少し異なる点に注意してください。
📚  Craft にも公開: https://www.craft.do/s/anoVgw55pjshwp

私は約6年間Replitで働いており、チームの成長と共に、製品のIDE部分(私たちは「ワークスペース」と呼んでいます)に焦点を当ててきました。当然のことながら、私はますますコードエディタに集中するようになりました。私たちは自分たちのニーズに合ったコードエディタを作成することを検討しましたが、コードエディタ開発の複雑さ、利用可能なオープンソースオプションの豊富さ、そして私たちのチーム規模を考えると、これは未知の挑戦となる可能性が高く、そのため私の時間は独自のエディタを構築する方面には費やされないかもしれません。私は幸運にも(そして苦労しながらも)本番環境でAceMonacoCodeMirrorという3つのコードエディタを使用してきました。時には同時に使用することもありました(詳細は後述します)。この記事では、Replitの歴史と私のエディタ使用経験、そしてそれらがどのように相互作用してきたかを振り返ります。

もしこの記事を読んでいる目的が直接的な3つのコードエディタの比較であれば、最後までスキップしてください。まとめと比較はそこに記載しています。

ストーリー

前奏:Ace

Replitの初期、2011年頃にはコードエディタは存在しませんでした。私たちは純粋なREPLインターフェース、つまりシンプルな入力ボックスのあるコンソールを使用していました。より複雑なプログラムを作成するためには、コードエディタの追加が明らかに急務でした。コードエディタは、シンタックスハイライト、エディタショートカット、自動インデント、検索と置換などの機能を提供してくれます。当時、Cloud9はAceをリリースしました。これは機能豊富でパフォーマンスの良いWebベースのコードエディタでした。現在でもAceエディタは積極的にメンテナンスされており、多言語サポート、キーバインディング、ブラウザでの良好な動作を特徴とする豊かなエコシステムを持っています。

👇🏻 オリジナルのReplitインターフェースとAceコードエディタの比較。このスクリーンショットは、2011年からReplitのオープンソース版を再ホストしているコミュニティメンバーによって提供されましたhttps://www.repldotit.com

Image

私たちは2017年頃までAceを使用し続け、その後Monacoに切り替えました。Aceはまだメンテナンスされていますが、メンテナーはたった1人です。AmazonがCloud9を買収した後、彼らはオープンソースプロジェクトの優先順位を再調整したようです。エディタは以前のように頻繁に更新されなくなり、Githubのissueも積み上がり、メンテナーもほとんど新機能を追加しなくなりました。全体的に、AceのAPIは開発者にとって時代遅れで扱いにくいものに感じられ始めました。メンテナーは素晴らしい方ですが、できることには限界があります。

挿話:Monaco

ご存知かもしれませんが、VSCodeはMonacoエディタを使用しています。実際、MicrosoftはMonacoを基にVSCodeを構築しました。コードエディタをMonacoに切り替えることで、VSCodeの開発者たちによるクールな更新や機能をすべて享受できると考えました。Monacoは私たちのウェブサイトにマッチするモダンで洗練されたUIを備えており、JavaScript、HTML、CSSに対して優れたオートコンプリート機能があり、LSP(Language-Server-Protocol)に対応した言語クライアントを簡単に作成できるAPIも提供されているようです。APIドキュメントは素晴らしく、TypeScriptの定義も付属しており、開発視点で見ると拡張性の高い機能を備えています。

👇🏻Monacoエディタのスクリーンショット(デフォルト設定)、クリーンで整理されたUIに注目してください。

Image

AceからMonacoへの移行には代償が伴いました。後者はAceの多くの機能を欠いていますが、コミュニティの熱意と貢献によって、すぐにAceを凌駕すると確信しています。Monacoの最初の問題は、多くの言語サポートが不足していることです。VSCodeには多くの言語サポートがありますが、それらはNodeJS/Electronの能力に依存しており、ブラウザでは利用できません。そのため、私たちはMonacoにコードを貢献し、より多くの言語をサポートするようにしました。Scala、Julia、Scheme、Clojureなどの言語サポートや、Pythonのような言語のバグ修正を追加しました。私はMonaco用にシンタックスハイライトディスプレイを書き、アダプターを通じてAceがサポートするすべての言語をサポートできるようにしました。最後に、MonacoがAceに比べて欠けている機能はVimとEmacsのキーバインドですが、おそらくすぐに誰かがNPMでこれらの機能をサポートするパッケージを公開するでしょう。

Monacoのもう一つの問題はビルドツールです。MicrosoftはWeb技術を使ってMonacoを構築しましたが、現在のWebエコシステムやビルドツールとうまく統合されていません。私はMonacoをWebpack Dllとして事前コンパイルし、多くのWebpack設定を追加してようやく動作させることができました。これらの追加は苦痛であり、ビルドシステムの複雑さとコストを増加させました。数か月後、MicrosoftはMonaco用のWebpackプラグインをリリースし、状況は多少改善されましたが、特に私たちがフロントエンドをNext.jsに移行したときには完璧ではありませんでした。残念ながら、Monacoにはコードを遅延ロードしたり分割したりする簡単な方法もないため、コードを小さなファイルに分割して読み込み速度を向上させることはできませんでした。この問題により、私たちのプロジェクトのサイズは最大5M増加し、これは軽視できることではありません。

Monacoはモバイル端末でもあまり使い勝手が良くありません。この部分のコードを外部委託しようとしましたが、引き受けてくれる業者がいませんでした。そこで自分で対応しようとしたとき、Monacoのコードベースを調査・読解することが非常に難しいことに気づきました。Monacoエディター自体は、VSCodeを最初に構築した後、そこから切り離されたようなもので、VSCodeコードベースの他の部分と強く結合しています。VSCode自体もコードがよく書かれているとは言えず、https://web.archive.org/web/20150502200822/https://www.zdnet.com/article/microsofts-browser-based-dev-toolbox-how-monaco-came-to-be/やhttps://www.youtube.com/watch?v=FyCYva9DhsIのように、最も古いTypeScriptプロジェクトの一つであり、Microsoftの大企業スタイルで書かれています。モバイル端末でそこそこ使えるものは実現できましたが、VSCodeのフォークをメンテナンスするつもりはありません。私たちがVSCodeに行った変更はVSCodeのメインブランチにマージされる見込みがなく、現在のモバイル版はプロダクション環境で使用できるまでには程遠いからです。そのため、最善の解決策は、スマートフォンでは引き続きAceエディターを使用することだと判断しました。完璧ではないかもしれませんが、問題ありません(使えないわけではありません)。

したがって、Replit上では最終的に2つのコードエディタが存在することになりました:1つはPC用、もう1つはモバイル用です。PC向けの新機能はすべてAce(モバイル版)に移植する必要がありました。Ace用にLSP機能をサポートする言語クライアントを開発し、複数ユーザーによる同時編集を可能にする操作変換アダプタ(訳注:OT変換?)も実装する必要がありました。多くの場合、移植する時間すらありませんでした。例えば、コードのマルチスレッド機能はモバイル版に移植されることはありませんでした。

舞台裏:CodeMirror

2018年末、MarijnはCodeMirrorの書き直しを発表し、バージョン6への更新とともに優れた設計ドキュメントを公開しました。このリライトの主な動機の一つは、タッチデバイスへの対応を強化することでした。この時期、私たちはモバイル(一般的な意味で)が戦略的に重要であると認識していました。次の10億人のソフトウェアクリエイターをオンラインにするためには、モバイル対応が必須だったのです。CodeMirrorは、JavaScript/ライブラリレベルで完全に実装する(Google DocsのGoogle Closureのように)のではなく、contenteditableを通じてネイティブブラウザのテキスト編集機能を活用することで、モバイルでの操作性を実現しようとしました。

ProseMirrorはCodeMirror 6のAPI設計に影響を与えたMarijnの別プロジェクトです。私自身、当時開発していたWYSIWYGプロジェクトで使用し、その良さを実感していました。ProseMirrorは非常に小さなコアを持ち、他のすべてはプラグインシステムを通じて実装されます。エディタライブラリとして、モジュール化され、プラグ可能で、機能的であり、信じられないほどの自由度を提供します。そこで私は、会社として新版CodeMirrorの開発をスポンサーすることに決め、個人的にも資金を提供しました。

昨年、CodeMirror 6のベータ版がリリースされ、私はReplitに組み込むことに非常に興奮し、チームの他のメンバーも同様でした。エディタを試し始めると、学習曲線はやや急でしたが、一度理解するとスーパー・コードエディタ開発者のような気分になれます。CodeMirror 6をプロジェクトに適用するため、私は段階的に導入を開始しました。まずReplit上で読み取り専用のエディタとして追加し、その後、サイト内の他のコード編集可能な場所にも組み込んでいきました。

今年初め、私たちは「信仰の飛躍」(訳注:アサシンクリードのネタ)を始め、CodeMirrorをモバイル環境に統合し始めました。ユーザーの視点から見ると、CodeMirrorは客観的に見てモバイル上の他のどのエディターよりも優れています。まだ私たちがサポートしているすべての言語やその他の機能をカバーしているわけではありませんが、モバイルへの統合は価値のある取り組みでした。この統合後のユーザーフィードバックは、私たちが予想していた以上に良好でした。CodeMirrorを使用しているユーザーの中で(訳注:おそらく小規模テスト、または新旧バージョンの切り替えオプションを提供して統計を取ったもの)、モバイルユーザーの割合は約70%に達しました!CodeMirrorは、モバイルでAceを使用する場合よりもユーザーを引き留める効果があります。CodeMirrorのプラグイン可能な性質(提供される無限の可能性)を考えると、これら(心躍る結果)は、モバイルでさらに価値あることを提供する始まりに過ぎないことは明らかです。私たちはまず、モバイルで欠けているPC版の機能をモバイル版CodeMirrorに移植することから始めます。

Image

CodeMirror 6のコミュニティはまだ初期段階にあるため、多くの機能を自前で実装したり、特定の機能の開発資金を提供したり、Marijnと協力してバグを修正する必要があります。私たちは、自身の貢献を通じてCodeMirrorコミュニティを導き、還元したいと考えています。ここでは、現在積極的に開発中の機能のリストを挙げます:Vim Mode、Emacs Mode、LSPクライアント、インデントマーカー、CSSカラーピッカー、言語パーサー、そして将来的にデスクトップ版CodeMirrorをリリースする際に、投稿で発表する予定の多くの機能です。新しいCodeMirrorに対する人々の期待は高く、今後1~2年でコミュニティとエコシステムのユーザー数が急増し、多くの人が本番環境での使用を急いでいると思います。

私たちは、CodeMirror上でますます多くの機能を構築し、コードのアクセシビリティ向上において不可欠な要素とすることを非常に楽しみにしています。常々、理想的なユーザー体験を実現するためには最終的に独自のエディタを開発する必要があると話していました。それでも、CodeMirrorを使って実現できることに満足しています。

バトルセクション

あなたに最適なコードエディタを見つけやすくするために、まとめておきます。繰り返しになりますが、これは私個人の経験であり、あなたの経験とは異なるかもしれません。

各セクションで、エディタに1~3点を付けます。3点が最高評価です。

安定性

エディタ 評価 説明

| Ace | ⭐️⭐️⭐️ | 非常に安定しており信頼性が高い。このエディターは歴史的な検証を経ており、10年以上にわたり多くのツールをサポートしてきた。私が使用している間、重大な変更(break change)を経験したことは一度もない。いくつかのバージョンで小さなバグが導入されることはあったが、それらは迅速に修正された。 |
| Monaco | ⭐️⭐️ | Monacoは安定した編集体験を提供する。もちろんいくつかのバグは存在するが、VSCodeのリリースに伴い迅速に修正される。メンテナンスチームは新しいバージョンを継続的にリリースすることに長けている。1点減点した理由は、APIが最も安定しているとは言えず、頻繁に小さな変更があり煩わしいためである。マイクロソフトはまだMonacoの1.0バージョンをリリースしていない。 |
| CodeMirror 6 | ⭐️ | CodeMirrorはまだベータ段階であり、プロジェクトには多くの小さなバグが存在する。しかしMarijnは迅速に対応し修正を加えている。ベータ段階ではあるが、Marijnが現在のAPIに満足していると考えられ、重大な変更(break change)が発生する可能性は低い。CodeMirror 6は多くの機能に採用され始めており、Chromeの開発ツールでさえ来年からコードエディターとしての採用を検討している可能性がある。 |

すぐに使える体験

エディタ 評価 説明
Ace ⭐️⭐️ すぐに使える優れた体験を提供し、多くの機能と言語をサポートしています。基本的なJavaScript Lint機能(JSHintを使用)や自動補完機能も含まれています。ただ、ユーザーインターフェースが少し古く、時々混乱を感じるかもしれません。
Monaco ⭐️⭐️⭐️ 非常に洗練されたユーザーインターフェースです。このエディタには、HTML、CSS、JavaScriptのコードヒントサポートなど、多くの機能が組み込まれています。
CodeMirror 6 ⭐️⭐️ エディタを正常に動作させるにはいくつかの設定が必要です。これはプロジェクトのモジュール性とのトレードオフです。basic-setup パッケージがあり、いくつかのモジュールを組み合わせ、コアモジュールを再エクスポートしています。ユーザーインターフェースは良好です。

モジュール化、ビルドツール、進化の軌跡

エディタ 評価 説明
Ace ⭐️⭐️ Aceは非常に軽量で、モジュール化もサポートしています。他のモジュールを遅延ロードで読み込むことが可能です。しかしAceは比較的古いプロジェクトで、独自のモジュール管理システムを備えており、既存のプログラムに組み込むには若干の設定が必要です。
Monaco ⭐️ Monacoエディタはバンドル後のサイズが非常に大きく、約5M程度になります。また、私の知る限り遅延ロードは不可能です。Monacoはビルドシステムに特別な設定が必要で、既存システムとの統合が難しいです。
CodeMirror 6 ⭐️⭐️ CodeMirrorは現代的な技術で構築されています。バンドラを使用せずにES6モジュールでインポートすることも可能です。遅延ロード機能は簡単に実現でき、ES6の動的インポート機能を使用するだけです。このプロジェクトは非常にモジュール化されており、エディタコアは非常に軽量です。

拡張性と高度な機能

エディタ 評価 説明

| Ace | ⭐️⭐️ | Aceには多くの設定項目があり、効果も良く、拡張ポイントも充実しています。汎用性は高くありませんが、多くの高度な機能を実現できます。APIは確かにやや古い印象を受けますが、非常に信頼性があります。プロジェクトを迅速に試す必要がある場合、Aceを簡単に選択できます。そのコードは読みやすく、コアコードはほぼ10年間変更されていません。 |
| Monaco | ⭐️⭐️ | Monacoは豊富な設定項目を備え、エディタの動作や基本機能を変更するAPIを提供しています。しかし、拡張可能な領域は限定的で、あまりに特化しすぎています。私はよくエディタと格闘し、危険で収束が難しいハックパッチを当てなければなりませんでした。そのコードベースは読みやすくなく、内部コードは絶えず変化しています。最終的に、Monacoのアップグレードを止めました。将来も私たちが必要とするいくつかの機能をサポートする見込みがないためです。 |

| CodeMirror 6 | ⭐️⭐️⭐️ | CodeMirror 6 は構築当初から拡張性を考慮して設計されており、これが主要な設計原則の一つとなっています。この拡張性により、CodeMirror はモジュール化が可能です。実際、コア自体(@codemirror/view と @codemirror/state)は本質的に拡張可能な textarea です。すべての「コード」機能は拡張として実装されています。シンタックスハイライトや行番号などの基本的な要素も、拡張やパッケージとして実装されています。独自の拡張を作成する際、これらの公式パッケージは優れたサンプルリソースとなります。CodeMirror を使用して派手なプラグインを構築するのは非常に簡単で、プラグイン開発者として、信じられないほど強力なサポートを提供してくれます!その拡張ポイントは非常に汎用的であるため、あなたはプログラム世界の神となり、実装したい機能を完全に自分で決定し、その結果に対処できます。 |

コミュニティとドキュメント

エディタ 評価 説明
Ace ⭐️⭐️ 長年にわたり、Aceは豊富なエコシステムと多数の使用記事・ブログを蓄積してきました。あらゆる言語のシンタックスハイライトをサポートし、コミュニティ提供のツールキットも豊富です。APIドキュメントは最良とは言えませんが、ほとんどのユースケースには十分です。構造化された(やや古い)コードベースは優れた(ドキュメントの)補助リソースです。オンラインには入門ガイドもあります。

| Monaco | ⭐️⭐️ | Monacoは2018年頃から本格的に開発が進められましたが、コミュニティの急速な衰退が感じられます。NPMにはコミュニティがメンテナンスするパッケージが多数存在します。MonacoのAPIドキュメント自体は十分に整っていますが、公式ガイドがないため、初心者にとっては習得が難しいと感じられるかもしれません。プロジェクトの構造が複雑なため、APIドキュメントの補助としてコードを読むことも容易ではありません。 |
| CodeMirror 6 | ⭐️⭐️⭐️ | CodeMirror 6には活発な開発の勢いが見られます。私たちもCodeMirror 6にとって重要なパッケージを提供することでコミュニティの発展を支援しようとしていますので、ご期待ください!そのドキュメントは素晴らしく、今後さらに改善されていくことを願っています。ドキュメントシステムには優れた入門記事と多くのサンプルが用意されており、詳細な解説が付随しています。前述の拡張性について触れましたが、ほとんどの機能は拡張によって実現されており、これらは機能を実装したい際の「強力な味方」となります。 |

パフォーマンス

免責事項:パフォーマンス評価には明確なベンチマークデータが存在しません。
エディタ 評価 説明
Ace ⭐️⭐️⭐️ Aceはブラウザやマシンの性能が現在ほど高くなかった時代に生まれたため、今日においても非常に優れたパフォーマンスを発揮します。
Monaco ⭐️⭐️ Monacoには多くのパフォーマンス最適化が施されていますが、やや重い印象があります。Replitの低電力マシンユーザーからは、Monacoが電力消費が激しいという声が寄せられています。
CodeMirror 6 ⭐️⭐️⭐️ CodeMirrorはこれまでのところ優れたパフォーマンスを示しています。これは作者が多くの時間をかけてパフォーマンス最適化を行った結果です。

モバイルサポート

ここでは評価を行いません。なぜなら、モバイル対応のコードエディタを求める場合、現時点で選択肢はCodeMirror 6のみだからです。Aceのモバイルサポートは悪くありませんが、プロダクション環境での使用には適しておらず、Monacoはモバイル端末では利用できません。

私はむしろ、CodeMirrorはWebviewコンポーネントを使用するネイティブアプリケーションにも適用できると言えるでしょう。CodeMirrorのほとんどの内容はシリアライズ可能であるため、ネイティブコードからWebviewとやり取りすることができます。

お読みいただきありがとうございます!

この部分は著者の広告タイムのため、翻訳を一時的に控えます。

- EOF -
この記事の初出: 「訳」Ace、CodeMirror、Monaco:Webコードエディタの比較 - Xheldon Blog