コードハイライトのグラマー未ロード問題を修正し、非推奨エクスポートを削除

basecamp/lexxy

highlightCode ヘルパーが prismjs を直接インポートしていたため、グラマー定義が読み込まれない問題を修正しました。あわせて v0.7.0 以前から非推奨だった highlightAll エクスポートが削除されています。

背景

highlightCode ヘルパーはコードブロックの構文ハイライトを担う関数ですが、グラマーが実際に動作しない状態になっていました。原因は、ヘルパーが prismjs を直接インポートしていたことにあります。Prism のグラマー定義(prism-rubyprism-go など)は src/config/prism.js でまとめてロードされているにもかかわらず、ヘルパーはその設定ファイルを経由せず素の prismjs を参照していたため、グラマーが未定義のまま動作していました。

この問題と同時に、v0.7.0 より前のバージョンとの互換性のために維持されていた highlightAll エクスポートも削除されています。PR の説明では BREAKING CHANGE として明記されており、旧 API への移行猶予期間が終了したと判断されたことがわかります。

技術的な変更

変更の核心は、src/config/prism.js をグラマー定義を持つモジュールとして明示的にエクスポートし、ヘルパーがそこからインポートするよう修正した点です。

src/config/prism.js では、これまで import "prismjs" として副作用のみのインポートをしていましたが、import Prism from "prismjs" に変更し、ファイル末尾に export default Prism を追加しました。これにより、グラマーがすべてロードされた状態の Prism オブジェクトをモジュールとして外部に提供できるようになりました。また、window.Prism ||= {} への書き換えは機能的に同等で、コードの簡潔化です。

変更前:

window.Prism = window.Prism || {}
window.Prism.manual = true

import "prismjs"

// Import base language dependencies first
import "prismjs/components/prism-clike"
// ...
import "prismjs/components/prism-diff"

変更後:

window.Prism ||= {}
window.Prism.manual = true

import Prism from "prismjs"

// Import base language dependencies first
import "prismjs/components/prism-clike"
// ...
import "prismjs/components/prism-diff"

export default Prism

src/helpers/code_highlighting_helper.js 側では、インポート元を "prismjs" から "../config/prism" に変更するだけで修正が完了しています。

変更前:

import Prism from "prismjs"

変更後:

import Prism from "../config/prism"

src/index.js からは以下の3行が削除され、highlightAll の公開が終了しました。

// legacy export for <=v0.7
export { highlightCode as highlightAll } from "./helpers/code_highlighting_helper"

テスト用のダミーアプリ test/dummy/app/javascript/controllers/events_logger_controller.js でも highlightAll から highlightCode への移行が行われており、破壊的変更への対応例として参照できます。

設計判断

グラマーロードの責務を prism.js 設定ファイルに一元化する設計が採用されました。

prismjs を直接インポートする代わりに設定ファイル経由でインポートさせることで、「Prism を使うならグラマーも必ず揃っている」という不変条件をモジュール境界で保証できます。各利用箇所が個別にグラマーのインポートを意識する必要がなくなり、将来グラマーを追加・削除する場合も src/config/prism.js の変更だけで対応できます。

この修正に対応する形で、追加されたユニットテスト test/javascript/unit/helpers/code_highlighting_helper.test.js では、期待されるグラマー(clikemarkuprubyphpgobashjsondiff など9種)が Prism.languages に定義されていることを test.each で網羅的に検証しています。グラマーの未ロードという問題の性質上、この種の存在確認テストが有効なリグレッション防止策として機能します。

まとめ

インポート元を "prismjs" から "../config/prism" に切り替えるという最小限の変更で、グラマー未ロードという実害のあるバグが解消されました。同時に旧 API highlightAll を削除したことで、v0.7.0 以前から引き継いできた互換レイヤーが整理され、コードベースがよりシンプルになっています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
237d9102

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
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リンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

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

JavaScriptのモジュールシステムやPrism.jsに関する知識を前提としており、対象読者であるエンジニアに適した技術レベルと表現で書かれています。

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

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

各セクションが総論→各論の構造を持ち、各段落はトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られており、非常に読みやすいです。

Diff内容との照合 ✓ PASS

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

記事内で引用されているすべてのコードブロックは、提供されたDiffの内容と完全に一致しています。ファイル名も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「グラマー」「BREAKING CHANGE」「リグレッション防止策」などの技術用語が、PRの文脈と一般の用法に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

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

グラマーがロードされなかった原因(インポート元の問題)についての説明は、Diffの変更内容と整合しており、技術的に正確です。

事実の突合 ✓ PASS

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

記事内のすべての主張(バグ修正、非推奨APIの削除、テスト追加など)は、PRのタイトル、説明、Diffの内容によって裏付けられており、ハルシネーションは検出されませんでした。

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

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

PR番号(#959)、バージョン番号(v0.7.0)、テストで検証されたグラマーの数(9種)など、数値や固有名詞はすべて正確です。

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

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

記事のタイトルは、PRの主題である「グラマー未ロード問題の修正」と、破壊的変更である「非推奨エクスポートの削除」の両方を的確に表現しており、PR内容と完全に一致しています。

外部知識の正確性 ✓ PASS

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

記事に含まれる情報はすべてPR内で言及されている内容に基づいており、PRに記載のない外部知識(サポート状況やリリース予定など)は含まれていません。

時間表現の正確性 ✓ PASS

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

PRで「removed deprecated export」と過去形で表現されている事象を「削除されています」と正しく記述しており、時間表現に歪曲はありません。