跪拜 Guibai
← Back to the summary

A Weekend-by-Weekend Vue 2 to Vue 3 Migration That Actually Shipped

Disclaimer: The refactoring was done during a business lull and did not delay normal iterations. Don't secretly do this like I did; it's best to report it in advance.

The company project is a 3-year-old Vue 2 backend system. The codebase isn't large (just over 50 pages), but it has a "long history" — it went through four frontend developers, each with a different style, no TypeScript, no component library standards, and console.log everywhere.

I spent three weekends (Friday nights + all day Saturdays) upgrading it to Vue 3 + TS + Vite. It wasn't to show off; I was genuinely fed up.

Week 1: Building the skeleton, solving the "it runs" problem

First, I ran the migration tool from @vue/cli, but it only solved about 30% of the issues. The rest was done manually:

  1. Options API → Composition API: This was the most painful part. Some component logic was scattered across data, computed, and methods. During the refactor, I had to first untangle the logical relationships. My strategy was: don't change the logic yet, just change the syntax, ensuring the behavior remains identical.
  2. Vue Router 3 → 4: The main issue was that router.addRoutes was deprecated and replaced with router.addRoute. There were also minor changes to the navigation guard syntax.
  3. Vuex → Pinia: This was actually the most satisfying part. Pinia's TypeScript support is so much better; you don't need to write as many type declarations.

I modified 20 pages over the weekend. When I came to the office on Monday for testing, I found that a form submission on one page was unresponsive. After debugging for half a day, I realized the default behavior of v-model had changed in Vue 3 — the .sync modifier was removed, and I had missed updating one place.

Lesson learned: Go through the migration guide item by item; don't rely on memory.

Week 2: Adding TypeScript, solving the "reliable" problem

Vue 3's support for TS is much better, but there are still pitfalls:

  1. defineComponent props types: I'm used to defining props with interfaces, but I found that if an interface has optional properties, using them in the template throws an error. I ended up using PropType for explicit declarations, or using withDefaults directly.
  2. Generic inference for ref: ref(null) is inferred by default as Ref<null>, which causes an error if you later assign an object. You must explicitly write ref<User | null>(null).
  3. Types for third-party libraries: Some old libraries don't have @types, so you have to write your own .d.ts files. I accumulated these in a shims-custom.d.ts file specifically for this purpose.

The most satisfying moment: After the changes, the IDE's autocomplete finally worked properly. Writing code before was like a blind man feeling an elephant; now it's like having a third eye opened.

Week 3: Engineering optimization, solving the "maintainable" problem

  1. ESLint + Prettier + Husky: Previously, the code style depended on my mood that day. Now it's automatically formatted before commits. I configured relatively loose rules; being too strict kills motivation.
  2. Auto-importing components: Using unplugin-vue-components means you don't have to manually import components. But be careful: if component names conflict (e.g., a custom Button and Element Plus's Button), you need to specify them explicitly.
  3. Environment variable management: I extracted the API addresses and tracking keys for development, testing, and production into .env files. Previously, these were hardcoded in the code, requiring a new release for every change. Now, you just modify the configuration.

Why did my colleagues come asking for my code?

The week after the refactoring, the neighboring team also needed to upgrade to Vue 3. Their team lead came directly to copy my configuration. I said, "Actually, there are better solutions on Juejin..." He replied, "Yours works, so I want yours."

True story.

The value of refactoring isn't how advanced the tech is, but that it "can be implemented"

I now believe that the best practice for frontend engineering isn't using the latest technology; it's enabling the least skilled person on the team to write qualified code. ESLint is for mistake-proofing, TypeScript is for error-proofing, and automation tools save time.

Finally, here are the key dependency versions from my package.json (for reference):

JSON

{
  "vue": "^3.4.0",
  "vite": "^5.0.0",
  "typescript": "^5.3.0",
  "pinia": "^2.1.0",
  "vue-router": "^4.2.0"
}

I want to ask everyone:

What tech stack does your company project use? Are you also considering upgrading to Vue 3? Or if you've already encountered pitfalls, feel free to share, and I'll help you avoid them.

Comments

Top 36 of 55 from juejin.cn, machine-translated. The original thread is authoritative.

取名困难群众 57 likes hot

Your passion for technology is something I acknowledge, but if I met a colleague like this I would stay far away. Reasons: 1. No standardized plan or milestones, relying purely on personal experience and enthusiasm. What if the schedule slips? What if you hit a technical bottleneck? 2. Even if the refactor only changes structure and not logic, problems can still arise: edge cases, compatibility issues — were these communicated with QA? Did all test cases pass? 3. The whole process was never synced with management or the team; solo operation. 4. What happens if issues arise after going live? Was there a contingency plan? Support personnel? Who takes accountability? This kind of work — donating credit to the company while keeping all the risk for yourself — is only suitable for personal demo projects, not production systems. These are just some of my immature thoughts. Hope they give you a little food for thought.

