A dynamic proxy middleware for webpack-dev-server that enables hot-swapping proxy configurations and mock data without restarting your dev server.
During frontend development, you often need to:
- Switch between local mock data and remote servers
- Test against different environments (dev, staging, production)
- Use different proxy strategies for specific APIs
Traditionally, these changes require modifying config files and restarting webpack, which:
- Slows down development (waiting for compilation)
- Interrupts your workflow
- Makes debugging across environments difficult
Dev Server Proxy solves this by allowing real-time configuration updates through a simple .devserverrc file.
- π₯ Hot Configuration Reload - Update proxy rules without restarting
- π Hot Mock Updates - Modify mock files and see changes instantly
- π― Flexible Routing - Global proxy, custom API rules, and path-level configurations
- π Multi-Environment Support - Built-in support for mock, test, staging, and production
- β‘ Webpack 4 & 5 Compatible - Works with both major versions
- π¦ Rspack Support - Seamlessly integrates with Rspack's webpack-dev-server
npm install dev-server-proxy --save-dev
# or
pnpm add dev-server-proxy -D1. Add scripts to package.json
For Webpack < 5 (using --proxy flag):
{
"scripts": {
"start": "webpack-dev-server --config webpack.dev.config.js --proxy mock",
"start:online": "webpack-dev-server --config webpack.dev.config.js --proxy online"
}
}For Webpack >= 5 (using PROXY env variable):
{
"scripts": {
"start": "PROXY=mock webpack serve --config webpack.dev.config.js",
"start:online": "PROXY=online webpack serve --config webpack.dev.config.js"
}
}2. Configure webpack devServer
For Webpack:
const devServerProxy = require('dev-server-proxy');
const config = require('./config');
module.exports = {
devServer: {
...devServerProxy(config),
// For webpack 5, pass version number:
// ...devServerProxy(config, 5),
historyApiFallback: true,
port: 3000
}
};For Rspack:
const { webpackDevServerProxy } = require('dev-server-proxy');
const config = require('./config');
const proxyConfig = webpackDevServerProxy(config, 5);
const { setupMiddlewares, allowedHosts, open, https } = proxyConfig;
module.exports = {
devServer: {
setupMiddlewares,
allowedHosts,
open,
server: https ? 'https' : 'http',
port: 3000,
historyApiFallback: true
}
};3. Create config.js
const path = require('path');
module.exports = {
WORK_PATH: __dirname,
MOCK_PATH: path.join(__dirname, './mock'),
AJAX_API: /^\/api\/request.ajax$/,
// Environment configurations
PROXY_ONLINE: {
host: 'dev.example.com',
target: 'https://api.example.com',
open: 'https://dev.example.com:3000'
},
PROXY_MOCK: {
host: 'dev.example.com',
open: 'http://dev.example.com:3000'
}
};4. Configure hosts file
127.0.0.1 dev.example.com
5. Create mock files
Create mock files in your MOCK_PATH directory. File names use underscores to separate path segments:
// File: mock/user_GET_info.js
// Maps to: user/GET/info
module.exports = (params) => {
return {
status: 200,
response: {
code: 0,
data: {
username: 'john_doe',
email: 'john@example.com'
}
}
};
};6. Start development
npm startModify the .devserverrc file in your working directory to change proxy settings on the fly:
{
"PROXY": "PROXY_ONLINE",
"PATH_RULES": {
"user/GET/info": {
"proxy": "PROXY_MOCK"
},
"product/GET/list": {
"target": "https://staging.example.com"
}
}
}Changes take effect immediately without restarting the dev server!
WORK_PATH- Working directory pathMOCK_PATH- Directory containing mock filesAJAX_API- Regex pattern matching your API endpoint
Define proxy configurations for different environments:
{
PROXY_MOCK: {
host: 'dev.example.com',
open: 'http://dev.example.com:3000'
},
PROXY_TEST: {
host: 'dev.example.com',
target: 'https://test-api.example.com',
open: 'https://dev.example.com:3000'
},
PROXY_ONLINE: {
host: 'dev.example.com',
target: 'https://api.example.com',
open: 'https://dev.example.com:3000'
}
}For non-standard API patterns, use CUSTOM_API:
{
CUSTOM_API: [
{
rule: (parsedUrl) => {
// Custom logic to extract path from URL
if (parsedUrl.pathname.startsWith('/custom/')) {
return parsedUrl.pathname.replace('/custom/', '');
}
}
}
]
}If you need more control, you can manually integrate the middleware:
const startMockWatch = require('dev-server-proxy/src/startWatch');
const getProxyMiddleware = require('dev-server-proxy/src/core/server');
const config = require('./config');
// Start file watchers
startMockWatch(config);
// Use middleware in your Express app
app.use('/', getProxyMiddleware(config));Mock files should export a function that receives request parameters and returns a response object:
module.exports = (params) => {
// params contains parsed request parameters
console.log('Request params:', params);
return {
status: 200, // HTTP status code
response: { // Response body
code: 0,
data: { /* your data */ },
message: 'Success'
}
};
};Use underscores to separate path segments and HTTP methods:
user_GET_info.jsβuser/GET/infoproduct_POST_create.jsβproduct/POST/createorder_GET_list.jsβorder/GET/list
For in-depth information about the architecture, design patterns, and implementation details, see ARCHITECTURE.md.