言語工学の実践
Vue の構文・生成 JavaScript・診断・エディターの動作を変えるときに、必要な検証を選ぶためのガイドです。 利用者が目にする結果の正しさを、どのテストや出力で示すかを整理しています。
まず 変更の種類 から該当する行を選び、小さな再現例を追加して出力を確認してください。 フォーマッタの修正には整形後の文字列、LSP の修正には問題を再現するエディター操作が必要です。 次に 追加の検証 で性能・セキュリティ・fuzzing の要否を確認します。 参考にした他のプロジェクトの手法は、末尾の 参考資料 にまとめています。
変更の種類
言語処理に関わる PR には、変更の種類と、次の表で対応する検証結果を記載してください。 開発中は対象を絞ったコマンドで確認し、共通の動作に影響する場合は検証範囲を広げます。
| 変更の種類 | 必要な検証 | よく使うコマンド |
|---|---|---|
| パーサー・AST | 最小限のパーサーフィクスチャと、期待する AST またはエラー出力。無関係なスナップショットをまとめて更新しないこと。 | cargo test -p vize_armature、cargo test -p vize_test_runner、node tests/tooling/support/generate-expected.ts <fixture> |
| コンパイラ・コード生成 | 最小限のソースフィクスチャと、期待する DOM・Vapor・SSR 出力。生成コードの実行時の構造が変わる場合は、実際のプロジェクトで互換性も確認すること。 | cargo test -p vize_atelier_dom、cargo test -p vize_atelier_vapor、vp run --filter './tests' test:build |
| 意味解析・lint・ファイル間解析 | ルールや解析器のフィクスチャ、JSON またはエージェント向け出力のスナップショット、変更する診断のドキュメント。 | cargo test -p vize_patina、vp run --filter './tests' test:lint、node --test tests/tooling/snapshot-baselines.test.ts |
| 仮想 TypeScript・型チェック | 最小限の SFC フィクスチャ、元のソース位置に対応付けた診断のスナップショット、生成した仮想 TS のレビュー、公式 Vue または TypeScript との互換性の説明。 | vp run --filter './tests' test:check:fixtures、cargo test -p vize_canon、vize check --show-virtual-ts <file> |
| フォーマッタ・LSP | 整形後の文字列を照合するテスト、またはプロトコルの基本動作を確認するテスト。利用者が目にする動作を変える場合は、該当するエディター操作の統合テストも行うこと。 | cargo test -p vize_glyph、cargo test -p vize_maestro、node --test tests/tooling/lsp-smoke.test.ts |
| 実行時パッケージ・リリース・ドキュメント | リポジトリの運用規約を確認するテスト、インストール後の基本動作またはワークフローの検証。本番利用の位置付けが変わる場合は、リリースや利用準備状況のドキュメントも更新すること。 | node --test tests/tooling/*.test.ts tests/tooling/release/*.test.ts、rust-script tools/commands/release/npm/smoke-release-install.rs --prepare-manifests --runtime-checks、vp run --workspace-root check:ci |
追加の検証
変更の種類によっては、上の表に加えて性能・セキュリティ・fuzzing の検証が必要です。 レビュー担当者の記憶に頼らず、どの検証を行い、何が分かったかを PR に記録してください。
| 検証の観点 | 対象になる変更 | 記録する検証結果 |
|---|---|---|
| セキュリティ | URL 処理、HTML・SSR 出力、ファイルシステム・設定の読み込み、ネイティブコードの読み込み、パッケージ公開、CI、認証情報。 | .github/workflows/check.yml の security-audit、vp exec pnpm audit --prod --audit-level moderate、cargo audit --deny warnings、インストール後の実行時チェック、GitHub Actions の参照が固定されていることの確認、危険な入力や境界に絞った回帰テスト。 |
| 性能 | パーサー、コンパイラ、リンター、フォーマッタ、型チェッカー、キャッシュ、プロジェクトグラフの探索、生成される出力、CLI の入出力。 | .github/workflows/benchmark.yml、tools/benchmarks/scripts/compare-pr.ts、tools/benchmarks/scripts/enforce-pr-budget.ts、pr-benchmark-budget の結果、ローカルの bench:* タスク。性能低下の原因を特定する場合は、vize lint --profile、vize check --profile、vize fmt --profile の出力も記録すること。 |
| fuzzing | バイト列の解析、構文エラーからの回復、CSS の解析、JS・TS の式の解析、テンプレートの字句解析、コード生成時のエラーからの回復。 | .github/workflows/fuzz.yml、tests/fuzz/Cargo.toml、tools/commands/ci/fuzz/seed_corpus.rs、cargo +nightly fuzz run <target>、アップロードされた fuzz-reproducers-*。クラッシュ・タイムアウト・メモリ不足の原因を把握した後に、最小化した再現例を決定論的な回帰テストとして追加すること。 |
ベースラインの扱い
- 最小限の失敗例や動作例から始めてください。複数の機能にまたがる動作を示す必要がある場合に、フィクスチャの範囲を広げます。
- スナップショットやベースラインは、利用者が目にする動作の契約です。診断、生成コード、公開 CLI の出力、エディターの動作が変わる差分には、新しい出力が正しい理由を PR に記載してください。
- 変動するデータはベースラインに入る前に正規化してください。パス、計測時間、ハッシュ、環境情報によって、スナップショットの更新が繰り返し発生しないようにします。
- 互換性を示す成果物を明確に残してください。
tests/snapshots/check、tests/snapshots/lint、実際のプロジェクトのフィクスチャのスナップショット、Vue 互換性マトリックスが互換性の記録になります。 - PR の対象外の出力を含む、大規模なスナップショット更新は行わないでください。多くのファイルが同時に変わる場合は、共通する原因を簡潔に説明してください。
検証を広げる条件
次の変更では、対象を絞ったテストに加えて、より広い範囲の検証を行ってください。
- 構文、変換、仮想 TypeScript の動作が通常の Vue アプリケーションに影響する場合は、実際のプロジェクトのフィクスチャを追加・更新し、公式 Vue ツールとの互換性を説明してください。
- 生成コードの構造、キャッシュ、プロジェクトグラフの探索、型情報を使う解析が処理速度に影響する場合は、対象に合うローカルベンチマークを実行し、PR の性能予算による判定も確認してください。
- URL 処理、HTML・SSR 出力、設定の読み込み、パッケージ公開、ネイティブコードの読み込み、CI、認証情報の周辺を変更する場合は、セキュリティ監査の結果を記録し、境界が引き続き守られることを示す回帰テストを追加してください。
- パーサーの回復処理、任意のバイト入力、CSS・テンプレート・式の解析、クラッシュを修正する場合は、対応する fuzz ターゲットを実行するか実行を予定し、再現例を保存してください。修正の Issue を閉じる前に、最小化した再現例を決定論的な回帰テストとして取り込んでください。
- LSP、エディター、クイックフィックス、補完、ホバー、増分処理を変更する場合は、最後に出る診断だけでなく、利用者の一連の操作を再現するシナリオテストを追加してください。
- パス、ハッシュ、順序、計測時間、環境、ホストのプラットフォームによってスナップショットが変わる場合は、まず正規化してください。その後に残る差分が意味のある場合だけ、ベースラインを更新してください。
継続して確認する仕組み
Vize では、これらの方針を記憶に頼らず実行できるよう、次のファイルや CI に組み込んでいます。
CONTRIBUTING.mdは、変更の種類に応じた検証を貢献者に案内します。.github/PULL_REQUEST_TEMPLATE.mdは、動作の根拠、リスク、検証結果の記載を求めます。tools/benchmarks/scripts/test-inventory.tsは、PR の CI で現在のテスト資産を集計します。.github/workflows/benchmark.ymlは、ベースと変更後の CLI の性能を比較し、PR の性能予算を適用します。.github/workflows/check.ymlのsecurity-auditは、本番用 npm・Rust 依存関係の脆弱性情報を確認します。.github/workflows/fuzz.ymlは、tests/fuzzの cargo-fuzz ワークスペースを実行し、パーサー・コンパイラの調査に使うクラッシュ再現例をアップロードします。docs/release/production-readiness.mdとdocs/release/vue-parity-matrix.mdは、本番利用に対応している、または互換性があると判断できる条件を定めます。tests/tooling/language-engineering-practices.test.tsは、このページ、貢献ガイド、PR テンプレートの対応を確認します。
参考資料
以下の TypeScript の JavaScript 実装に関する記述は、v5.9.3
(コミット c63de15)を参照しています。
既存の JS のベースラインの手法を確認できる参照先を固定したもので、最初の調査で使ったコミットを復元したものではありません。
現在の Go によるネイティブ実装のパスやタスクは、
現在の TypeScript の貢献ガイド を参照してください。
| 出典 | 参考にした手法 | Vize への適用 |
|---|---|---|
rust-lang/rust と rustc-dev-guide |
compiletest は UI テストをスイートごとにまとめ、期待する出力をソースケースの近くに保存します。tidy でリポジトリの不変条件を確認し、エコシステムと性能の回帰は別に追跡します。 |
コンパイラに関わる変更では、まずフィクスチャを追加・更新します。パーサー・コンパイラの期待値は tests/fixtures と tests/expected に、リポジトリの不変条件は tests/tooling/*.test.ts に残します。 |
rustc のエコシステム・性能テスト |
Crater、cargotest、大規模プロジェクトのビルダー、rustc-perf により、コンパイラの変更をマージする前後で、広い範囲の互換性や性能のリスクを明らかにします。 | Vue の意味解析、生成コードの構造、頻繁に実行される処理への広い影響は、単体テストだけで判断せず、実際のプロジェクトのフィクスチャ、Vue 互換性マトリックス、PR の性能予算でも確認します。 |
rust-fuzz/cargo-fuzz と libFuzzer |
カバレッジを使って入力を探索する fuzz ターゲットが任意のバイト列を処理し、コーパスを保存します。クラッシュの再現例を最小化してから、決定論的な回帰テストに変換します。 | クラッシュ修正を完了とする前に、tests/fuzz から cargo +nightly fuzz run <target> を使い、パーサー、字句解析器、CSS、式、テンプレートのコンパイルの境界を fuzzing で検証します。 |
| Linux カーネルのテスト | KUnit は小さな単位の内部動作を、kselftest は利用者に公開されるシステムインターフェースを検証します。KCOV はカバレッジを使う fuzzing に情報を提供し、perf stat は再現可能なカウンターと時間の計測結果を記録します。 |
小さなクレート単位の検証と、CLI・ワークスペースの統合検証を分けます。任意の入力はカバレッジや fuzzing で確認し、頻繁に実行される処理が変わる場合はプロファイルやベンチマークの結果を添えます。 |
| Chromium のテストと CQ | Chromium は外部環境に依存しない単体テスト、ブラウザ、Web、Telemetry、fuzzer のテストを組み合わせます。CQ・trybot は負荷が高い検証や不安定な検証を明示し、ClusterFuzz は検出された fuzz ターゲットを大規模に実行します。 | 通常の Vize の検証は外部環境に依存しないようにします。ブラウザ・アプリの動作は実際のプロジェクトのフィクスチャでも確認し、Telemetry に相当する状況把握には PR の性能予算を使います。調査用の fuzz 再現例も保存します。 |
| V8 のテスト と 機能のリリース手順 | V8 は mjsunit や Test262 などのエンジン用スイートを実行し、期待値のファイルはレビュー後に再生成します。tools/run_perf.py とベンチマーク比較を使い、言語機能のリリース前に fuzzing を求めます。 |
Vue・TS の互換性の変更を言語機能の変更として扱います。元の動作の出典を示し、シナリオテストを追加し、必要な場合は性能を比較し、利用段階を引き上げる前に fuzzing を実行するか実行を予定します。 |
microsoft/TypeScript |
Hereby のタスクグラフは、ビルド、整形、lint、テスト、ベースラインのタスクを分けます。コンパイラの出力は、baseline-accept の前に tests/baselines/reference とローカルで生成した出力を比較してレビューします。 |
スナップショットはレビュー済みの契約として維持します。tests/snapshots/* や Rust の insta スナップショットが変わる場合は、PR で理由を説明し、変更した動作に範囲を限定してください。 |
TypeScript tests/cases/fourslash |
エディター向けの言語サービスの動作を、コンパイラのテストから推測せず、数千のシナリオファイルとして記録します。 | LSP、クイックフィックス、補完、ホバー、エディターの増分処理には、パーサー・コンパイラのフィクスチャに加え、シナリオ単位で基本動作や統合を検証するテストが必要です。 |
microsoft/typescript-go |
ネイティブ移植版は TypeScript のサブモジュールを参照実装として保持し、最小限のコンパイラテストを追加します。生成した出力を testdata/baselines/local に保存し、縮小した .diff ベースラインを参照実装に近づいたことの根拠とします。 |
Vize 固有のルールを導入する前に、公式 Vue・TypeScript の動作と Vize の出力を比較してください。意図的に動作を変える場合は、その理由と互換性の区分を記載してください。 |
facebook/flow |
Flow は、ディレクトリ単位の統合テストと期待する出力の .exp を維持し、意図的な出力変更の再記録を支援します。エディターやサーバーの処理には、操作と検証を組み合わせる newtests を使います。 |
診断やエディターの処理には、小さなシナリオフィクスチャを優先します。スナップショットの再記録は差分をレビューし、生成時のノイズがベースラインに入らないことを確認してから受け入れます。 |