跪拜 Guibai
← All articles
Vue.js · Frontend

How One Developer Swapped an 80k-Line jQuery App for Vue3 Without Permission

By 奶油mm ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Many organizations still run critical internal tools on unmodularized jQuery codebases where a single global variable can break production. This strategy shows how to modernize incrementally without a rewrite grant, keeping the backend untouched and the business unaware until the new stack proves itself.

Summary

An 80,000-line jQuery 1.12 and Bootstrap 3 admin panel, held together by decade-old comments warning against deletion, was silently migrated to Vue3 over three months. The migration started after a single variable-name collision in an 800-line function took down the entire site's styles, exposing the architecture's fragility. Rather than proposing a full rewrite, the developer embedded a Vite-powered Vue3 app alongside the legacy code, using Vue Router to intercept specific paths while hiding the old DOM container.

Vue components reused the existing jQuery AJAX wrapper through a thin adapter, so backend APIs required zero changes. For pages that needed partial upgrades, Web Components bridged jQuery frames with Vue interactive elements. The first fully converted page, the order list, went live with no incidents, and business users only noticed it felt faster.

Within weeks, four of six team members adopted Vue3 for new pages. The CTO eventually requested the remaining pages be migrated, unaware the groundwork had already been laid. The approach kept risk low by isolating each page, using hash-mode routing for compatibility, and splitting the 400KB+ bundle below 200KB with manual chunks and a CDN.

Takeaways
An 800-line jQuery function with reused global variables caused a site-wide style collapse after a 3-line change, exposing the architecture's brittleness.
Vue3 was embedded into the legacy project by adding a hidden mount point and using Vue Router to intercept specific paths, hiding the jQuery container on matched routes.
A thin adapter layer let Vue components call the existing jQuery AJAX wrapper directly, eliminating any need for backend changes.
Web Components served as a bridge, allowing Vue components to render inside jQuery pages as custom HTML elements for partial page upgrades.
The first fully refactored page, the order list, went live with zero bugs after three days of testing; business users only noticed improved speed.
Four of six team members adopted Vue3 for new pages within a month, and the CTO later requested the remaining pages be migrated.
Global Bootstrap 3 styles polluted Vue components until scoped styles and CSS Modules were applied to the Vue root node.
Memory leaks from uncleaned jQuery events were fixed by calling $.off() inside Vue's onUnmounted lifecycle hook.
Vue Router's history mode was swapped for hash mode to avoid server-side configuration changes the legacy project couldn't support.
The 400KB+ Vue3 and Element Plus bundle was reduced below 200KB for first-screen loads using Vite's manualChunks and a CDN.
Conclusions

The hardest part of a legacy rewrite is rarely the code; it's navigating organizational resistance by delivering incremental, provable business value that builds political cover.

Reusing the existing data layer rather than replacing it removes the largest source of risk and approval friction in frontend migrations.

Web Components are an underused migration tool: they let modern frameworks and legacy code coexist in the same DOM without either knowing about the other.

Silent, page-by-page replacement works because users judge software by speed and correctness, not by the framework that renders it.

Concepts & terms
Route hijacking
A migration technique where a modern router intercepts specific URL paths and renders new pages, while the legacy router handles the rest, allowing both stacks to coexist in the same application.
Web Components bridge
Using the Custom Elements API to wrap framework components (e.g., Vue SFCs) as standard HTML tags, so they can be dropped into legacy server-rendered or jQuery-built pages without framework conflicts.
legacyApi adapter
A thin wrapper that exposes an old global API object (like a jQuery AJAX utility) as a module import, letting modern code call existing backend interfaces without rewriting them.
From the discussion

The discussion splits between admiration for the audacity of the rewrite and sharp criticism of the developer's technical judgment. One side points to a specific variable-scoping bug as evidence of incompetence, while a reply defends the decision to work within the existing monolithic function rather than risk wider breakage. A separate thread argues the real issue is low pay and workplace dynamics, framing the secret rewrite as a provocation that shifts the burden onto the person who acts.

Pulling off a clandestine framework migration is impressive in its boldness.
A developer who introduces variable-scoping bugs in a refactor lacks fundamental skills, casting doubt on the entire codebase's quality.
Working inside a legacy 800-line function is sometimes the safer choice than restructuring it and causing cascading failures.
The root cause of such situations is not technical inability but low wages and a workplace culture that punishes initiative by loading more work onto the person who steps up.
The secret rewrite is seen as a reckless move that disrupts team equilibrium and invites retaliation.
Featured comments
OnceSure 1 likes

"The reason was that in that 800-line function, line 203 had a global variable i being reused in a loop, and my new code declared another i at line 600, causing an earlier loop to exit prematurely and the DOM structure to misalign." Someone who can't even write a closure — you can imagine what their refactored code looks like.

ashuicoder

You're a talent yourself. The guy said the old code was in one function. Do you dare to touch that function? Changing it would break even more. You just keep writing inside that function.

薛定谔的玩具车 1 likes

People like this will get their comeuppance sooner or later. It's not that others can't fix it. It's that the boss pays peanuts. You come in and upset the balance, and from then on all the work falls on you.

See top comments, translated →
Source: juejin.cn ↗ Google Translate ↗ Backup ↗