← Back to all articles

I Refactored Our Company's Frontend Project in 3 Weekends – My Boss Didn't Notice, But My Colleagues All Wanted My Code

我用3个周末重构了公司的前端项目,老板没发现,但同事都来找我要代码了

柯克七七 2026-06-09 5,787 views
前端

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

The company's project is a 3-year-old Vue2 backend system. The codebase isn't large (over 50 pages), but it has a "long history" – having gone through 4 frontend developers, resulting in varied styles, no TypeScript, no component library standards, and console.log statements scattered everywhere.

I spent 3 weekends (Friday evening + all day Saturday) upgrading it to Vue3 + TS + Vite. This wasn't about showing off; I was genuinely fed up with the old system.

Week 1: Building the Skeleton, Solving the 'Runnable' Problem

First, I ran @vue/cli's migration tool, but found it only solved about 30% of the issues. The rest required manual changes:

  1. Options API → Composition API: This was the most painful part. Some component logic was scattered across data, computed, and methods. During refactoring, I first had to clarify the logical relationships. My strategy was: don't change the logic yet, only change the syntax to ensure consistent behavior.
  2. Vue Router 3 → 4: The main change was router.addRoutes being deprecated and replaced with router.addRoute. There were also minor changes in how navigation guards are written.
  3. Vuex → Pinia: This, conversely, was the most satisfying. Pinia's TypeScript support is far superior, eliminating the need for so many type declarations.

Over the weekend, I modified 20 pages. When I tested them at the company on Monday, I found that a form on one page didn't respond after submission. After debugging for a long time, I discovered that v-model's default behavior had changed in Vue3 – the .sync modifier was removed, and I missed one place.

Lesson: The migration guide must be checked line by line, not relied upon from memory.

Week 2: Implementing TypeScript, Solving the 'Reliability' Problem

Vue3's support for TS has greatly improved, but there are still pitfalls:

  1. defineComponent props types: I'm used to defining props with interfaces, but I found that if an interface had optional properties, using them in the template would throw an error. I eventually switched to explicitly declaring them with PropType or directly using withDefaults.
  2. ref generic inference: ref(null) defaults to Ref<null>, which causes an error if an object is assigned later. You must explicitly write ref< User | null>(null).
  3. Third-party library types: Some older libraries don't have @types definitions, so I had to write my own .d.ts files. I compiled a shims-custom.d.ts specifically for these.

The most satisfying moment: After the changes, IDE auto-completion finally worked correctly. Before, coding felt like a blind man feeling an elephant; now, it's like having divine insight.

Week 3: Engineering Optimizations, Solving the 'Maintainability' Problem

  1. ESLint + Prettier + Husky: Previously, code style depended on the day's mood; now, it's automatically formatted before committing. I configured a relatively lenient set of rules; overly strict rules can dampen enthusiasm.
  2. Automatic component import: Using unplugin-vue-components eliminates the need to manually import components. However, be aware that if component names conflict (e.g., a custom Button and an Element Plus Button), you need to explicitly specify them.
  3. Environment variable management: Extracted API addresses, analytics keys for development, testing, and production, and managed them using .env files. Previously, these were hardcoded in the codebase; changing them meant a new release. Now, only the configuration needs to be updated.

Why Did My Colleagues Ask Me for the Code?

Two weeks after the refactoring, the adjacent team also needed to upgrade to Vue3. Their team lead directly came 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 About Advanced Technology, It's About Being 'Implementable'

I now believe that the best practice for frontend engineering isn't about using the latest technology; it's about enabling even the least experienced person on the team to write qualified code. ESLint is for preventing silly mistakes, TypeScript is for preventing errors, and automation tools save time.

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

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

A question for everyone:

What's the tech stack of your company's projects? Is anyone else considering upgrading to Vue3? Or if you've already encountered pitfalls, feel free to share; I can help you avoid them.

Read original on juejin.cn →