ビルド成果物をGit管理から除外し、ビルドステップを各フローに組み込む
JavaScriptのビルド成果物(lexxy.js等)をGit管理から除外し、CI・gem build・bin/setupそれぞれのフローにyarn buildを自動的に組み込むことで、PRごとのマージコンフリクトを解消しつつ、各利用シーンで必要なアセットが確実に生成される仕組みを整備しました。
背景
app/assets/javascript/以下のビルド成果物が、ソースコード変更を含むすべてのPRでマージコンフリクトを引き起こしていました。lexxy.js(14,087行)・.min.js・.br・.gzはいずれもyarn buildが生成するアーティファクトであり、ソースコードとしての意味を持ちません。バンドル結果のような大容量生成ファイルをバージョン管理に含めると、差分ノイズの増加・コンフリクトの頻発・レビューコストの増大といった問題が生じます。
これらのファイルは.gitignoreで/app/assets/javascript/*.js.mapのみが除外されており、成果物本体は追跡対象のままでした。本PRはこの設計上の不整合を解消するものです。
技術的な変更
ビルド成果物の除外と、それを補うビルドステップの追加が3箇所に施されました。
.gitignoreの変更では、ファイル単位の除外パターンからディレクトリ単位の除外パターンへ変更されています。
変更前:
-/app/assets/javascript/*.js.map
変更後:
+/app/assets/javascript/
これにより、現在存在するlexxy.js・lexxy.min.js・.br・.gzだけでなく、将来生成されるいかなる成果物も追跡対象に入らなくなります。CSSのソースファイルはapp/assets/stylesheets/に、JSのソースファイルはsrc/にあるため、javascript/ディレクトリを丸ごと除外しても追跡すべきファイルは失われません。
Rakefileの変更では、yarn_buildタスクを定義し、Rake::Task["build"].enhanceを使って既存のbuildタスクの前処理として差し込んでいます。
task :yarn_build do
sh "yarn build"
end
Rake::Task["build"].enhance([ :yarn_build ])
enhanceメソッドは既存タスクの定義を書き換えずに依存タスクを追加できるため、bundler/gem_tasksが定義したbuildタスクを侵襲することなく前処理を注入できます。これによりgem build(Rakeのbuildタスク)を実行すると自動的にyarn buildが先行し、gemファイルに最新のビルド成果物が同梱されます。
CIとセットアップスクリプトの変更では、rails-system-testsジョブのyarn installステップの直後にyarn buildステップが追加され、bin/setupでもyarn installの直後にyarn buildが実行されるようになりました。PRの説明によれば、ビルド済みアセットを必要とするのはRailsシステムテストのジョブのみであり、PlaywrightやVitestのジョブには変更はありません。
設計判断
「ビルド成果物はディスクに生成するが、Gitには含めない」 という原則を、gem配布・CI・開発環境セットアップの3つの経路すべてで一貫させた設計です。
各経路でyarn buildを呼び出すタイミングを明示的に管理することで、「Gitから取得するだけでは動かない」という状態を許容しつつ、「各フローの正しいステップで必ずビルドが実行される」ことを保証しています。lexxy.gemspecのglobはビルド時にディスク上のファイルを拾うため、gemspec自体の変更は不要です。
また、Rake::Task["build"].enhanceによる注入は、bundler/gem_tasksが提供するタスクを直接上書きしない低侵襲なアプローチです。Rakeの依存関係解決に委ねることで、将来的なbundler側の変更にも追従しやすくなっています。
まとめ
ビルド成果物の除外とビルドステップの各フローへの組み込みを同時に行うことで、マージコンフリクトの根本原因を取り除きながら、gemの配布・CI・ローカル開発のいずれの経路でも成果物が欠けない状態を維持しています。変更の規模は小さいものの、「何をGitで管理し、何をビルドプロセスに委ねるか」という境界を明確に引き直した設計上の整理といえます。