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
mainchunk is renamed tocommon, becausemainis now an entry name. - The
defaultentry is removed, along with thewebpack_controller_bundle_tagsfallback that served it.mainis already on the page, so a page with no entry of its own needs nothing extra. generateEntriesno longer takes adefaultEntriesargument.applyVue3Migrationsno longer needs to skip it. Nothing passes it any more.maincan now declare avue3_migration.ymlfile 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 webpackbuild. It exits 0, produces 746 entrypoints, and has nodefaultentry.
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.jsis nowcommon.chunk.js.main.chunk.jsis now the newmainentry's own chunk. Nothing in this repository hardcodes either name, but anything outside it that does would need updating. - Rolling
mainout to Vue 3 would move every app it initializes at once. That is a separate decision. This MR does not add avue3_migration.ymlfile formain.
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