Introduce vue3_migration.yml config file

What does this MR do and why?

Introduces a declarative, co-located metadata format for tracking Vue 3 migration state per page entry. Each page that opts into migration adds a sibling vue3_migration.yml file next to its index.js.

The bundler reads these files to decide whether to emit a .vue3 chunk, and Rails chooses which chunk to serve at request time. In development and test Rails reads the yml files directly, in production it reads a vue3_migration.json manifest compiled by the bundler (see "Packaged builds" below).

Why?

This MR helps team members across our groups to "opt-in" their apps to use Vue 3 (@vue/compat) with a yml file + a feature flag.

Why use a yml config?

Today, switching a page between Vue 2 and Vue 3 requires changes in three different places:

  • A ?vue3 dynamic import inside the page's index.js.
  • A gon.features.vue3Migrate* runtime branch inside the same file.
  • A push_frontend_feature_flag(:vue3_migrate_*, current_user) call in the controller that pushes the flag to gon.features.

The bundler has no way to know which pages are mid-migration without parsing the JS source. This MR reduces boilerplate with a config file per page that the webpack/vite and Rails read from.

MRs

you are here! Introduce vue3_migration.yml config file (!234347 - merged)
Roll out vue3_migration.yml to remaining Vue pages (!236797 - merged)

How it works

vue3_migration.yml has one required status field with two possible values:

Status Bundler Rails
rollout Vue 2 + Vue 3 chunks (.vue3 sibling) Serves Vue 3 when feature_flag is enabled
migrated Vue 3 chunk only, under the original entry name Always serves Vue 3 (no lookup needed)

Pages without a vue3_migration.yml stay on Vue 2.

Note: When a page has an index.js in more than one root (for example pages/projects/jobs/show in both app/ and ee/), the corresponding YAML files must agree on status and feature_flag.

Packaged builds (Omnibus/CNG)

Omnibus strips app/assets from the packaged Rails app, so the yml files are not available at runtime in production (see !234347 (comment 3605473854)). To make the rollout work "statically", the bundler (webpack and rspack) compiles the rollout entries into public/assets/webpack/vue3_migration.json.

In production Rails reads that manifest and raises when it is missing (instead of silently serving Vue 2) so Omnibus and CNG package builds cannot ship without it.

Scope of this MR

Infrastructure

  • Bundler loader (config/helpers/vue3_migration_loader.js): walks pages/**/vue3_migration.yml, parses + validates each file, and produces a maps of entrypoints consumed by both Webpack and Vite.
  • Manifest plugin (config/plugins/vue3_migration_manifest_plugin.js): emits vue3_migration.json with the rollout entries during the build, wired into both webpack and rspack.
  • Rails resolver (lib/gitlab/vue3_migration.rb): exposes Gitlab::Vue3Migration.entrypoint_for(name, current_user:) which swaps the correct entrypoint file if the feature flag is enabled. Reads the yml files in development and test, and the compiled manifest in production.

One feature flag is migrated as a working example

This MR migrates vue3_migrate_jobs at:

  • pages/projects/jobs/show
  • pages/projects/jobs/index
  • pages/admin/jobs/index

For each page:

  • Added a vue3_migration.yml with status: rollout and feature_flag: vue3_migrate_jobs.
  • Simplified the page's index.js: removed the gon.features.vue3MigrateJobs branch and the dynamic ?vue3 import. The file is now a single import + initializer call.
  • Removed push_frontend_feature_flag(:vue3_migrate_jobs, current_user) from the corresponding controllers.

How to review

Local verification

This MR change the vue 3 migration method for the jobs apps. Locally you can check that the jobs apps are running in Vue 3 when you enable the feature flag.

  1. Enable the FF vue3_migrate_jobs e.g. https://gdk.test:3443/rails/features/
  2. Visit the migrated job pages
  1. Check the console message indicated the pages are running in Vue 3.

[gitlab] [V] Using Vue.js 3 (with @vue/compat) for AdminJobsTableAppRoot

Screenshot_2026-05-21_at_12.00.02

Production assets verification

You can run the production build and verify that the manifest if built correctly:

$ bundle exec rake gitlab:assets:compile # (or yarn rspack-prod)
$ cat public/assets/webpack/vue3_migration.json
{
  "pages.admin.jobs.index": {
    "feature_flag": "vue3_migrate_jobs"
  },
  "pages.projects.jobs.index": {
    "feature_flag": "vue3_migrate_jobs"
  },
  "pages.projects.jobs.show": {
    "feature_flag": "vue3_migrate_jobs"
  }
}

Packaged build verification

The e2e:test-on-omnibus-ee job runs the new QA spec (test case: https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/606899) against the Omnibus image built from this MR, replacing the manual docker run ... find check from the review thread.

Follow-up work

Migrating the remaining vue3_migrate_* flags to the new format (one MR per flag):

  • vue3_migrate_work_items
  • vue3_migrate_pipelines
  • vue3_migrate_admin_runners
  • vue3_migrate_compliance_center

References

Edited by Miguel Rincon

Merge request reports

Loading