1- import type { SocketMessage } from '../server/socketServer' ;
1+ import type {
2+ ClientMessage ,
3+ ClientMessageRuntimeError ,
4+ SocketMessage ,
5+ } from '../server/socketServer' ;
26import type { NormalizedClientConfig } from '../types' ;
37
48const config : NormalizedClientConfig = RSBUILD_CLIENT_CONFIG ;
@@ -150,6 +154,13 @@ let socket: WebSocket | null = null;
150154let reconnectCount = 0 ;
151155let pingIntervalId : ReturnType < typeof setInterval > ;
152156
157+ const isSocketReady = ( ) => socket && socket . readyState === socket . OPEN ;
158+ const socketSend = ( data : ClientMessage ) => {
159+ if ( isSocketReady ( ) ) {
160+ socket ! . send ( JSON . stringify ( data ) ) ;
161+ }
162+ } ;
163+
153164function onOpen ( ) {
154165 // Notify users that the WebSocket has successfully connected.
155166 console . info ( '[rsbuild] WebSocket connected.' ) ;
@@ -160,10 +171,15 @@ function onOpen() {
160171 // To prevent WebSocket timeouts caused by proxies (e.g., nginx, docker),
161172 // send a periodic ping message to keep the connection alive.
162173 pingIntervalId = setInterval ( ( ) => {
163- if ( socket && socket . readyState === socket . OPEN ) {
164- socket . send ( JSON . stringify ( { type : 'ping' } ) ) ;
165- }
174+ socketSend ( { type : 'ping' } ) ;
166175 } , 30000 ) ;
176+
177+ if ( errorMessages . length ) {
178+ errorMessages . forEach ( ( message ) => {
179+ socketSend ( message ) ;
180+ } ) ;
181+ errorMessages . length = 0 ;
182+ }
167183}
168184
169185function onMessage ( e : MessageEvent < string > ) {
@@ -214,7 +230,7 @@ function onClose() {
214230 setTimeout ( connect , 1000 * 1.5 ** reconnectCount ) ;
215231}
216232
217- function onError ( ) {
233+ function onSocketError ( ) {
218234 if ( formatURL ( ) !== formatURL ( true ) ) {
219235 console . error (
220236 '[rsbuild] WebSocket connection failed. Trying direct connection fallback.' ,
@@ -225,6 +241,20 @@ function onError() {
225241 }
226242}
227243
244+ const errorMessages : ClientMessageRuntimeError [ ] = [ ] ;
245+
246+ function onRuntimeError ( event : ErrorEvent ) {
247+ const message : ClientMessageRuntimeError = {
248+ type : 'runtime-error' ,
249+ message : event . message ,
250+ } ;
251+ if ( isSocketReady ( ) ) {
252+ socketSend ( message ) ;
253+ } else {
254+ errorMessages . push ( message ) ;
255+ }
256+ }
257+
228258// Establishing a WebSocket connection with the server.
229259function connect ( fallback = false ) {
230260 if ( reconnectCount === 0 ) {
@@ -240,7 +270,7 @@ function connect(fallback = false) {
240270 socket . addEventListener ( 'message' , onMessage ) ;
241271 // Handle errors
242272 if ( ! fallback ) {
243- socket . addEventListener ( 'error' , onError ) ;
273+ socket . addEventListener ( 'error' , onSocketError ) ;
244274 }
245275}
246276
@@ -250,7 +280,7 @@ function removeListeners() {
250280 socket . removeEventListener ( 'open' , onOpen ) ;
251281 socket . removeEventListener ( 'close' , onClose ) ;
252282 socket . removeEventListener ( 'message' , onMessage ) ;
253- socket . removeEventListener ( 'error' , onError ) ;
283+ socket . removeEventListener ( 'error' , onSocketError ) ;
254284 }
255285}
256286
@@ -260,4 +290,8 @@ function reloadPage() {
260290 }
261291}
262292
293+ if ( typeof window !== 'undefined' ) {
294+ window . addEventListener ( 'error' , onRuntimeError ) ;
295+ }
296+
263297connect ( ) ;
0 commit comments