NPMパッケージで`@lexical/code`の組み込み言語が読み込まれない問題を修正

basecamp/lexxy

NPMパッケージとしてhighlightCodeをインポートした際、@lexical/codeが標準で提供するシンタックスハイライト言語が読み込まれないバグが修正されました。あわせてKotlinのサポートも追加されています。

背景

gemとして使用する場合はモノバンドルに全言語インポートが含まれるため問題が表面化していませんでしたが、NPMパッケージ経由では@lexical/codeが前提とするPrism言語グラマーが欠落する状態でした。@lexical/codeはコードハイライト機能の内部で、JavaScript・TypeScript・Python・Rustなど多数のグラマーを前提として動作します。これらがsrc/config/prism.jsに明示的にインポートされていなかったため、NPMパッケージ利用者にはハイライトが機能しないケースが生じていました。

技術的な変更

src/config/prism.js@lexical/codeが標準で扱う言語グラマーのインポートが追加されました。Prismのグラマーは相互に依存して拡張し合う構造を持つため、読み込み順序が重要です。追加されたインポート群はその依存順を考慮して並べられており、コメントで「Don't reorder: they extend each other」と明示されています。

変更前:

import Prism from "prismjs"

// Import base language dependencies first
import "prismjs/components/prism-clike"
import "prismjs/components/prism-markup"
import "prismjs/components/prism-markup-templating"

// Import languages
import "prismjs/components/prism-ruby"
import "prismjs/components/prism-php"
import "prismjs/components/prism-go"
import "prismjs/components/prism-bash"
import "prismjs/components/prism-json"
import "prismjs/components/prism-diff"

変更後:

import Prism from "prismjs"
// Prism and base @lexical/code languages
// Don't reorder: they extend each other
import "prismjs/components/prism-clike"
import "prismjs/components/prism-diff"
import "prismjs/components/prism-javascript"
import "prismjs/components/prism-markup"
import "prismjs/components/prism-markdown"
import "prismjs/components/prism-c"
import "prismjs/components/prism-css"
import "prismjs/components/prism-objectivec"
import "prismjs/components/prism-sql"
import "prismjs/components/prism-powershell"
import "prismjs/components/prism-python"
import "prismjs/components/prism-rust"
import "prismjs/components/prism-swift"
import "prismjs/components/prism-typescript"
import "prismjs/components/prism-java"
import "prismjs/components/prism-cpp"

// Import extra base language dependencies
import "prismjs/components/prism-markup-templating"

// Import extra languages
import "prismjs/components/prism-ruby"
import "prismjs/components/prism-php"
import "prismjs/components/prism-go"
import "prismjs/components/prism-bash"
import "prismjs/components/prism-json"
import "prismjs/components/prism-kotlin"

変更前はdiffが「extra languages」セクションの末尾にありましたが、変更後は@lexical/codeのベース言語群の一部として冒頭に移動しています。またこれまでdiffがあったスロットにはKotlinが追加されました。同時にsrc/elements/code_language_picker.jsにもlanguages.kotlin ||= "Kotlin"が追加されており、UIのピッカーにKotlinが表示されるようになっています。

設計判断

言語インポート群を「@lexical/codeのベース言語」と「拡張言語」の2グループに明確に分離する構成が採られました。コメントによるセクション区切りと順序の固定指示を設けることで、今後のメンテナー向けに「ライブラリ由来の必須セット」と「lexxy独自の追加セット」の意図を伝える設計になっています。Prismのグラマーは拡張チェーンを持つため(例: cppcに依存)、順序の誤りが無音の機能不全を引き起こしやすい。コメントと区分けによってそのリスクを明示化した判断といえます。

テスト側でもtest/javascript/unit/helpers/code_highlighting_helper.test.jsに期待される言語グラマーがすべてロードされているかを確認するテストが追加され、意図しないグラマーの欠落を検出する仕組みが導入されています。

まとめ

本PRは、gemとNPMという2つの配布形態の差異によって隠蔽されていたグラマー欠落バグを修正した変更です。@lexical/codeが前提とする言語セットを明示的にインポートし、コメントで順序依存を宣言する構成にしたことで、今後の言語追加時に同様の問題を防ぐ基盤が整いました。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
3c52316a

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)、背景、技術的な変更、設計判断、まとめ(結論)という「総論→各論→結論」の3部構成が明確に適用されており、模範的です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```javascript:src/config/prism.js)およびGitHubのPRリンク記法([PR #964](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

NPM、Prism.js、gemといった用語を前提としており、専門知識を持つエンジニアという対象読者に適した技術レベルと表現で書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論で構成され、各段落はトピックセンテンスで始まり、1段落1トピックの原則が守られています。段落の長さも適切です。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のコードブロックは、提供されたDiff情報を正確に反映しています。`src/config/prism.js`の変更内容、Kotlinの追加などが正しく引用されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「言語グラマー」「モノバンドル」「@lexical/code」など、PRの文脈に沿った技術用語が正確かつ適切に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「gemとNPMの配布形態による差異」という問題の根本原因や、「Prismグラマーの依存関係と読み込み順序の重要性」など、技術的な説明はすべて正確で論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(バグの原因、Kotlinの追加、テストの導入など)は、PRのDescriptionやDiffの内容によって裏付けられています。「設計判断」セクションもコードの構造から導かれた妥当な解説であり、ハルシネーションは認められません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#964)やファイルパス(`src/config/prism.js`など)といった数値・固有名詞はすべて正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルは、PRのタイトル「Fix npm included languages」の内容をより具体的に、かつ正確に要約しており、主題と完全に一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事はPR情報(Description, Diff)に基づいており、バージョンサポート状況やリリース日程といったPRに記載のない外部知識の持ち込みはありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「〜が修正されました」「〜でした」といった過去形の表現が使われており、完了した変更であるというPRの時制と正確に一致しています。