Skip to content

Commit 07313fa

Browse files
committed
Support multiple ports (not smart yet)
1 parent 8c46963 commit 07313fa

File tree

11 files changed

+173
-75
lines changed

11 files changed

+173
-75
lines changed

programs/develop/webpack/dev-server.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -126,31 +126,11 @@ export async function devServer(projectPath: string, devOptions: DevOptions) {
126126
'Access-Control-Allow-Origin': '*'
127127
},
128128
port,
129-
hot: true,
130-
webSocketServer: {
131-
type: 'ws',
132-
options: {
133-
port: typeof port === 'number' ? port : undefined
134-
}
135-
}
129+
hot: true
136130
}
137131

138132
const devServer = new RspackDevServer(serverConfig, compiler as any)
139133

140-
// Pass the actual port to the reload plugin
141-
if (typeof port === 'number') {
142-
compiler.options.plugins?.forEach((plugin) => {
143-
if (
144-
plugin &&
145-
typeof plugin === 'object' &&
146-
'constructor' in plugin &&
147-
plugin.constructor.name === 'ReloadPlugin'
148-
) {
149-
;(plugin as any).port = port
150-
}
151-
})
152-
}
153-
154134
devServer.startCallback((error) => {
155135
if (error != null) {
156136
if ((error as NodeJS.ErrnoException).code === 'EADDRINUSE') {

programs/develop/webpack/plugin-reload/extensions/chrome-manager-extension/reload-service.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@ export async function connect() {
1717
}
1818

1919
webSocket.onopen = () => {
20-
console.info(`[Reload Service] Connection opened.`)
20+
console.info(
21+
`[Reload Service] Connection opened. Listening on port ${port}...`
22+
)
2123
}
2224

2325
webSocket.onmessage = async (event) => {
2426
const message = JSON.parse(event.data)
2527

2628
if (message.status === 'serverReady') {
27-
console.info('[Reload Service] Connection ready.')
29+
console.info(
30+
`[Reload Service] Server ready. Requesting initial load data...`
31+
)
2832
await requestInitialLoadData()
2933
}
3034

programs/develop/webpack/plugin-reload/extensions/chromium-based-manager-extension/reload-service.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@ export async function connect() {
1717
}
1818

1919
webSocket.onopen = () => {
20-
console.info(`[Reload Service] Connection opened.`)
20+
console.info(
21+
`[Reload Service] Connection opened. Listening on port ${port}...`
22+
)
2123
}
2224

2325
webSocket.onmessage = async (event) => {
2426
const message = JSON.parse(event.data)
2527

2628
if (message.status === 'serverReady') {
27-
console.info('[Reload Service] Connection ready.')
29+
console.info(
30+
`[Reload Service] Server ready. Requesting initial load data...`
31+
)
2832
await requestInitialLoadData()
2933
}
3034

programs/develop/webpack/plugin-reload/extensions/edge-manager-extension/reload-service.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,26 @@ export async function connect() {
99

1010
// Get port from the placeholder that will be replaced during build
1111
const port = '__RELOAD_PORT__'
12-
webSocket = new WebSocket(`ws://localhost:${port}`)
12+
webSocket = new WebSocket(`ws://localhost:${port + 1}`)
1313

1414
webSocket.onerror = (event) => {
1515
console.error(`[Reload Service] Connection error: ${JSON.stringify(event)}`)
1616
webSocket.close()
1717
}
1818

1919
webSocket.onopen = () => {
20-
console.info(`[Reload Service] Connection opened.`)
20+
console.info(
21+
`[Reload Service] Connection opened. Listening on port ${port}...`
22+
)
2123
}
2224

2325
webSocket.onmessage = async (event) => {
2426
const message = JSON.parse(event.data)
2527

2628
if (message.status === 'serverReady') {
27-
console.info('[Reload Service] Connection ready.')
29+
console.info(
30+
`[Reload Service] Server ready. Requesting initial load data...`
31+
)
2832
await requestInitialLoadData()
2933
}
3034

programs/develop/webpack/plugin-reload/extensions/firefox-manager-extension/reload-service.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,27 @@ export async function connect() {
66
return
77
}
88

9-
webSocket = new WebSocket('wss://127.0.0.1:8002')
9+
const port = '__RELOAD_PORT__'
10+
webSocket = new WebSocket(`wss://127.0.0.1:${port + 2}`)
1011

1112
webSocket.onerror = (event) => {
1213
console.error(`[Reload Service] Connection error: ${JSON.stringify(event)}`)
1314
webSocket.close()
1415
}
1516

1617
webSocket.onopen = () => {
17-
console.info(`[Reload Service] Connection opened.`)
18+
console.info(
19+
`[Reload Service] Connection opened. Listening on port ${port}...`
20+
)
1821
}
1922

2023
webSocket.onmessage = async (event) => {
2124
const message = JSON.parse(event.data)
2225

2326
if (message.status === 'serverReady') {
24-
console.info('[Reload Service] Connection ready.')
27+
console.info(
28+
`[Reload Service] Server ready. Requesting initial load data...`
29+
)
2530
await requestInitialLoadData()
2631
}
2732

programs/develop/webpack/plugin-reload/extensions/gecko-based-manager-extension/reload-service.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,28 @@ export async function connect() {
66
return
77
}
88

9-
webSocket = new WebSocket('wss://127.0.0.1:8002')
9+
// Get port from the placeholder that will be replaced during build
10+
const port = '__RELOAD_PORT__'
11+
webSocket = new WebSocket(`wss://127.0.0.1:${port + 2}`)
1012

1113
webSocket.onerror = (event) => {
1214
console.error(`[Reload Service] Connection error: ${JSON.stringify(event)}`)
1315
webSocket.close()
1416
}
1517

1618
webSocket.onopen = () => {
17-
console.info(`[Reload Service] Connection opened.`)
19+
console.info(
20+
`[Reload Service] Connection opened. Listening on port ${port}...`
21+
)
1822
}
1923

2024
webSocket.onmessage = async (event) => {
2125
const message = JSON.parse(event.data)
2226

2327
if (message.status === 'serverReady') {
24-
console.info('[Reload Service] Connection ready.')
25-
await requestInitialLoadData()
28+
console.info(
29+
`[Reload Service] Server ready. Requesting initial load data...`
30+
)
2631
}
2732

2833
if (message.changedFile) {

programs/develop/webpack/plugin-reload/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ export class ReloadPlugin {
4545
manifestPath: this.manifestPath,
4646
browser: this.browser,
4747
autoReload: this.autoReload,
48-
stats: this.stats
48+
stats: this.stats,
49+
port: this.port
4950
}).apply(compiler)
5051
}
5152
}

programs/develop/webpack/plugin-reload/steps/create-web-socket-server/web-socket-server/start-server.ts

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as path from 'path'
22
import * as fs from 'fs'
3-
import {WebSocketServer} from 'ws'
3+
import {WebSocketServer, WebSocket} from 'ws'
44
import {Compiler} from '@rspack/core'
55
import * as messages from '../../../../lib/messages'
66
import {type Manifest} from '../../../../webpack-types'
@@ -23,27 +23,39 @@ interface Message {
2323
function setupServer(port: number, browser: DevOptions['browser']) {
2424
switch (browser) {
2525
case 'chrome':
26-
return new WebSocketServer({
27-
host: 'localhost',
26+
return {
27+
server: new WebSocketServer({
28+
host: 'localhost',
29+
port
30+
}),
2831
port
29-
})
32+
}
3033

3134
case 'edge':
32-
return new WebSocketServer({
33-
host: 'localhost',
34-
port: port + 1
35-
})
35+
return {
36+
server: new WebSocketServer({
37+
host: 'localhost',
38+
port: port + 1
39+
}),
40+
port
41+
}
3642

3743
case 'firefox':
38-
return new WebSocketServer({
39-
server: httpsServer(port + 2).server
40-
})
44+
return {
45+
server: new WebSocketServer({
46+
server: httpsServer(port + 2).server
47+
}),
48+
port
49+
}
4150

4251
default:
43-
return new WebSocketServer({
44-
host: 'localhost',
52+
return {
53+
server: new WebSocketServer({
54+
host: 'localhost',
55+
port: 8888
56+
}),
4557
port: 8888
46-
})
58+
}
4759
}
4860
}
4961

@@ -53,15 +65,24 @@ export async function startServer(compiler: Compiler, options: DevOptions) {
5365
fs.readFileSync(path.join(projectPath, 'manifest.json'), 'utf-8')
5466
)
5567

56-
// Use the port from options instead of hardcoding
57-
const port = options.port || 8080
58-
const webSocketServer = setupServer(port, options.browser)
68+
const {server: webSocketServer} = setupServer(options.port!, options.browser)
69+
70+
// Track all active connections
71+
const connections = new Set<WebSocket>()
5972

6073
webSocketServer.on('connection', (ws) => {
74+
// Add to active connections
75+
connections.add(ws)
76+
6177
ws.send(JSON.stringify({status: 'serverReady'}))
6278

6379
ws.on('error', (error) => {
6480
console.log(messages.webSocketError(error))
81+
connections.delete(ws)
82+
})
83+
84+
ws.on('close', () => {
85+
connections.delete(ws)
6586
})
6687

6788
ws.on('message', (msg) => {
@@ -102,5 +123,30 @@ export async function startServer(compiler: Compiler, options: DevOptions) {
102123
}
103124
}
104125

126+
// Handle graceful shutdown
127+
const cleanup = () => {
128+
console.log('\nClosing WebSocket connections...')
129+
130+
// Close all active connections
131+
for (const ws of connections) {
132+
try {
133+
ws.close(1000, 'Server shutting down')
134+
} catch (error) {
135+
console.error('Error closing WebSocket connection:', error)
136+
}
137+
}
138+
139+
// Close the server
140+
webSocketServer.close(() => {
141+
console.log('WebSocket server closed')
142+
process.exit(0)
143+
})
144+
}
145+
146+
// Handle process termination signals
147+
process.on('SIGINT', cleanup)
148+
process.on('SIGTERM', cleanup)
149+
process.on('SIGHUP', cleanup)
150+
105151
return webSocketServer
106152
}

0 commit comments

Comments
 (0)