跪拜 Guibai
← All articles
Frontend · React.js · Vite

A React+Vite Stack That Ships Frontends Before the Backend Exists

By YIAN ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Server-level mock tooling that shows real HTTP traffic in DevTools removes the biggest friction in frontend-backend parallel work. A team can ship a fully interactive UI, validate state management and routing, and merge to real endpoints later by toggling one config boolean — no dead-data cleanup, no last-minute rewiring.

Summary

Frontend teams routinely stall waiting for backend APIs. A standard React 18 + Vite stack eliminates that dependency by combining Axios API layering, server-level mock interception via vite-plugin-mock, and Zustand for global state. The mock plugin operates inside Vite’s Node dev server, so requests appear in the Network tab exactly like real calls — unlike browser-side Mock.js, which hides them.

The workflow is straightforward: wrap Axios with a shared baseURL and timeout, organize API functions by business module, then define mock arrays that match those exact URL paths. Flipping a single `enable` flag in vite.config.js switches the entire app from mock data to live backend endpoints with no code changes.

Routing gets a pragmatic treatment too. HashRouter deploys anywhere without server config and never 404s on refresh; BrowserRouter gives clean URLs but demands Nginx `try_files` or equivalent. Zustand replaces the Context+useReducer combo for global state, subscribing components only to the slices they consume and avoiding the re-render tax of Provider trees.

Takeaways
— vite-plugin-mock intercepts requests in Vite’s Node dev server, so the browser Network tab shows complete request-response pairs — unlike Mock.js, which swallows them at the XHR level.
— A single `enable: true/false` in vite.config.js switches the entire application between mock and real backends; no business code changes are needed.
— Axios instances with a shared `baseURL` and timeout let every API module import the same configured client, keeping endpoint URLs centralized.
— Organizing API functions by business domain (e.g., `api/todos.js`) means components import a named function and never touch URLs, headers, or error handling directly.
— HashRouter requires zero server configuration and survives page refreshes without 404s, making it the pragmatic choice for static deploys and prototypes.
— Zustand stores live outside the React tree, so components subscribe to specific state slices and skip the full-tree re-renders that Context+useReducer triggers.
— Async calls inside `useEffect` must be wrapped in an IIFE because the effect cleanup expects a function, not a Promise.
Conclusions

The mock-at-dev-server pattern (vite-plugin-mock) is a distinct upgrade over browser-side interception: it keeps the Network tab honest, which matters more for debugging velocity than most teams admit.

The architecture’s real payoff is the one-config switch from mock to production. That single boolean eliminates an entire class of integration bugs caused by manually replacing stubbed data across components.

Zustand’s selector-based subscriptions solve the Context performance problem without introducing the ceremony of Redux. For global state in React, the Context+useReducer pattern is now a legacy fallback, not a default.

HashRouter remains underrated in professional circles. For any app served from a CDN or static host without server config access, it is the only routing mode that won’t break on refresh.

Concepts & terms
vite-plugin-mock
A Vite plugin that intercepts HTTP requests inside the dev server’s Node process and returns preset JSON. Because interception happens server-side, browser DevTools show real network entries, unlike browser-level mock libraries.
BFF (Backend For Frontend)
A dedicated backend layer that sits between the frontend and downstream services. It can aggregate, transform, or stub data specifically for one frontend client, and typically runs in production — distinct from dev-only mock tools.
Zustand
A lightweight React state management library where stores are plain JavaScript objects outside the component tree. Components subscribe to specific slices via selectors, avoiding the Provider wrapping and full-tree re-renders of Context.
IIFE (Immediately Invoked Function Expression)
A JavaScript pattern — `(async () => { ... })()` — that defines and immediately executes a function. Required inside React’s `useEffect` for async work because the effect must return a cleanup function, not a Promise.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