3x-ui/docs/migrations/vue3-phase1-inventory.md
MHSanaei f874060a4d
docs(migration): Phase 1 inventory — Vue 2 / AD-Vue 1 surface area
Captures the breakage surface for the Vue 3 + Ant Design Vue 4 + Vite
migration: 17,650 lines across 69 templates, 3,145 a-* component
instances across 63 files, with per-pattern counts and file lists.

Key findings:
- No Vue filters anywhere — dodges a major Vue 3 breaking change
- 358 v-model uses; AD-Vue 4 absorbs most, custom components don't
- 233 <template slot="X"> usages must become <template #X>
- 49 scopedSlots: { ... } column defs need new slots: { ... } shape
- a-icon is removed in AD-Vue 4 — every icon must be imported

Establishes the 8-phase order; Phase 2 (Vite toolchain) is next.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 10:33:24 +02:00

101 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Vue 3 + Ant Design Vue 4 Migration — Phase 1 Inventory
Branch: `vue3-migration`
Source state: Vue 2 + Ant Design Vue 1.7.8, no build step, Go template-driven.
## Scope
- **69 HTML templates**, ~17,650 total lines
- **Largest pages:**
- `web/html/xray.html` — 2,360 lines
- `web/html/index.html` — ~1,700 lines
- `web/html/settings.html` — 720 lines
- `web/html/settings/xray/outbounds.html` — 263 lines
## Vue 2 → Vue 3 breakage surface
| Pattern | Count | Files | Severity | Notes |
|---|---:|---:|---|---|
| `{{ x \| filter }}` | **0** | 0 | ✅ none | Filters removed in Vue 3 — but we don't use any. |
| `<template slot="X">` | 233 | 36 | medium | Rewrite to `<template #X>`. Mechanical. |
| `slot-scope="X"` (incl. above) | 275 total | 40 | medium | Rewrite to `v-slot:name="X"`. Mechanical. |
| `scopedSlots: { ... }` (in JS column defs) | 49 | 4 | medium | Vue 3 removed `scopedSlots`. All slots are now scoped. Replace with `slots: { ... }` or rely on template slot binding only. |
| `new Vue({...})` mounts | ~30+ | 30 | medium | Replace with `createApp({...}).mount('#id')`. Each page mounts its own Vue instance. |
| `Vue.use / Vue.component / Vue.prototype` | <49 (after subtracting mounts) | various | medium | Replace with `app.use / app.component / app.config.globalProperties`. |
| `$listeners` / `$on` / `$off` / `$once` / `$children` | 4 | 4 | low | Mostly inside `aTableSortable.html`. `$listeners` merged into `$attrs`. Event-bus methods removed need an explicit emitter (mitt, or component refs). |
| `inline-template` / `functional` | 1 | 1 | trivial | One occurrence. |
| `.sync` modifier | 0 | 0 | none | Removed in Vue 3, replaced by `v-model:propName`. We don't use it. |
| `v-model` | 358 | 36 | **high** | Default `v-model` on custom components changed (`value` `modelValue`, `input` event `update:modelValue`). Most of these target AD-Vue components, which AD-Vue 4 already adapts to internally but components we wrote ourselves (e.g. `aClientTable`, `aTableSortable`) need updates. |
| `Vue.set` / `Vue.delete` / `Vue.observable` | 0 | 0 | none | Replaced by `reactive()`. Not needed. |
| `transition` class names (`-enter`, `-leave`) | 1 (in `qrcode_modal.html`) | 1 | low | Renamed in Vue 3: `*-enter` `*-enter-from`, `*-leave-to` stays, etc. |
| Key modifiers using `keyCode` (`@keyup.13`) | 0 | 0 | none | Number key codes removed in Vue 3. We don't use them. |
| `ref="..."` attrs | 21 | 9 | low | Behavior unchanged for Options API refs still work the same. |
| `.native` event modifier | 0 | 0 | none | Removed in Vue 3 (events on components are no longer "fake" by default). |
## Ant Design Vue 1.x → 4.x breakage surface
Total `<a-*>` component instances: **3,145 across 63 files**. This is the bulk of the migration cost.
The most-used components (rough estimate from grep):
- `a-input`, `a-select`, `a-button` heavily used; props mostly stable, but `<a-select-option>` slot syntax changed
- `a-form` + `a-form-item` Form API was substantially redesigned in AD-Vue 3+. We use it lightly (`layout="vertical"`, `label-col`, `wrapper-col`); migration is mechanical but every form needs touching.
- `a-table` column definitions with `scopedSlots` (49 instances) need to become `slots: { customRender: 'name' }` or use template slot binding directly.
- `a-modal` **`v-model` on a-modal changed**: `v-model="visible"` `v-model:open="visible"` (or `v-model:visible` depending on version). Every modal needs updating.
- `a-icon` **removed as a generic component in AD-Vue 4.** Each icon must be imported individually from `@ant-design/icons-vue`. We use ~233 `a-icon` references mostly via `type="..."` attribute. Likely the single highest-friction change.
- `a-tooltip`, `a-popover`, `a-drawer` slot-based titles (`<template slot="title">` → `<template #title>`).
- `a-collapse` + `a-collapse-panel` — header slot syntax changes.
- `a-tabs` + `a-tab-pane``tab` slot rewrite, possibly renamed.
- `a-space` — exists in AD-Vue 4, props stable.
- `a-tag` — stable.
## Key custom code
- `web/assets/js/util/index.js` — utilities (HttpUtil, ObjectUtil, ClipboardManager, SizeFormatter, etc.). Framework-agnostic. **Trivial migration** (no Vue dependency).
- `web/assets/js/axios-init.js` — axios setup. **Trivial migration**.
- `web/assets/js/websocket.js` — websocket client. **Trivial migration** (we recently refactored this).
- `web/assets/js/model/{inbound,outbound,dbinbound,setting,reality_targets}.js` — domain model classes. Plain JS. **Trivial migration**.
- `web/assets/js/subscription.js` — subscription page logic.
- Custom components in `web/html/component/`:
- `aClientTable.html` — non-trivial; uses scoped slots and v-model
- `aSidebar.html` — sidebar navigation
- `aThemeSwitch.html` — theme picker
- `aPersianDatepicker.html` — wraps a third-party datepicker
- `aTableSortable.html` — uses `$listeners`, `$on` — needs explicit refactor
- `aSettingListItem.html`, `aCustomStatistic.html` — small wrappers
- These are the **only places using the deprecated event-bus APIs** (4 occurrences).
## Server-side coupling
The Go layer interpolates translations directly into templates via `{{ i18n "key" }}`. After migration we have two options:
- **Keep Go-side i18n.** Vite builds .html partials that still get processed by Go's `template` package. Means `<script type="module">` entrypoints reference build artifacts but markup is still server-rendered. Pro: smallest change. Con: every page change forces a Vite rebuild *and* a Go restart.
- **Move i18n to client side.** Export the translation TOML files as JSON, ship as static assets, use `vue-i18n`. Pro: cleaner client/server split, hot reload during dev. Con: more change, every i18n key reference in templates must be rewritten.
We will defer this decision to Phase 7. For Phases 24 we keep the Go-side approach.
## Risk-ranked migration order
Order chosen so that breakage is contained and we always have a working panel:
1. **Phase 2 — Toolchain.** Vite scaffold; Go binary embeds `dist/` via `embed.FS`. New build runs in CI alongside existing static assets; legacy continues to work.
2. **Phase 3 — Utils.** Migrate framework-agnostic JS first. Zero Vue dependency, zero risk.
3. **Phase 4 — `login.html`.** Smallest page with state. Hits every Vue 2→3 syntax change and every AD-Vue 1→4 component change at small scale. Becomes the template the rest follow.
4. **Phase 5 — Medium pages and modals.** `index.html`, `settings.html`, all modals. ~30 templates of 200-1000 lines each.
5. **Phase 6 — `xray.html`.** The 2,360-line page with the inbound/outbound editors. Highest regression risk — will likely break and need fixing in the QA pass.
6. **Phase 7 — i18n decision.**
7. **Phase 8 — Regression pass + delete legacy templates + cut release.**
## Numbers to remember
- **68 weeks** of focused work, single developer
- **63 HTML files** to touch
- **3,145 AD-Vue component instances** to validate
- **One** assumption that needs confirming with the user: build step OK (yes — confirmed by choice of Vite)
## Confirmed user decisions
- ✅ Migrate to Vue 3 + Ant Design Vue 4
- ✅ Introduce Vite build step (npm acceptable)
- ✅ Work on a long-running `vue3-migration` branch
- ⏸ i18n strategy — to be decided in Phase 7