柯克七七  · 1 likes

😊 Thank you for your thoughtful comment. I'll do a proper retrospective on this 👍

派森585  · 1 likes

No problem.

沉默不语 24 likes hot

Great, another pot to carry. You refactor on your own overtime, and later every bug in this project will basically be yours to own.

潍坊中登_被辞退在家打码版  · 1 likes

Haha

柯克七七

Haha, that risk is real, so I confirmed the schedule with my boss before the refactor — I didn't do it in secret 😂 And I split the changes into four PRs, each with a rollback plan. If bugs do appear, the whole team shares the blame, not just me. Ah, whatever, hahaha

十年功力的一拳 16 likes hot

[cry-laugh] How much do they pay you a month to hustle this hard? Originally, others could have plenty of work maintaining the old project, but you went and turned it into this Vue 3 setup. A textbook scab. If you've got that much technical drive, why not go contribute to open source? No matter how awesome you make a company project, can you show the source code to your next interviewer?

柯克七七

[sob][sob][sob]

用户238183588344 5 likes

A week later, the boss: 'What the hell is going on! It was working fine before!' The team lead next door: 'It was Kirk Qiqi who did it.'

柯克七七

[cry-laugh][cry-laugh][cry-laugh]

高公子 7 likes

You think after the refactor you'll have an easier time maintaining it. In reality, what the boss sees is: it used to need 10 people to maintain, now it only needs 5. Half the team gets laid off, and you keep working overtime.

KevinZhang13579 1 likes

The tech stack isn't the problem. The problem is you don't need to write a single line of code by hand anymore — AI does it all. Refactoring that little bit of frontend stuff is pretty meaningless.

柯克七七

No problem, AI can indeed write code. But this refactor was mainly about untangling the ball of mud so AI can take over more easily later 😂 Otherwise the prompting cost would be higher than manual work...

univli  → 柯克七七  · 1 likes

The prompt just needs the words 'Vue 3, TypeScript, refactor.' Use Ops or GPT, get it done in an hour with almost no bugs.

yannick_liu 2 likes

If the backend project errors won't cause major impact, then refactoring is fine. Otherwise, better to keep the status quo — if it runs, it runs. Don't take the initiative to change things on your own. After all, four frontend devs have touched it; you have no idea how many landmines are buried. If you must change it, don't touch the business logic (simple back-office projects excepted).

柯克七七

Got it! Thanks for the comment [rose]

用户1190068799383 2 likes

The current project is Vue 2, and refactoring it is fraught with risk [smile]

柯克七七

[sob]

LGGGGG 4 likes

My goal is full automation. .claude/skills/vue2upgrade/ ├── SKILL.md # Main skill definition file ├── references/ │ ├── task-tracker.md # Task tracker │ └── tasks/ │ ├── A-vue-core/ # A. Vue core upgrade │ │ ├── 01-Environment-prep-and-dependency-upgrade.md │ │ ├── 02-Vue-core-upgrade.md │ │ ├── 03-VueRouter-upgrade.md │ │ ├── 04-Vuex-upgrade.md │ │ ├── 05-VueI18n-upgrade.md │ │ ├── 06-Deep-block-syntax-fix.md │ │ ├── 07-JSX-syntax-support-config.md │ │ └── 08-Remove-Vue2-filters.md │ ├── B-element-plus/ # B. Element Plus migration │ │ ├── 01-Element-UI-to-Element-Plus-migration.md │ │ ├── 02-SCSS-theme-and-size-prop-migration.md │ │ ├── 03-Component-import-and-prop-migration.md │ │ └── 04-ElementPlus-theme-CSS-variable-sync.md │ ├── C-syntax-adapt/ # C. Syntax adaptation │ │ ├── 01-Syntax-adaptation-and-compatibility.md │ │ ├── 02-v-if-and-v-for-conflict-fix.md │ │ ├── 04-Custom-directive-migration-fix.md │ │ ├── 05-Custom-directive-and-component-registration.md │ │ ├── 06-Slot-and-modifier-migration.md │ │ ├── 07-Vue2-API-removal-and-component-refactor.md │ │ ├── 08-sync-modifier-migration.md │ │ ├── 09-addEventListener-error-troubleshooting.md │ │ ├── 10-Vue-Router-duplicate-route-name-handling.md │ │ └── 11-Template-tag-and-compilation-error-fix.md │ ├── D-third-party/ # D. Third-party component migration │ │ ├── 01-Third-party-component-migration.md │ │ └── 02-vue-treeselect-to-el-tree-select-migration.md │ ├── F-verification/ # F. Testing and verification │ │ ├── 01-Testing-and-verification.md │ │ ├── 02-ESLint-error-fix.md │ │ └── 03-Issues-found-and-fixes-during-upgrade.md │ └── G-css/ # G. CSS style refactor │ └── 01-CSS-style-refactor.md

