Migration from Vue 2 to Vue 3
This epic is created to track the current state of migrating the codebase from Vue 2 to Vue 3. We aim to outline here the list of potential blockers and track the ongoing efforts. Please keep in mind this epic is planned to be very general/shallow as we plan to be more detailed in the sub-epics / linked issues [[_TOC_]] ## Next steps as of 2025-12-06 These are steps that aren't blocked, and can in theory be done in parallel. These are all the nodes in the [graph](#graph) with no dependencies. - https://gitlab.com/gitlab-org/gitlab/-/issues/520987+ - ... ## Process overview ### Graph Legend - Gray = GitLab repo task (Not started) - Green = GitLab repo task (Completed) - Yellow = GitLab repo task (In progress) - Blue = GitLab UI task - Purple = Switchboard task - Green outline = Non main GitLab repo task (Completed) - Yellow outline = Non main GitLab repo task (In progress) ```mermaid %%{init: {'flowchart': { 'nodeSpacing': 20, 'rankSpacing': 20 } } }%% graph TD %% Styles classDef gitlab %% fill:#6f8,color:#fff classDef gitlab_in_progress fill:#ffef00 classDef gitlab_complete fill:#3dc068 classDef gitlab_ui fill:#00a4ff,color:#fff classDef gitlab_ui_in_progress fill:#00a4ff,color:#fff,stroke:#ffef00,stroke-width:10px classDef gitlab_ui_complete fill:#00a4ff,color:#fff,stroke:#3dc068,stroke-width:10px classDef other fill:#a2a2d0,color:#fff classDef other_in_progress fill:#a2a2d0,color:#fff,stroke:#ffef00,stroke-width:10px classDef other_complete fill:#a2a2d0,color:#fff,stroke:#3dc068,stroke-width:10px classDef optional stroke-dasharray: 5 5 %% Nodes gitlab_use_gitlab_ui_source["`Make GitLab consume GitLab UI source`"]:::gitlab_complete gitlab_ui_vue_compat_package["`Publish versions built with @vue/compat to npm (gitlab-ui#1985)`"]:::gitlab_ui gitlab_jest_unquarantine["`Fix all GitLab Jest specs under @vue/compat quarantine`"]:::gitlab_complete gitlab_jest_unskip["`Fix all skipped @vue/compat GitLab Jest specs`"]:::gitlab_complete gitlab_gdk["`Add support for running GDK with @vue/compat`"]:::gitlab_complete gitlab_run_rspec["`Add support for running RSpecs with @vue/compat`"]:::gitlab_complete gitlab_run_qa["`Add support for running QA specs with @vue/compat`"]:::gitlab gitlab_fix_rspec["`Fix RSpecs with @vue/compat`"]:::gitlab_in_progress gitlab_fix_qa["`Fix QA specs with @vue/compat`"]:::gitlab gitlab_prod_build_vite["`Add support for a Vite production build with @vue/compat`"]:::gitlab gitlab_prod_build_vite_vue2["`Add support for a Vite production build with Vue 2`"]:::gitlab gitlab_prod_build_webpack["`Add support for a Webpack production build with @vue/compat`"]:::gitlab gitlab_feature_flagged_builds["`Add support for feature flagged asset builds`"]:::gitlab class gitlab_feature_flagged_builds optional switchboard_drop_compat_flags["`Drop compat flags in Switchboard`"]:::other switchboard_vue3["`Switch to Vue 3 in Switchboard`"]:::other gitlab_drop_vue2["`Drop support for Vue 2 in GitLab`"]:::gitlab gitlab_ui_drop_vue2["`Drop support for Vue 2 in GitLab UI`"]:::gitlab_ui_in_progress gitlab_ui_drop_compat_flags["`Drop compat flags in GitLab UI`"]:::gitlab_ui_in_progress gitlab_drop_compat_flags["`Drop compat flags in GitLab`"]:::gitlab gitlab_vue3["`Switch to Vue 3 in GitLab`"]:::gitlab gitlab_ui_vue3["`Switch to Vue 3 in GitLab UI`"]:::gitlab_ui %% Dependencies - kill webpack first gitlab_gdk --> gitlab_run_rspec gitlab_gdk --> gitlab_run_qa gitlab_feature_flagged_builds -.-> vite_or_webpack switchboard_drop_compat_flags --> switchboard_vue3 switchboard_vue3 --> gitlab_ui_vue3 gitlab_jest_unquarantine --> gitlab_drop_vue2 gitlab_jest_unskip --> gitlab_drop_vue2 gitlab_run_rspec --> gitlab_fix_rspec --> gitlab_drop_vue2 gitlab_run_qa --> gitlab_fix_qa --> gitlab_drop_vue2 vite_or_webpack --> gitlab_drop_vue2 gitlab_drop_vue2 --> gitlab_drop_compat_flags --> gitlab_vue3 gitlab_drop_vue2 --> gitlab_ui_drop_vue2 gitlab_ui_drop_vue2 --> gitlab_vue3 --> gitlab_ui_vue3 gitlab_ui_package ---> gitlab_gdk gitlab_drop_vue2 --> gitlab_ui_drop_compat_flags --> gitlab_ui_vue3 gitlab_ui_drop_compat_flags --> switchboard_vue3 gitlab_ui_drop_compat_flags --> gitlab_vue3 subgraph gitlab_ui_package["Either"] direction LR gitlab_use_gitlab_ui_source gitlab_ui_vue_compat_package end subgraph vite_or_webpack["Either"] direction LR subgraph vite["Vite"] direction LR gitlab_prod_build_vite_vue2 --> gitlab_prod_build_vite end subgraph webpack["Webpack"] gitlab_prod_build_webpack end end ``` ### Step 0: pre-migration - [x] remove the outdated `slot`/`slot-scope` attributes - [x] main codebase (https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64604 by @ntepluhina) - [x] GitLab UI - Mostly done in https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2269 - [x] Several chart components still use the deprecated slot syntax, and require particular attention due to more complex slot definitions and incomplete test coverage (see https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2269#note_612928917) - [x] set up linter rules to prevent deprecated APIs from being used (https://gitlab.com/gitlab-org/frontend/eslint-plugin/-/merge_requests/50#note_610914212 by @markrian) - [x] check how unit tests work with compat build and evaluate the effort for VTU 1 -> 2 migration - VTU 1 --> 2 migration could be mostly automated with codemods, however it is possible only when - [x] evaluate the effort of making class-based stores reactive - [x] check how Vuex works in compat build and evaluate the effort for Vuex v3 -> v4 migration - [x] check how VueApollo works in compat build and evaluate the effort for VueApollo 3 -> 4 migration - [x] check how Vue Router works in compat build and evaluate the effort for v3 -> v4 migration - [ ] evaluate Vue-related non-core dependencies in terms of their readiness for migration / working in compat build ### Step 1: "Vue3-friendly". Utilize `@vue/compat` for migration Child epic: https://gitlab.com/groups/gitlab-org/-/epics/9013+ At this point we want all our Vue-related project use `@vue/compat`: * [x] https://gitlab.com/gitlab-org/gitlab-ui (epic: https://gitlab.com/groups/gitlab-org/-/epics/7203) * [ ] https://gitlab.com/gitlab-org/gitlab (epic: TBD) * [ ] https://gitlab.com/gitlab-org/status-page (epic/issue: TBD) * [ ] https://gitlab.com/gitlab-org/customers-gitlab-com/ (epic: https://gitlab.com/groups/gitlab-org/-/epics/10121) * [ ] https://gitlab.com/gitlab-org/gitlab-design (epic: TBD) * [x] https://gitlab.com/gitlab-com/gl-infra/gitlab-dedicated/switchboard (epic: TBD) At this point we will be relying on [vue-test-utils-compat](https://www.npmjs.com/package/vue-test-utils-compat) to make our test suite compatible with Vue2 and `@vue/compat`. Our codebase should be tested and verified both with Vue2 and Vue3 with feature flag (or similar approach) flipping usage of vue version when needed Known blockers outside of GitLab: * [x] `bootstrap-vue` release with `@vue/compat` https://github.com/bootstrap-vue/bootstrap-vue/pull/6905 * [x] `@vue/test-utils` release with https://github.com/vuejs/test-utils/pull/1804 merged ### Step 2: "Vue3-first". Drop Vue.js 2 support (per project) After ensuring everything is working with `@vue/compat` each project **independently** will take decision to drop Vue2 support. `gitlab-ui` will be the last one as long as there will be no vue2-based consumers At this point we will move [vue-test-utils-compat](https://www.npmjs.com/package/vue-test-utils-compat) from being application-wide to specific explicit initialization in each test suite. This will allow us to write tests using `@vue/test-utils v2` while not being forced to rewrite all tests to `@vue/test-utils-v1`. For old tests we will switch compat flags one-by-one, applying codemods with fixes (approx. 80% of test suide could be automatically migrated to `@vue/test-utils v2` automatically) Also we will start migrating codebase to Vue3 by acting both horizontally and vertically. Under **vertical** migration we are considering disabling **compat flags** in `@vue/compat` one-by-one and performing mostly automated conversions to our codebase. Under **horizontal** migration we're considering migrating existing components to Vue3 by adding: `{ compatConfig: { MODE: 3 }}` to components. These approaches will take place simultaneously and decision will taken on per-case basics ### Step 3: Switch `@vue/compat` to `vue` (per project) As soon as `@vue/compat` will have all compat flags switched off, we should be able just swap `@vue/compat` with `vue` and be ready to go
epic