From 70d199c632b6281358c603333c21dfd6fb864820 Mon Sep 17 00:00:00 2001 From: adrians5j Date: Tue, 13 Oct 2026 13:54:23 +0200 Subject: [PATCH] fix(build-tools): stop one WebSocket message from crashing the API The API bundle replaced ws's optional native `bufferutil` module with an empty one (`resolve.fallback: { bufferutil: false }`). ws loads it inside a try/catch, and an empty module loads without throwing, so ws switched to `bufferUtil.unmask`, which is undefined. Every client frame is masked, so any incoming WebSocket message of 32 bytes or more threw "bufferUtil.unmask is not a function" and took the API process down. On a self-hosted API that needed no authentication: one message to the WebSocket endpoint was enough. bufferutil is now left out with an IgnorePlugin entry instead, like jsdom's `canvas`. An ignored module throws MODULE_NOT_FOUND when required, ws catches that, and it keeps its JavaScript mask/unmask. Co-Authored-By: Claude Opus 5.5 --- .../bundling/function/createRsbuildConfig.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/build-tools/bundling/function/createRsbuildConfig.js b/packages/build-tools/bundling/function/createRsbuildConfig.js index 48ebb993343..9abe0052750 100644 --- a/packages/build-tools/bundling/function/createRsbuildConfig.js +++ b/packages/build-tools/bundling/function/createRsbuildConfig.js @@ -94,15 +94,18 @@ export const createRsbuildConfig = async ({ cwd, enforceMaxBundleSize }) => { new rspack.IgnorePlugin({ resourceRegExp: /^canvas$/, contextRegExp: /jsdom/ + }), + // Leave out `ws`'s optional native `bufferutil` module. It has to be an + // IgnorePlugin, not `resolve.fallback: { bufferutil: false }`: a `false` fallback + // bundles an empty module, so ws's `require("bufferutil")` succeeds and every + // incoming frame of 32 bytes or more calls the missing `bufferUtil.unmask` and + // crashes the process. An ignored module throws when required, which ws catches, + // and it keeps using its JavaScript implementation. + new rspack.IgnorePlugin({ + resourceRegExp: /^bufferutil$/, + contextRegExp: /[\\/]ws[\\/]/ }) ], - resolve: { - fallback: { - // Disable optional native dependency used by 'ws' package for performance optimizations. - // Not needed in Lambda environment and can cause bundling/deployment issues. - bufferutil: false - } - }, // bree's root-jobs loader does `await import(importUrl)` on a path it builds at runtime, // which rspack can't resolve statically, so it reports a critical dependency. That import // sits behind `if (this.config.root && ...)` (node_modules/bree/src/index.js), and