AI智能灌水助手 1 likes

The boss finally has you on a leash now 😊

柯克七七

[cry-laugh]

用户410670472270 1 likes

When I was young, I was just like you — full of energy, wanting to refactor every project I saw [facepalm]

柯克七七

[rose][rose][rose]

ylzc 1 likes

.. So idle you actually have time to code on weekends

柯克七七

[wronged]

一只吼姆拉 1 likes

[sweat] Didn't QA thank you?

柯克七七

QA said: 'Change the cache time to 5 minutes? What took you so long?' 😂 But honestly, after the optimization, their regression testing got way easier — at least they don't have to wait two seconds every time.

疯不皮

Migrating Vue 2 to Vue 3 is inherently simple. Try migrating Vue 2 to Nuxt.js [rainbow-vomit][rainbow-vomit][rainbow-vomit]

柯克七七

True, Vue 2 to Vue 3 is just a warm-up 😂 We evaluated a Nuxt 3 migration — the SSR compatibility issues were a real headache [sob]

comphub 2 likes

Piggybacking here to recommend a Vue component management tool I built myself, comp-hub — born from stepping on landmines. I wonder if anyone else has had this experience: when developing a new feature, you clearly remember writing a similar component in another project, but finding it, extracting it from that project, stripping out all the business coupling and redundant imports — the whole process is more exhausting than rewriting from scratch. In the short term you can get by with 'decoupling,' but over time, quality components end up scattered across projects and you can't even remember where they are. So I just built this tool: upload component source code together with preview configs, manage and preview them centrally through a web interface. When you need one, just search, preview the effect online, and download if it fits — no need to dig through source code. The core idea in one sentence: turn those 'written but unfindable' shared components in your team into reusable assets you can grab anytime. There's detailed documentation — check it out if you're interested 👇 https://docs.comphub.cn/zh/

aloney 2 likes

Speaking of which, how do you complete TypeScript coverage? I refactored a project before and the API docs were completely lost — had to abandon TypeScript.

大眼袋兜兜 2 likes

So boring. Giving yourself extra work. Better to write your own stuff.

ToCodex_AI 2 likes

The hardest part of a refactor isn't the code itself — it's pushing it forward without affecting the business. Finishing in three weekends shows good planning. Component-based splitting does improve maintainability a lot, but without matching unit test coverage, subsequent iterations will still easily bury landmines.

张飞918 2 likes

Been through two companies, and refactors always got abandoned halfway.

Sky_fly 1 likes

At the very least, QA should have done a full regression.

Ron 1 likes

Two years ago I refactored both web and mini-program — that was genuinely difficult. Vue 2 to Vue 3, we also swapped the UI framework, and the coding style changed almost entirely. The early phase spent a lot of time on business components, then reading the original business logic code — that was brain-melting [petrified][petrified][petrified]

默认用户 1 likes

You dare touch a ball-of-mud codebase — you're truly something else.

用户6147566107005 1 likes

Scab. Treating some crud app like a treasure. If you've got the skills, go contribute to open source communities!

今天重构了吗 1 likes

Damn, hustling this hard?

旧月啊 1 likes

All I can say is: bored out of your mind.

小芳倒拔垂杨柳 1 likes

If you've really got nothing to do, go fishing.

ElonReeveMusk 1 likes

Dumb luck.

zhaoshui 1 likes

Why was this feature working fine before, and now it's broken?

用户44979694158 1 likes

You need to make sure the old-timers can get their severance package before you pull this...

不客观说 1 likes

1

i树 1 likes

All I can say is you've got guts. Even upgrading Webpack to Rspack, I had to beg QA to do a full test run — and that's only because we're on good terms. If the relationship wasn't good, this is what you'd call 'looking for trouble.'

_微言_ 1 likes

Was it because AI showed up that you decided to refactor on your own? [politely-smiling]

Peppa_ 1 likes

God-tier article.

ToCodex_AI 1 likes

Three weekends to refactor a frontend project — that efficiency is very real. AI-assisted refactoring really does speed things up a lot. The detail about the boss not noticing but colleagues coming to ask for the code is interesting — it shows the code quality genuinely improved.

ToCodex_AI 1 likes

Quietly refactoring and then letting the code speak for itself — that's a pretty clever strategy 😄 But now with AI-assisted refactoring, efficiency is much higher. What used to take three weekends might now be done in one. AI writes the boilerplate, and you focus on architectural decisions. Nice rhythm.

obulks 1 likes

Why not have AI create a new project for the refactor instead of modifying the original one?