Keep component-less routes matchable in the Vue Router compat layer
What does this MR do and why?
This MR fixes the Uncaught Error: No match for router error that occurs in the merge request list under Vue 3 whenever the user filters, sorts, switches tab, or changes page.
The fix adds a placeholder component to routes in the Vue Router compat layer that have no component, name, redirect, or children. This restores Vue Router 3 behaviour. Routes with children are not modified: Vue Router 4 handles component-less parents, and a placeholder there would shadow the nested router-view. Vue 2 behaviour does not change: the helper only runs under Vue 3.
Changes are made to:
app/assets/javascripts/lib/utils/vue3compat/vue_router_helper.js:transformRoutesadds the placeholderapp/assets/javascripts/lib/utils/vue3compat/vue_router.js: reuses the same placeholder for the default route
Root cause
app/assets/javascripts/merge_requests/list/index.js creates its router with routes: [{ path: '/' }], a route with no component, name, or redirect.
Vue Router 3 matched such a route. Vue Router 4 drops it silently: its isMatchable() check only inserts a record that has a name, a components entry, or a redirect. The router has zero matchers as a result.
The initial resolve only logs a console warning. But every this.$router.push({ query }) call (6 call sites in merge_requests_list_app.vue) resolves against the current route path in an empty matcher table and throws MATCHER_NOT_FOUND.
The hypothesis in the issue (trailing slash or location shape) was wrong. The path is fine; the route table is empty.
app/assets/javascripts/todos/index.js declares the same bare route. Todos is already Vue 3 migrated but never calls $router, so it has no symptom yet.
The Jest spec for the list app replaces router.push with jest.fn(), so the Vue 3 Jest job never caught this.
Verification in CI
The pipeline at https://gitlab.com/gitlab-org/gitlab/-/pipelines/2846185045 ran on an earlier revision of this branch. That revision included two temporary commits for testing:
vue3_migration.ymlfiles and a temporary flag to run the project, group, and dashboard merge request list pages under Vue 3.- A console check cherry-picked from !255199, which fails any feature spec that logs a SEVERE browser console message.
The label pipeline:run-rspec-vue3 scheduled 32 rspec system pg17 vue3 jobs. Results:
- Zero
No match formessages appeared in all Vue 3 system job traces. Every merge request list filter and sort spec in the issue passed under Vue 3. - Exception:
spec/features/merge_requests/user_filters_by_deployments_spec.rb(examples at lines 68 and 80) failed under Vue 3 withUncaught TypeError: Cannot read properties of null (reading 'emitsOptions')when the date picker opened. This is a separate Vue 3 compat bug, not the router error fixed in this MR, and is out of scope. Under Vue 2 the same spec only trips the known GFM autocompletereading 'text'console noise from the reveal check. - Other failures: Most remaining system jobs in that pipeline failed because the reveal check trips pre-existing console errors across the suite (catalogued in #628901). This is expected and unrelated.
The current revision of this branch contains only the compat layer fix and its tests.
How to set up and validate locally
- Run
VUE_VERSION=3 yarn jest spec/frontend/lib/utils/vue3compatto run the compat layer tests under Vue 3. - Run
yarn jest spec/frontend/lib/utils/vue3compatto run the same tests under Vue 2. - Run
VUE_VERSION=3 yarn jest spec/frontend/merge_requests/list spec/frontend/todosto run the merge request list and todos specs under Vue 3. - Revert the two files under
app/assets/javascripts/lib/utils/vue3compat/. Run step 1 again to see the new test fail withNo match for.
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
- I have evaluated the MR acceptance checklist for this MR.
References
- Closes #628844 (closed)
- Surfaced by the reveal merge request !255199
- Failing pipeline https://gitlab.com/gitlab-org/gitlab/-/pipelines/2843011566 (jobs https://gitlab.com/gitlab-org/gitlab/-/jobs/16462296276, https://gitlab.com/gitlab-org/gitlab/-/jobs/16462296282, https://gitlab.com/gitlab-org/gitlab/-/jobs/16462296290)
- Vue 3 migration (Code Review) epic gitlab-org#23167
- Verification pipeline https://gitlab.com/gitlab-org/gitlab/-/pipelines/2846185045 and the console error catalogue #628901
- Second affected caller:
app/assets/javascripts/todos/index.js(already migrated under !251248 (merged))