Draft: Build main as a standalone webpack entry

This MR is stacked. It targets branch 623999-vue3-migration-yml-global-bundles, not master. It depends on the merge request at !252286 (merged).

What does this MR do and why?

main had no bundle name. config/helpers/entry_points.js declared it as default: ['./main']. generateEntries prepended that array to every page entry, about 630 of them. A splitChunks cache group then hoisted the shared modules back out into their own chunk.

The Vue 3 rollout switch works by serving <entry>.vue3 in place of <entry>. An entry that is not a bundle cannot take part in that switch. Because of this, everything main reaches was locked to Vue 2. This includes main_ee.js and main_jh.js, which main imports through the ee_else_ce alias.

This MR makes main its own webpack entry, so it can get a vue3_migration.yml file like any other bundle in a later MR.

Approach

Declare main as its own entry. Render it from app/views/layouts/_head.html.haml, ahead of the page entry.

This matches how Vite already works. config/vite.json globs entrypoints/, and app/views/layouts/_vite_main.html.haml emits main.js as its own script tag. This change brings webpack in line with that shape. It does not add a new shape.

Load order still holds. GitlabScriptTagHelper overrides javascript_include_tag to set defer on every script tag, and deferred scripts run in document order, so main still executes before the page entry. optimization.runtimeChunk: 'single' makes separate entries share one module registry, so nothing runs twice. super_sidebar and sentry have been separate script tags on the same page all along.

Knock-on changes:

  • The splitChunks cache group that used to produce the main chunk is renamed to common, because main is now an entry name.
  • The default entry is removed, along with the webpack_controller_bundle_tags fallback that served it. main is already on the page, so a page with no entry of its own needs nothing extra.
  • generateEntries no longer takes a defaultEntries argument. applyVue3Migrations no longer needs to skip it. Nothing passes it any more.
  • main can now declare a vue3_migration.yml file like any other bundle. The loader, the Ruby resolver, and the files spec no longer reject one. The docs are updated to match.

How to verify

  • Run yarn jest spec/frontend/config/webpack_helpers_spec.js. It passes: 9 examples.
  • Run bundle exec rspec spec/lib/gitlab/vue3_migration_spec.rb spec/lib/gitlab/vue3_migration_files_spec.rb spec/helpers/webpack_helper_spec.rb spec/helpers/vite_helper_spec.rb. It passes: 952 examples, 0 failures.
  • Run a full yarn webpack build. It exits 0, produces 746 entrypoints, and has no default entry.

The build manifest shows the new chunk graph. Page entries are lean: they no longer carry main's modules. The browser gets those from the main script tag emitted just before the page entry. webpack_entrypoint_paths de-duplicates runtime.bundle.js and common.chunk.js across the two tags within one request.

entry chunks
main runtime.bundle.js, common.chunk.js, monaco.chunk.js, 17 shared chunks, main.chunk.js
super_sidebar runtime.bundle.js, common.chunk.js, 18 shared chunks, super_sidebar.chunk.js
pages.admin.applications runtime.bundle.js, common.chunk.js, 3 shared chunks, pages.admin.applications.chunk.js

No browser check was run. A local Vite dev-server check would not tell us anything here, because Vite already emitted main.js as its own entry before this change. Webpack is what this MR alters.

Risks

  • This changes the chunk graph of every page. Read the bundle-size job on this MR for the real measurement. Do not rely on the local build numbers above for that.
  • Asset file names change. The shared chunk that used to ship as main.chunk.js is now common.chunk.js. main.chunk.js is now the new main entry's own chunk. Nothing in this repository hardcodes either name, but anything outside it that does would need updating.
  • Rolling main out to Vue 3 would move every app it initializes at once. That is a separate decision. This MR does not add a vue3_migration.yml file for main.

Open questions

The tracking issue flags this phase as needing sign-off before merge, because of the chunk-graph change. This MR is a Draft so reviewers can check the shape of the change and the bundle-size numbers first.

References

#623999 — tracking issue; this is Phase 3 of that plan !252286 (merged) — Phase 1, which this MR targets and depends on !252280 (closed) — Phase 0, the infection guard &6252 — parent epic

Edited by Miguel Rincon

Merge request reports

Loading
Loading