Mark bundles that never import Vue as migrated to Vue 3

What does this MR do and why?

These bundles never import Vue:

  • Global bundles:
    • sentry
    • coverage_persistence
    • tracker
    • sandboxed_mermaid_v11
    • sandboxed_mermaid_v12
    • sandboxed_swagger
  • Page entries:
    • pages.help.index
    • pages.search.admin.vector_storage (EE only)

Their Vue 3 build runs the same code as their Vue 2 build, so a feature flag rollout would switch nothing. This MR adds a vue3_migration.yml with status: migrated for each one. A migrated entry builds only the Vue 3 bundle, under its original name, with no flag.

95e2f1e0 did the same for the EE path locks page, which mounts no Vue app.

The production behaviour does not change. The evidence is below.

Evidence: no change in production

1. dependency-cruiser: the entries reach no Vue module

dependency-cruiser followed every import, including node_modules and dynamic imports, with the webpack resolve config. It counted modules from vue, @vue/*, vue-*, @gitlab/ui, pinia and vuex, and any .vue file.

A page entry also imports the index.js of each ancestor page, and migrated builds those ancestors as Vue 3 too. So for pages, the check walks the full entry, ancestors included.

Entry Entry modules Modules reached Vue modules or .vue files
sentry sentry/index.js 336 0
coverage_persistence entrypoints/coverage_persistence.js 1 0
tracker entrypoints/tracker.js 57 0
sandboxed_mermaid_v11 lib/mermaid_v11.js 2665 0
sandboxed_mermaid_v12 lib/mermaid_v12.js 4116 0
sandboxed_swagger lib/swagger.js 43 0
pages.help.index pages/help/index/index.js 5 0
pages.search.admin.vector_storage ee/…/pages/search/admin/vector_storage/index.js 1 0

dependency-cruiser could not resolve three imports inside the mermaid dependencies:

  • web-worker, an optional Node-only import in elkjs.
  • cose-base and layout-base, graph layout libraries used by the cytoscape plugins.

None of them is a Vue package. The build check below covers them, because webpack resolves everything.

Page entries that were checked and left out

I checked all 256 page entries that have no vue3_migration.yml in any edition. Most reach Vue and stay in the final sweep. These come close, but are left out:

  • pages.admin.application_settings.network, pages.admin.spam_logs, pages.admin.identities.edit, pages.admin.identities.new and pages.groups.settings.domain_verification.index. Their own index.js reaches no Vue, but an ancestor entry does, for example pages/admin/index.js. migrated would switch that ancestor's Vue app on these pages.
  • pages.projects.settings.merge_requests. The CE copy reaches no Vue, but the EE copy does.
  • pages.iam.consent. It reaches no Vue, but the build check found a change. Babel injects core-js polyfill imports into the entry module, and the ?vue3 build gives the page a second copy of 95 core-js modules. main already loads the first copy.
Script
// For each entry, count the Vue modules it reaches.
import { cruise } from 'dependency-cruiser';
import extractWebpackResolveConfig from 'dependency-cruiser/config-utl/extract-webpack-resolve-config';

const VUE = /(^|\/)node_modules\/(vue|@vue|vue-[^/]+|@gitlab\/ui|pinia|vuex|@vue3-migration)\/|\.vue$/;
const resolve = await extractWebpackResolveConfig('config/webpack.config.js');

// `files`: the entry modules. For a page, its index.js and every ancestor
// index.js, from generateEntries() in config/webpack.helpers.js.
const { output } = await cruise(files, {
  combinedDependencies: true,
  enhancedResolveOptions: {
    exportsFields: ['exports'],
    conditionNames: ['import', 'browser', 'module', 'default'],
    mainFields: ['browser', 'module', 'main'],
  },
}, resolve);
const vue = output.modules.filter((m) => VUE.test(m.source));

2. Webpack: the production build runs the same code

I ran a production webpack build of these 8 entries with the real config/webpack.config.js, twice: once with the migration files and once without them. Minification was on. Compression and source maps were off. With the files, the entry modules carry the ?vue3 query, from applyVue3Migrations, the same function the real config uses.

  • 379 of the 381 JavaScript files are byte-identical. That includes all files of the 6 global bundles.
  • The 2 page chunks, pages.help.index and pages.search.admin.vector_storage, contain the same modules. The only change is the id of the entry module, which webpack hashes from its path and the ?vue3 query.
  • For all 375 chunks, the list of modules is the same once the ?vue3 suffix is removed.
  • manifest.json is identical, apart from the output path, log lines, and the hash and size of the 2 page chunks.
  • vue3_migration.json is identical. A migrated entry has no flag, so it is not listed.
How the build was run

The script replaces entry with the 8 entries, after it calls the original entry function, because splitChunks reads the entry counts that function sets. It writes the module list of every chunk from the webpack stats.

node --max-old-space-size=8192 tmp/build_compare.js master
node --max-old-space-size=8192 tmp/build_compare.js migrated
diff -rq tmp/cmp/master tmp/cmp/migrated
# Files tmp/cmp/master/manifest.json and tmp/cmp/migrated/manifest.json differ
# Files tmp/cmp/master/pages.help.index.chunk.js and tmp/cmp/migrated/pages.help.index.chunk.js differ
# Files tmp/cmp/master/pages.search.admin.vector_storage.chunk.js and tmp/cmp/migrated/pages.search.admin.vector_storage.chunk.js differ

3. Rails: the same entry name is served

Gitlab::Vue3Migration.entrypoint_for returns the name unchanged for an entry with no feature_flag. rollout? is false, so webpack_bundle_tag does not read current_user for these entries.

How to set up and validate locally

  1. Open any page and check that sentry and tracker load as before.
  2. Open /help.
  3. Open a Markdown file with a Mermaid diagram, and an OpenAPI file, to load the sandboxed bundles.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

References

  • Takes these entries out of the final sweep: !261154 (merged)
  • Same approach for a page with no Vue app: 95e2f1e0
  • Rollout issue for the final sweep: #633141
  • Vue 3 migration epic: &23285
Edited by Miguel Rincon

Merge request reports

Loading
Loading