From a80083bf3ce99dc671666daa16b7a61c0e75c828 Mon Sep 17 00:00:00 2001 From: neverland Date: Mon, 3 Aug 2026 18:41:00 +0800 Subject: [PATCH 1/2] fix: reduce default HPM logging --- src/server.ts | 8 +- tests/e2e/proxy-logging.test.js | 173 ++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/proxy-logging.test.js diff --git a/src/server.ts b/src/server.ts index 0043022..69a78f2 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1708,6 +1708,12 @@ class Server< const { createProxyMiddleware } = await import( /* webpackChunkName: "http-proxy-middleware" */ 'http-proxy-middleware' ); + const defaultProxyLogger = { + // HPM logs every successful proxy request at info level, so treat it as verbose output. + info: this.logger.log.bind(this.logger), + warn: this.logger.warn.bind(this.logger), + error: this.logger.error.bind(this.logger), + }; const getProxyMiddleware = ( proxyConfig: DevServerProxyConfigArrayItem, @@ -1720,7 +1726,7 @@ class Server< } if (typeof proxyOptions.logger === 'undefined') { - proxyOptions.logger = this.logger as EXPECTED_ANY; + proxyOptions.logger = defaultProxyLogger; } if (proxyOptions.target || proxyOptions.router) { diff --git a/tests/e2e/proxy-logging.test.js b/tests/e2e/proxy-logging.test.js new file mode 100644 index 0000000..eacdb02 --- /dev/null +++ b/tests/e2e/proxy-logging.test.js @@ -0,0 +1,173 @@ +const http = require('node:http'); +const path = require('node:path'); +const { rspack } = require('@rspack/core'); +const { RspackDevServer } = require('@rspack/dev-server'); +const { + getRandomPorts, + releaseRandomPorts, +} = require('../helpers/get-random-port'); +const request = require('../helpers/http-request'); + +describe('proxy logging', () => { + let backend; + let devServer; + let ports; + + beforeEach(async () => { + ports = await getRandomPorts(2, '127.0.0.1'); + }); + + afterEach(async () => { + if (devServer) { + await devServer.stop(); + devServer = undefined; + } + + if (backend) { + await new Promise((resolve, reject) => { + backend.close((error) => { + if (error) { + reject(error); + return; + } + + resolve(); + }); + }); + backend = undefined; + } + + releaseRandomPorts(ports); + }); + + const createInfrastructureConsole = () => { + const infrastructureConsole = Object.create(console); + + infrastructureConsole.debug = rs.fn(); + infrastructureConsole.log = rs.fn(); + infrastructureConsole.info = rs.fn(); + infrastructureConsole.warn = rs.fn(); + infrastructureConsole.error = rs.fn(); + + return infrastructureConsole; + }; + + const containsLog = (mock, text) => + mock.mock.calls.some((args) => + args.some((argument) => String(argument).includes(text)), + ); + + const startBackend = async () => { + backend = http.createServer((_request, response) => { + response.end('proxied'); + }); + + await new Promise((resolve, reject) => { + backend.once('error', reject); + backend.listen(ports[0], '127.0.0.1', resolve); + }); + }; + + const startDevServer = async ({ level = 'info', logger } = {}) => { + const infrastructureConsole = createInfrastructureConsole(); + const compiler = rspack({ + entry: path.resolve(__dirname, '../placeholder.js'), + infrastructureLogging: { + appendOnly: true, + colors: false, + console: infrastructureConsole, + level, + }, + stats: 'none', + }); + + devServer = new RspackDevServer( + { + client: false, + hot: false, + liveReload: false, + host: '127.0.0.1', + port: ports[1], + proxy: [ + { + context: ['/api'], + target: `http://127.0.0.1:${ports[0]}`, + ...(logger ? { logger } : {}), + }, + ], + static: false, + webSocketServer: false, + }, + compiler, + ); + + await devServer.start(); + + return infrastructureConsole; + }; + + it('does not print successful requests at the default level', async () => { + await startBackend(); + const infrastructureConsole = await startDevServer(); + + const response = await request({ + hostname: '127.0.0.1', + path: '/api/users', + port: ports[1], + }); + + expect(response.status).toBe(200); + expect(containsLog(infrastructureConsole.info, '[HPM]')).toBe(false); + expect(containsLog(infrastructureConsole.log, '[HPM]')).toBe(false); + }); + + it('prints successful requests at the log level', async () => { + await startBackend(); + const infrastructureConsole = await startDevServer({ level: 'log' }); + + const response = await request({ + hostname: '127.0.0.1', + path: '/api/users', + port: ports[1], + }); + + expect(response.status).toBe(200); + expect(containsLog(infrastructureConsole.log, '[HPM] GET /api/users')).toBe( + true, + ); + }); + + it('still prints proxy errors at the default level', async () => { + const infrastructureConsole = await startDevServer(); + + const response = await request({ + hostname: '127.0.0.1', + path: '/api/users', + port: ports[1], + }); + + expect(response.status).toBe(504); + expect( + containsLog(infrastructureConsole.error, '[HPM] Error occurred'), + ).toBe(true); + }); + + it('preserves a custom proxy logger', async () => { + await startBackend(); + const logger = { + error: rs.fn(), + info: rs.fn(), + warn: rs.fn(), + }; + + await startDevServer({ logger }); + const response = await request({ + hostname: '127.0.0.1', + path: '/api/users', + port: ports[1], + }); + + expect(response.status).toBe(200); + expect(containsLog(logger.info, '[HPM] GET /api/users')).toBe(true); + }); +}); From 1c23fe10488079eb677f3203a110a631a3c5ac90 Mon Sep 17 00:00:00 2001 From: neverland Date: Mon, 3 Aug 2026 18:43:47 +0800 Subject: [PATCH 2/2] test: simplify proxy logging coverage --- tests/e2e/proxy-logging.test.js | 171 ++++++++------------------------ 1 file changed, 42 insertions(+), 129 deletions(-) diff --git a/tests/e2e/proxy-logging.test.js b/tests/e2e/proxy-logging.test.js index eacdb02..fb79905 100644 --- a/tests/e2e/proxy-logging.test.js +++ b/tests/e2e/proxy-logging.test.js @@ -1,98 +1,59 @@ +const { once } = require('node:events'); const http = require('node:http'); const path = require('node:path'); const { rspack } = require('@rspack/core'); const { RspackDevServer } = require('@rspack/dev-server'); -const { - getRandomPorts, - releaseRandomPorts, -} = require('../helpers/get-random-port'); const request = require('../helpers/http-request'); describe('proxy logging', () => { let backend; let devServer; - let ports; - - beforeEach(async () => { - ports = await getRandomPorts(2, '127.0.0.1'); - }); afterEach(async () => { - if (devServer) { - await devServer.stop(); - devServer = undefined; - } + await devServer?.stop(); - if (backend) { - await new Promise((resolve, reject) => { - backend.close((error) => { - if (error) { - reject(error); - return; - } - - resolve(); - }); - }); - backend = undefined; + if (backend?.listening) { + const closed = once(backend, 'close'); + backend.close(); + await closed; } - - releaseRandomPorts(ports); }); - const createInfrastructureConsole = () => { - const infrastructureConsole = Object.create(console); - - infrastructureConsole.debug = rs.fn(); - infrastructureConsole.log = rs.fn(); - infrastructureConsole.info = rs.fn(); - infrastructureConsole.warn = rs.fn(); - infrastructureConsole.error = rs.fn(); - - return infrastructureConsole; - }; - - const containsLog = (mock, text) => - mock.mock.calls.some((args) => - args.some((argument) => String(argument).includes(text)), - ); - - const startBackend = async () => { - backend = http.createServer((_request, response) => { - response.end('proxied'); - }); + it('uses the expected infrastructure log levels', async () => { + backend = http.createServer((_req, res) => res.end('proxied')); + backend.listen(0, '127.0.0.1'); + await once(backend, 'listening'); - await new Promise((resolve, reject) => { - backend.once('error', reject); - backend.listen(ports[0], '127.0.0.1', resolve); - }); - }; - - const startDevServer = async ({ level = 'info', logger } = {}) => { - const infrastructureConsole = createInfrastructureConsole(); + const backendPort = backend.address().port; + const logs = []; const compiler = rspack({ entry: path.resolve(__dirname, '../placeholder.js'), - infrastructureLogging: { - appendOnly: true, - colors: false, - console: infrastructureConsole, - level, - }, stats: 'none', }); + compiler.hooks.infrastructureLog.tap( + 'proxy-logging-test', + (name, type, args) => { + const message = args.map(String).join(' '); + + if (name === 'rspack-dev-server' && message.includes('[HPM]')) { + logs.push({ message, type }); + } + + return true; + }, + ); + devServer = new RspackDevServer( { client: false, hot: false, - liveReload: false, host: '127.0.0.1', - port: ports[1], + port: 0, proxy: [ { context: ['/api'], - target: `http://127.0.0.1:${ports[0]}`, - ...(logger ? { logger } : {}), + target: `http://127.0.0.1:${backendPort}`, }, ], static: false, @@ -102,72 +63,24 @@ describe('proxy logging', () => { ); await devServer.start(); - - return infrastructureConsole; - }; - - it('does not print successful requests at the default level', async () => { - await startBackend(); - const infrastructureConsole = await startDevServer(); - - const response = await request({ - hostname: '127.0.0.1', - path: '/api/users', - port: ports[1], - }); - - expect(response.status).toBe(200); - expect(containsLog(infrastructureConsole.info, '[HPM]')).toBe(false); - expect(containsLog(infrastructureConsole.log, '[HPM]')).toBe(false); - }); - - it('prints successful requests at the log level', async () => { - await startBackend(); - const infrastructureConsole = await startDevServer({ level: 'log' }); - - const response = await request({ - hostname: '127.0.0.1', - path: '/api/users', - port: ports[1], + const port = devServer.server.address().port; + const proxyRequest = () => + request({ hostname: '127.0.0.1', path: '/api/users', port }); + + expect((await proxyRequest()).status).toBe(200); + expect(logs).toContainEqual({ + message: expect.stringContaining('[HPM] GET /api/users'), + type: 'log', }); - expect(response.status).toBe(200); - expect(containsLog(infrastructureConsole.log, '[HPM] GET /api/users')).toBe( - true, - ); - }); - - it('still prints proxy errors at the default level', async () => { - const infrastructureConsole = await startDevServer(); + const closed = once(backend, 'close'); + backend.close(); + await closed; - const response = await request({ - hostname: '127.0.0.1', - path: '/api/users', - port: ports[1], + expect((await proxyRequest()).status).toBe(504); + expect(logs).toContainEqual({ + message: expect.stringContaining('[HPM] Error occurred'), + type: 'error', }); - - expect(response.status).toBe(504); - expect( - containsLog(infrastructureConsole.error, '[HPM] Error occurred'), - ).toBe(true); - }); - - it('preserves a custom proxy logger', async () => { - await startBackend(); - const logger = { - error: rs.fn(), - info: rs.fn(), - warn: rs.fn(), - }; - - await startDevServer({ logger }); - const response = await request({ - hostname: '127.0.0.1', - path: '/api/users', - port: ports[1], - }); - - expect(response.status).toBe(200); - expect(containsLog(logger.info, '[HPM] GET /api/users')).toBe(true); }); });