From 2e2e695d01be9725191a9c5ca0b75ed2e04b7537 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:06:59 +0000 Subject: [PATCH 1/2] Remove client-side ws module usage, use native WebSocket in Node.js >= 21 Agent-Logs-Url: https://github.com/jeroen/emscripten/sessions/923a9d3e-4844-44dc-b117-732a10bbfe10 Co-authored-by: jeroen <216319+jeroen@users.noreply.github.com> --- src/lib/libsockfs.js | 16 ++++------------ src/settings.js | 8 ++++---- .../test_codesize_minimal_O0.expected.js | 4 ++-- tools/feature_matrix.py | 2 +- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/lib/libsockfs.js b/src/lib/libsockfs.js index 01d6f831da2bf..bba6c1add23bd 100644 --- a/src/lib/libsockfs.js +++ b/src/lib/libsockfs.js @@ -212,17 +212,7 @@ addToLibrary({ #if SOCKET_DEBUG dbg(`websocket: connect: ${url}, ${subProtocols.toString()}`); #endif - // If node we use the ws library. - var WebSocketConstructor; -#if ENVIRONMENT_MAY_BE_NODE - if (ENVIRONMENT_IS_NODE) { - WebSocketConstructor = /** @type{(typeof WebSocket)} */(require('ws')); - } else -#endif // ENVIRONMENT_MAY_BE_NODE - { - WebSocketConstructor = WebSocket; - } - ws = new WebSocketConstructor(url, opts); + ws = new WebSocket(url, opts); ws.binaryType = 'arraybuffer'; } catch (e) { #if SOCKET_DEBUG @@ -338,7 +328,8 @@ addToLibrary({ SOCKFS.emit('message', sock.stream.fd); }; - if (ENVIRONMENT_IS_NODE) { + if (typeof peer.socket.on === 'function') { + // EventEmitter-style events (server-side ws library objects in Node.js). peer.socket.on('open', handleOpen); peer.socket.on('message', function(data, isBinary) { if (!isBinary) { @@ -359,6 +350,7 @@ addToLibrary({ // don't throw }); } else { + // Browser-style events (browser WebSocket and native Node.js WebSocket >= 21). peer.socket.onopen = handleOpen; peer.socket.onclose = function() { SOCKFS.emit('close', sock.stream.fd); diff --git a/src/settings.js b/src/settings.js index fdb3a4ad1864e..a5ac7635528ff 100644 --- a/src/settings.js +++ b/src/settings.js @@ -1921,10 +1921,10 @@ var MIN_CHROME_VERSION = 85; // Specifies minimum node version to target for the generated code. This is // distinct from the minimum version required to run the emscripten compiler. // Version is encoded in MMmmVV, e.g. 181401 denotes Node 18.14.01. -// Minimum supported value is 180300, which was released 2022-05-18 (see -// feature_matrix.py). This version aligns with the version available in -// debian/stable (bookworm). -var MIN_NODE_VERSION = 180300; +// Minimum supported value is 210000 (Node.js 21.0.0, released 2023-10-17). +// Node.js 21+ includes the native WebSocket client API, removing the need +// for the external 'ws' module for WebSocket client connections. +var MIN_NODE_VERSION = 210000; // If true, uses minimal sized runtime without POSIX features, Module, // preRun/preInit/etc., Emscripten built-in XHR loading or library_browser.js. diff --git a/test/codesize/test_codesize_minimal_O0.expected.js b/test/codesize/test_codesize_minimal_O0.expected.js index 90ccede8fa797..d5b11365b52ea 100644 --- a/test/codesize/test_codesize_minimal_O0.expected.js +++ b/test/codesize/test_codesize_minimal_O0.expected.js @@ -19,8 +19,8 @@ // Note: We use a typeof check here instead of optional chaining using // globalThis because older browsers might not have globalThis defined. var currentNodeVersion = typeof process !== 'undefined' && process.versions?.node ? humanReadableVersionToPacked(process.versions.node) : TARGET_NOT_SUPPORTED; - if (currentNodeVersion < 180300) { - throw new Error(`This emscripten-generated code requires node v${ packedVersionToHumanReadable(180300) } (detected v${packedVersionToHumanReadable(currentNodeVersion)})`); + if (currentNodeVersion < 210000) { + throw new Error(`This emscripten-generated code requires node v${ packedVersionToHumanReadable(210000) } (detected v${packedVersionToHumanReadable(currentNodeVersion)})`); } var userAgent = typeof navigator !== 'undefined' && navigator.userAgent; diff --git a/tools/feature_matrix.py b/tools/feature_matrix.py index 0c0e01fa93449..89c49afa886e0 100644 --- a/tools/feature_matrix.py +++ b/tools/feature_matrix.py @@ -27,7 +27,7 @@ OLDEST_SUPPORTED_SAFARI = 120200 # Released on 2019-03-25 # This is the oldest version of node that we do any testing with. # Keep this in sync with the test-node-compat in .circleci/config.yml. -OLDEST_SUPPORTED_NODE = 180300 +OLDEST_SUPPORTED_NODE = 210000 class Feature(IntEnum): From 7d7be185db7ec0cbee8de02a4ad48dfd34030e24 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:52:46 +0000 Subject: [PATCH 2/2] Update test_codesize_file_preload.expected.js: remove nodeCrypto block no longer compiled for Node >= 21 Agent-Logs-Url: https://github.com/jeroen/emscripten/sessions/70210fb3-c99f-45ac-8a49-40296067c9ca Co-authored-by: jeroen <216319+jeroen@users.noreply.github.com> --- test/codesize/test_codesize_file_preload.expected.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/codesize/test_codesize_file_preload.expected.js b/test/codesize/test_codesize_file_preload.expected.js index 1ab70743544e1..e444870d7807f 100644 --- a/test/codesize/test_codesize_file_preload.expected.js +++ b/test/codesize/test_codesize_file_preload.expected.js @@ -622,11 +622,6 @@ var PATH = { }; var initRandomFill = () => { - // This block is not needed on v19+ since crypto.getRandomValues is builtin - if (ENVIRONMENT_IS_NODE) { - var nodeCrypto = require("node:crypto"); - return view => nodeCrypto.randomFillSync(view); - } return view => (crypto.getRandomValues(view), 0); };