@rspack/dev-server 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/LICENSE +1 -1
- package/dist/config.d.ts +19 -14
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -52
- package/dist/config.js.map +1 -1
- package/dist/server.d.ts +14 -41
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +308 -257
- package/dist/server.js.map +1 -1
- package/jest.config.js +3 -1
- package/package.json +10 -9
- package/src/config.ts +21 -67
- package/src/server.ts +350 -311
- package/tests/__snapshots__/normalizeOptions.test.ts.snap +223 -24
- package/tests/e2e/hot-reaload.test.ts +35 -39
- package/tests/e2e-fixtures/react/node_modules/react/LICENSE +21 -0
- package/tests/e2e-fixtures/react/node_modules/react/README.md +37 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-dev-runtime.development.js +1296 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-dev-runtime.production.min.js +10 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-dev-runtime.profiling.min.js +10 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-runtime.development.js +1314 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-runtime.production.min.js +11 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-runtime.profiling.min.js +11 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react.development.js +2739 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react.production.min.js +26 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react.shared-subset.development.js +20 -0
- package/tests/e2e-fixtures/react/node_modules/react/cjs/react.shared-subset.production.min.js +10 -0
- package/tests/e2e-fixtures/react/node_modules/react/index.js +7 -0
- package/tests/e2e-fixtures/react/node_modules/react/jsx-dev-runtime.js +7 -0
- package/tests/e2e-fixtures/react/node_modules/react/jsx-runtime.js +7 -0
- package/tests/e2e-fixtures/react/node_modules/react/package.json +47 -0
- package/tests/e2e-fixtures/react/node_modules/react/react.shared-subset.js +7 -0
- package/tests/e2e-fixtures/react/node_modules/react/umd/react.development.js +3342 -0
- package/tests/e2e-fixtures/react/node_modules/react/umd/react.production.min.js +31 -0
- package/tests/e2e-fixtures/react/node_modules/react/umd/react.profiling.min.js +31 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/LICENSE +21 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/README.md +60 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.browser.development.js +7018 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.min.js +93 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js +7078 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js +101 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.browser.development.js +7003 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js +96 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.node.development.js +7059 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.node.production.min.js +102 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-test-utils.development.js +1741 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-test-utils.production.min.js +40 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom.development.js +29868 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom.production.min.js +323 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom.profiling.min.js +367 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/client.js +25 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/index.js +38 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/package.json +62 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/profiling.js +38 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/server.browser.js +17 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/server.js +3 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/server.node.js +17 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/test-utils.js +7 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server-legacy.browser.development.js +7015 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server-legacy.browser.production.min.js +75 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server.browser.development.js +7000 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server.browser.production.min.js +76 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-test-utils.development.js +1737 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-test-utils.production.min.js +33 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom.development.js +29869 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom.production.min.js +267 -0
- package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom.profiling.min.js +285 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/LICENSE +21 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/README.md +9 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_mock.development.js +700 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_mock.production.min.js +20 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_post_task.development.js +207 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_post_task.production.min.js +14 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler.development.js +634 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler.production.min.js +19 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/index.js +7 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/package.json +36 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler-unstable_mock.development.js +699 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler-unstable_mock.production.min.js +19 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler.development.js +152 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler.production.min.js +146 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler.profiling.min.js +146 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/unstable_mock.js +7 -0
- package/tests/e2e-fixtures/react/node_modules/scheduler/unstable_post_task.js +7 -0
- package/tests/e2e-fixtures/react/package.json +2 -0
- package/tests/e2e-fixtures/react/webpack.config.js +6 -2
- package/tests/helpers/emitFile.ts +58 -4
- package/tests/normalizeOptions.test.ts +58 -16
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/logger.d.ts +0 -7
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -28
- package/dist/logger.js.map +0 -1
- package/dist/ws.d.ts +0 -13
- package/dist/ws.d.ts.map +0 -1
- package/dist/ws.js +0 -12
- package/dist/ws.js.map +0 -1
- package/src/logger.ts +0 -30
- package/src/ws.ts +0 -18
package/src/server.ts
CHANGED
|
@@ -1,154 +1,207 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type { Logger } from "./logger";
|
|
1
|
+
import { Compiler, MultiCompiler } from "@rspack/core";
|
|
3
2
|
import type { Socket } from "net";
|
|
4
3
|
import type { FSWatcher, WatchOptions } from "chokidar";
|
|
5
|
-
import
|
|
6
|
-
import type {
|
|
7
|
-
Application,
|
|
8
|
-
RequestHandler as ExpressRequestHandler,
|
|
9
|
-
ErrorRequestHandler as ExpressErrorRequestHandler
|
|
10
|
-
} from "express";
|
|
11
|
-
import type { DevMiddleware } from "@rspack/dev-middleware";
|
|
4
|
+
import rdm, { getRspackMemoryAssets } from "@rspack/dev-middleware";
|
|
12
5
|
import type { Server } from "http";
|
|
13
|
-
import type { ResolvedDev } from "./config";
|
|
14
6
|
import fs from "fs";
|
|
15
|
-
import chokidar from "chokidar";
|
|
16
|
-
import http from "http";
|
|
17
|
-
import { createLogger } from "./logger";
|
|
18
7
|
import WebpackDevServer from "webpack-dev-server";
|
|
19
|
-
import
|
|
8
|
+
import type { ResolvedDevServer, DevServer } from "./config";
|
|
20
9
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
name?: string;
|
|
27
|
-
path?: string;
|
|
28
|
-
middleware: ExpressErrorRequestHandler | ExpressRequestHandler;
|
|
29
|
-
}
|
|
30
|
-
interface Listener {
|
|
31
|
-
name: string | Symbol;
|
|
32
|
-
listener: (...args: any) => void;
|
|
33
|
-
}
|
|
34
|
-
type Host = "local-ip" | "local-ipv4" | "local-ipv6" | string;
|
|
35
|
-
type Port = number | string | "auto";
|
|
36
|
-
|
|
37
|
-
// copy from webpack-dev-server
|
|
38
|
-
export class RspackDevServer {
|
|
39
|
-
options: ResolvedDev;
|
|
40
|
-
logger: Logger;
|
|
10
|
+
export class RspackDevServer extends WebpackDevServer {
|
|
11
|
+
/**
|
|
12
|
+
* resolved after `normalizedOptions`
|
|
13
|
+
*/
|
|
14
|
+
options: ResolvedDevServer;
|
|
41
15
|
staticWatchers: FSWatcher[];
|
|
42
16
|
sockets: Socket[];
|
|
43
|
-
app: Application;
|
|
44
17
|
server: Server;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// TODO: now only support 'ws'
|
|
49
|
-
webSocketServer: WebSocketServer | undefined;
|
|
50
|
-
|
|
51
|
-
constructor(public compiler: Compiler) {
|
|
52
|
-
this.logger = createLogger("rspack-dev-server");
|
|
53
|
-
this.staticWatchers = [];
|
|
54
|
-
this.listeners = [];
|
|
55
|
-
this.sockets = [];
|
|
56
|
-
this.currentHash = "";
|
|
57
|
-
this.options = this.normalizeOptions(compiler.options.devServer);
|
|
58
|
-
this.rewriteCompilerOptions();
|
|
59
|
-
this.addAdditionEntires();
|
|
60
|
-
}
|
|
18
|
+
// @ts-expect-error
|
|
19
|
+
public compiler: Compiler | MultiCompiler;
|
|
20
|
+
webSocketServer: WebpackDevServer.WebSocketServerImplementation | undefined;
|
|
61
21
|
|
|
62
|
-
|
|
63
|
-
|
|
22
|
+
constructor(options: DevServer, compiler: Compiler | MultiCompiler) {
|
|
23
|
+
// @ts-expect-error
|
|
24
|
+
super(options, compiler);
|
|
64
25
|
}
|
|
65
26
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
27
|
+
addAdditionEntires(compiler: Compiler) {
|
|
28
|
+
const additionalEntries: string[] = [];
|
|
29
|
+
// TODO: align with webpack-dev-server after options.target is aligned
|
|
30
|
+
const isWebTarget =
|
|
31
|
+
compiler.options.target.includes("web") ||
|
|
32
|
+
compiler.options.target.includes("webworker");
|
|
33
|
+
if (this.options.client && isWebTarget) {
|
|
34
|
+
let webSocketURLStr = "";
|
|
35
|
+
|
|
36
|
+
if (this.options.webSocketServer) {
|
|
37
|
+
const webSocketURL = this.options.client
|
|
38
|
+
.webSocketURL as WebpackDevServer.WebSocketURL;
|
|
39
|
+
const webSocketServer = this.options.webSocketServer;
|
|
40
|
+
const searchParams = new URLSearchParams();
|
|
41
|
+
|
|
42
|
+
let protocol: string;
|
|
43
|
+
|
|
44
|
+
// We are proxying dev server and need to specify custom `hostname`
|
|
45
|
+
if (typeof webSocketURL.protocol !== "undefined") {
|
|
46
|
+
protocol = webSocketURL.protocol;
|
|
47
|
+
} else {
|
|
48
|
+
protocol = this.options.server.type === "http" ? "ws:" : "wss:";
|
|
49
|
+
}
|
|
78
50
|
|
|
79
|
-
|
|
80
|
-
const entries: string[] = [];
|
|
51
|
+
searchParams.set("protocol", protocol);
|
|
81
52
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
86
|
-
entries.push(hotUpdateEntryPath);
|
|
53
|
+
if (typeof webSocketURL.username !== "undefined") {
|
|
54
|
+
searchParams.set("username", webSocketURL.username);
|
|
55
|
+
}
|
|
87
56
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
);
|
|
92
|
-
entries.push(reactRefreshEntryPath);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
57
|
+
if (typeof webSocketURL.password !== "undefined") {
|
|
58
|
+
searchParams.set("password", webSocketURL.password);
|
|
59
|
+
}
|
|
95
60
|
|
|
96
|
-
|
|
97
|
-
entries.push(devClientEntryPath);
|
|
98
|
-
for (const key in this.compiler.options.entry) {
|
|
99
|
-
this.compiler.options.entry[key].import.unshift(...entries);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
61
|
+
let hostname: string;
|
|
102
62
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
63
|
+
// SockJS is not supported server mode, so `hostname` and `port` can't specified, let's ignore them
|
|
64
|
+
// TODO show warning about this
|
|
65
|
+
const isSockJSType = webSocketServer.type === "sockjs";
|
|
106
66
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
67
|
+
// We are proxying dev server and need to specify custom `hostname`
|
|
68
|
+
if (typeof webSocketURL.hostname !== "undefined") {
|
|
69
|
+
hostname = webSocketURL.hostname;
|
|
70
|
+
}
|
|
71
|
+
// Web socket server works on custom `hostname`, only for `ws` because `sock-js` is not support custom `hostname`
|
|
72
|
+
else if (
|
|
73
|
+
typeof webSocketServer.options.host !== "undefined" &&
|
|
74
|
+
!isSockJSType
|
|
75
|
+
) {
|
|
76
|
+
hostname = webSocketServer.options.host;
|
|
77
|
+
}
|
|
78
|
+
// The `host` option is specified
|
|
79
|
+
else if (typeof this.options.host !== "undefined") {
|
|
80
|
+
hostname = this.options.host;
|
|
81
|
+
}
|
|
82
|
+
// The `port` option is not specified
|
|
83
|
+
else {
|
|
84
|
+
hostname = "0.0.0.0";
|
|
85
|
+
}
|
|
110
86
|
|
|
111
|
-
|
|
112
|
-
return WebpackDevServer.internalIP(family);
|
|
113
|
-
}
|
|
87
|
+
searchParams.set("hostname", hostname);
|
|
114
88
|
|
|
115
|
-
|
|
116
|
-
family: "v6" | "v4"
|
|
117
|
-
): Promise<string | undefined> {
|
|
118
|
-
return WebpackDevServer.internalIPSync(family);
|
|
119
|
-
}
|
|
89
|
+
let port: number | string;
|
|
120
90
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
91
|
+
// We are proxying dev server and need to specify custom `port`
|
|
92
|
+
if (typeof webSocketURL.port !== "undefined") {
|
|
93
|
+
port = webSocketURL.port;
|
|
94
|
+
}
|
|
95
|
+
// Web socket server works on custom `port`, only for `ws` because `sock-js` is not support custom `port`
|
|
96
|
+
else if (
|
|
97
|
+
typeof webSocketServer.options.port !== "undefined" &&
|
|
98
|
+
!isSockJSType
|
|
99
|
+
) {
|
|
100
|
+
port = webSocketServer.options.port;
|
|
101
|
+
}
|
|
102
|
+
// The `port` option is specified
|
|
103
|
+
else if (typeof this.options.port === "number") {
|
|
104
|
+
port = this.options.port;
|
|
105
|
+
}
|
|
106
|
+
// The `port` option is specified using `string`
|
|
107
|
+
else if (
|
|
108
|
+
typeof this.options.port === "string" &&
|
|
109
|
+
this.options.port !== "auto"
|
|
110
|
+
) {
|
|
111
|
+
port = Number(this.options.port);
|
|
112
|
+
}
|
|
113
|
+
// The `port` option is not specified or set to `auto`
|
|
114
|
+
else {
|
|
115
|
+
port = "0";
|
|
116
|
+
}
|
|
124
117
|
|
|
125
|
-
|
|
126
|
-
return WebpackDevServer.getFreePort(port, host);
|
|
127
|
-
}
|
|
118
|
+
searchParams.set("port", String(port));
|
|
128
119
|
|
|
129
|
-
|
|
130
|
-
// TODO: we need remove the `webpack-dev-server` tag in WebpackDevServer;
|
|
131
|
-
return "";
|
|
132
|
-
}
|
|
120
|
+
let pathname = "";
|
|
133
121
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
122
|
+
// We are proxying dev server and need to specify custom `pathname`
|
|
123
|
+
if (typeof webSocketURL.pathname !== "undefined") {
|
|
124
|
+
pathname = webSocketURL.pathname;
|
|
125
|
+
}
|
|
126
|
+
// Web socket server works on custom `path`
|
|
127
|
+
else if (
|
|
128
|
+
typeof webSocketServer.options.prefix !== "undefined" ||
|
|
129
|
+
typeof webSocketServer.options.path !== "undefined"
|
|
130
|
+
) {
|
|
131
|
+
pathname =
|
|
132
|
+
webSocketServer.options.prefix || webSocketServer.options.path;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
searchParams.set("pathname", pathname);
|
|
136
|
+
|
|
137
|
+
const client = /** @type {ClientConfiguration} */ this.options.client;
|
|
138
|
+
|
|
139
|
+
if (typeof client.logging !== "undefined") {
|
|
140
|
+
searchParams.set("logging", client.logging);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (typeof client.progress !== "undefined") {
|
|
144
|
+
searchParams.set("progress", String(client.progress));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (typeof client.overlay !== "undefined") {
|
|
148
|
+
searchParams.set(
|
|
149
|
+
"overlay",
|
|
150
|
+
typeof client.overlay === "boolean"
|
|
151
|
+
? String(client.overlay)
|
|
152
|
+
: JSON.stringify(client.overlay)
|
|
153
|
+
);
|
|
154
|
+
}
|
|
137
155
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
156
|
+
if (typeof client.reconnect !== "undefined") {
|
|
157
|
+
searchParams.set(
|
|
158
|
+
"reconnect",
|
|
159
|
+
typeof client.reconnect === "number"
|
|
160
|
+
? String(client.reconnect)
|
|
161
|
+
: "10"
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (typeof this.options.hot !== "undefined") {
|
|
166
|
+
searchParams.set("hot", String(this.options.hot));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (typeof this.options.liveReload !== "undefined") {
|
|
170
|
+
searchParams.set("live-reload", String(this.options.liveReload));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
webSocketURLStr = searchParams.toString();
|
|
147
174
|
}
|
|
175
|
+
|
|
176
|
+
// TODO: should use providerPlugin
|
|
177
|
+
additionalEntries.push(this.getClientTransport());
|
|
178
|
+
|
|
179
|
+
additionalEntries.push(
|
|
180
|
+
`${require.resolve("@rspack/dev-client")}?${webSocketURLStr}`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (this.options.hot) {
|
|
185
|
+
const hotUpdateEntryPath = require.resolve(
|
|
186
|
+
"@rspack/dev-client/devServer"
|
|
187
|
+
);
|
|
188
|
+
additionalEntries.push(hotUpdateEntryPath);
|
|
189
|
+
|
|
190
|
+
if (compiler.options.builtins.react?.refresh) {
|
|
191
|
+
const reactRefreshEntryPath = require.resolve(
|
|
192
|
+
"@rspack/dev-client/react-refresh"
|
|
193
|
+
);
|
|
194
|
+
additionalEntries.push(reactRefreshEntryPath);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
for (const key in compiler.options.entry) {
|
|
199
|
+
compiler.options.entry[key].import.unshift(...additionalEntries);
|
|
148
200
|
}
|
|
149
201
|
}
|
|
150
202
|
|
|
151
203
|
watchFiles(watchPath: string | string[], watchOptions?: WatchOptions): void {
|
|
204
|
+
const chokidar = require("chokidar");
|
|
152
205
|
const watcher = chokidar.watch(watchPath, watchOptions);
|
|
153
206
|
|
|
154
207
|
// disabling refreshing on changing the content
|
|
@@ -172,80 +225,154 @@ export class RspackDevServer {
|
|
|
172
225
|
this.staticWatchers.push(watcher);
|
|
173
226
|
}
|
|
174
227
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
228
|
+
getClientTransport(): string {
|
|
229
|
+
// WARNING: we can't use `super.getClientTransport`,
|
|
230
|
+
// because we doesn't had same directory structure.
|
|
231
|
+
// and TODO: we need impelement `webpack.providerPlugin`
|
|
232
|
+
let clientImplementation: string | undefined;
|
|
233
|
+
let clientImplementationFound = true;
|
|
234
|
+
const isKnownWebSocketServerImplementation =
|
|
235
|
+
this.options.webSocketServer &&
|
|
236
|
+
typeof this.options.webSocketServer.type === "string" &&
|
|
237
|
+
(this.options.webSocketServer.type === "ws" ||
|
|
238
|
+
this.options.webSocketServer.type === "sockjs");
|
|
239
|
+
|
|
240
|
+
let clientTransport: string | undefined;
|
|
241
|
+
|
|
242
|
+
if (this.options.client) {
|
|
243
|
+
if (
|
|
244
|
+
// @ts-ignore
|
|
245
|
+
typeof this.options.client.webSocketTransport !== "undefined"
|
|
246
|
+
) {
|
|
247
|
+
// @ts-ignore
|
|
248
|
+
clientTransport = this.options.client.webSocketTransport;
|
|
249
|
+
} else if (isKnownWebSocketServerImplementation) {
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
clientTransport = this.options.webSocketServer.type;
|
|
252
|
+
} else {
|
|
253
|
+
clientTransport = "ws";
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
clientTransport = "ws";
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
switch (typeof clientTransport) {
|
|
260
|
+
case "string":
|
|
261
|
+
// could be 'sockjs', 'ws', or a path that should be required
|
|
262
|
+
if (clientTransport === "sockjs") {
|
|
263
|
+
clientImplementation = require.resolve(
|
|
264
|
+
"@rspack/dev-client/clients/SockJSClient"
|
|
265
|
+
);
|
|
266
|
+
} else if (clientTransport === "ws") {
|
|
267
|
+
clientImplementation = require.resolve(
|
|
268
|
+
"@rspack/dev-client/clients/WebSocketClient"
|
|
269
|
+
);
|
|
270
|
+
} else {
|
|
271
|
+
try {
|
|
272
|
+
clientImplementation = require.resolve(clientTransport);
|
|
273
|
+
throw Error("Do not support custom ws client now");
|
|
274
|
+
} catch (e) {
|
|
275
|
+
clientImplementationFound = false;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
break;
|
|
279
|
+
default:
|
|
280
|
+
clientImplementationFound = false;
|
|
281
|
+
}
|
|
282
|
+
if (!clientImplementationFound) {
|
|
283
|
+
throw new Error(
|
|
284
|
+
`${
|
|
285
|
+
!isKnownWebSocketServerImplementation
|
|
286
|
+
? "When you use custom web socket implementation you must explicitly specify client.webSocketTransport. "
|
|
287
|
+
: ""
|
|
288
|
+
}client.webSocketTransport must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to a JS file via require.resolve(...) which exports a class `
|
|
289
|
+
);
|
|
178
290
|
}
|
|
291
|
+
|
|
292
|
+
return clientImplementation;
|
|
179
293
|
}
|
|
180
294
|
|
|
181
|
-
async
|
|
295
|
+
async initialize() {
|
|
296
|
+
const compilers =
|
|
297
|
+
this.compiler instanceof MultiCompiler
|
|
298
|
+
? this.compiler.compilers
|
|
299
|
+
: [this.compiler];
|
|
300
|
+
|
|
301
|
+
compilers.forEach(compiler => {
|
|
302
|
+
compiler.options.builtins.react ??= {};
|
|
303
|
+
if (this.options.hot) {
|
|
304
|
+
compiler.options.builtins.react.refresh ??= true;
|
|
305
|
+
compiler.options.builtins.react.development ??= true;
|
|
306
|
+
} else if (compiler.options.builtins.react.refresh) {
|
|
307
|
+
this.logger.warn(
|
|
308
|
+
"builtins.react.refresh needs builtins.react.development and devServer.hot enabled"
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
if (this.options.webSocketServer) {
|
|
314
|
+
compilers.forEach(compiler => {
|
|
315
|
+
this.addAdditionEntires(compiler);
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
|
|
182
319
|
this.setupHooks();
|
|
320
|
+
// @ts-expect-error: `setupApp` is private function in base class.
|
|
183
321
|
this.setupApp();
|
|
184
|
-
|
|
185
|
-
this.
|
|
186
|
-
this.createWebsocketServer();
|
|
322
|
+
// @ts-expect-error: `setupHostHeaderCheck` is private function in base class.
|
|
323
|
+
this.setupHostHeaderCheck();
|
|
187
324
|
this.setupDevMiddleware();
|
|
325
|
+
// @ts-expect-error: `setupBuiltInRoutes` is private function in base class.
|
|
326
|
+
this.setupBuiltInRoutes();
|
|
327
|
+
// @ts-expect-error: `setupWatchFiles` is private function in base class.
|
|
328
|
+
this.setupWatchFiles();
|
|
329
|
+
// @ts-expect-error: `setupWatchStaticFiles` is private function in base class.
|
|
330
|
+
this.setupWatchStaticFiles();
|
|
188
331
|
this.setupMiddlewares();
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
() => {
|
|
199
|
-
|
|
200
|
-
|
|
332
|
+
// @ts-expect-error: `createServer` is private function in base class.
|
|
333
|
+
this.createServer();
|
|
334
|
+
|
|
335
|
+
if (this.options.setupExitSignals) {
|
|
336
|
+
const signals = ["SIGINT", "SIGTERM"];
|
|
337
|
+
|
|
338
|
+
let needForceShutdown = false;
|
|
339
|
+
|
|
340
|
+
signals.forEach(signal => {
|
|
341
|
+
const listener = () => {
|
|
342
|
+
if (needForceShutdown) {
|
|
343
|
+
process.exit();
|
|
344
|
+
}
|
|
345
|
+
|
|
201
346
|
this.logger.info(
|
|
202
|
-
|
|
347
|
+
"Gracefully shutting down. To force exit, press ^C again. Please wait..."
|
|
203
348
|
);
|
|
204
|
-
resolve({});
|
|
205
|
-
}
|
|
206
|
-
)
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
349
|
|
|
210
|
-
|
|
211
|
-
throw new Error("Method not implemented.");
|
|
212
|
-
}
|
|
213
|
-
stopCallback(callback?: (err?: Error) => void): void {
|
|
214
|
-
throw new Error("Method not implemented.");
|
|
215
|
-
}
|
|
216
|
-
listen(port: Port, hostname: string, fn: (err?: Error) => void): void {
|
|
217
|
-
throw new Error("Method not implemented.");
|
|
218
|
-
}
|
|
219
|
-
close(callback?: (err?: Error) => void): void {
|
|
220
|
-
throw new Error("Method not implemented.");
|
|
221
|
-
}
|
|
350
|
+
needForceShutdown = true;
|
|
222
351
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
resolve(void 0);
|
|
234
|
-
});
|
|
235
|
-
for (const client of this.webSocketServer.clients) client.terminate();
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
}
|
|
352
|
+
this.stopCallback(() => {
|
|
353
|
+
if (typeof this.compiler.close === "function") {
|
|
354
|
+
this.compiler.close(() => {
|
|
355
|
+
process.exit();
|
|
356
|
+
});
|
|
357
|
+
} else {
|
|
358
|
+
process.exit();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
};
|
|
239
362
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
363
|
+
// @ts-expect-error: `listeners` is private function in base class.
|
|
364
|
+
this.listeners.push({ name: signal, listener });
|
|
243
365
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return;
|
|
366
|
+
process.on(signal, listener);
|
|
367
|
+
});
|
|
247
368
|
}
|
|
248
|
-
|
|
369
|
+
|
|
370
|
+
// Proxy WebSocket without the initial http request
|
|
371
|
+
// https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
|
|
372
|
+
// @ts-expect-error: `webSocketProxies` is private function in base class.
|
|
373
|
+
this.webSocketProxies.forEach(webSocketProxy => {
|
|
374
|
+
this.server.on("upgrade", webSocketProxy.upgrade);
|
|
375
|
+
}, this);
|
|
249
376
|
}
|
|
250
377
|
|
|
251
378
|
private setupDevMiddleware() {
|
|
@@ -253,151 +380,63 @@ export class RspackDevServer {
|
|
|
253
380
|
this.middleware = rdm(this.compiler, this.options.devMiddleware);
|
|
254
381
|
}
|
|
255
382
|
|
|
256
|
-
private createWebsocketServer() {
|
|
257
|
-
if (this.options.webSocketServer !== false) {
|
|
258
|
-
this.webSocketServer = createWebsocketServer(this);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
383
|
private setupMiddlewares() {
|
|
263
|
-
const
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
throw error;
|
|
279
|
-
}
|
|
280
|
-
res.write("");
|
|
281
|
-
res.end();
|
|
282
|
-
console.log("lazy compiler success");
|
|
384
|
+
const middlewares: WebpackDevServer.Middleware[] = [];
|
|
385
|
+
const compilers =
|
|
386
|
+
this.compiler instanceof MultiCompiler
|
|
387
|
+
? this.compiler.compilers
|
|
388
|
+
: [this.compiler];
|
|
389
|
+
|
|
390
|
+
if (Array.isArray(this.options.static)) {
|
|
391
|
+
this.options.static.forEach(staticOptions => {
|
|
392
|
+
staticOptions.publicPath.forEach(publicPath => {
|
|
393
|
+
compilers.forEach(compiler => {
|
|
394
|
+
if (compiler.options.builtins.noEmitAssets) {
|
|
395
|
+
middlewares.push({
|
|
396
|
+
name: "rspack-memory-assets",
|
|
397
|
+
path: publicPath,
|
|
398
|
+
middleware: getRspackMemoryAssets(compiler, this.middleware)
|
|
283
399
|
});
|
|
284
400
|
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
401
|
+
});
|
|
402
|
+
});
|
|
287
403
|
});
|
|
288
404
|
}
|
|
289
405
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
const { createProxyMiddleware } = require("http-proxy-middleware");
|
|
307
|
-
function getProxyMiddleware(proxyConfig) {
|
|
308
|
-
if (proxyConfig.target) {
|
|
309
|
-
const context = proxyConfig.context || proxyConfig.path;
|
|
310
|
-
return createProxyMiddleware(context, proxyConfig);
|
|
311
|
-
}
|
|
312
|
-
if (proxyConfig.router) {
|
|
313
|
-
return createProxyMiddleware(proxyConfig);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (!Array.isArray(options.proxy)) {
|
|
317
|
-
if (
|
|
318
|
-
Object.prototype.hasOwnProperty.call(options.proxy, "target") ||
|
|
319
|
-
Object.prototype.hasOwnProperty.call(options.proxy, "router")
|
|
320
|
-
) {
|
|
321
|
-
options.proxy = [options.proxy];
|
|
322
|
-
} else {
|
|
323
|
-
options.proxy = Object.keys(options.proxy).map(context => {
|
|
324
|
-
let proxyOptions;
|
|
325
|
-
// For backwards compatibility reasons.
|
|
326
|
-
const correctedContext = context
|
|
327
|
-
.replace(/^\*$/, "**")
|
|
328
|
-
.replace(/\/\*$/, "");
|
|
329
|
-
|
|
330
|
-
if (
|
|
331
|
-
typeof (/** @type {ProxyConfigMap} */ options.proxy[context]) ===
|
|
332
|
-
"string"
|
|
333
|
-
) {
|
|
334
|
-
proxyOptions = {
|
|
335
|
-
context: correctedContext,
|
|
336
|
-
target:
|
|
337
|
-
/** @type {ProxyConfigMap} */
|
|
338
|
-
options.proxy[context]
|
|
339
|
-
};
|
|
340
|
-
} else {
|
|
341
|
-
proxyOptions = {
|
|
342
|
-
// @ts-ignore
|
|
343
|
-
.../** @type {ProxyConfigMap} */ options.proxy[context]
|
|
344
|
-
};
|
|
345
|
-
proxyOptions.context = correctedContext;
|
|
406
|
+
compilers.forEach(compiler => {
|
|
407
|
+
if (compiler.options.experiments.lazyCompilation) {
|
|
408
|
+
middlewares.push({
|
|
409
|
+
middleware: (req, res, next) => {
|
|
410
|
+
if (req.url.indexOf("/lazy-compilation-web/") > -1) {
|
|
411
|
+
const path = req.url.replace("/lazy-compilation-web/", "");
|
|
412
|
+
if (fs.existsSync(path)) {
|
|
413
|
+
compiler.rebuild(new Set([path]), new Set(), error => {
|
|
414
|
+
if (error) {
|
|
415
|
+
throw error;
|
|
416
|
+
}
|
|
417
|
+
res.write("");
|
|
418
|
+
res.end();
|
|
419
|
+
console.log("lazy compiler success");
|
|
420
|
+
});
|
|
421
|
+
}
|
|
346
422
|
}
|
|
347
|
-
|
|
348
|
-
return proxyOptions;
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
options.proxy.forEach(proxyConfig => {
|
|
353
|
-
const handler = async (req, res, next) => {
|
|
354
|
-
let proxyMiddleware = getProxyMiddleware(proxyConfig);
|
|
355
|
-
const isByPassFuncDefined = typeof proxyConfig.bypass === "function";
|
|
356
|
-
const bypassUrl = isByPassFuncDefined
|
|
357
|
-
? await proxyConfig.bypass(req, res, proxyConfig)
|
|
358
|
-
: null;
|
|
359
|
-
if (typeof bypassUrl === "boolean") {
|
|
360
|
-
req.url = null;
|
|
361
|
-
next();
|
|
362
|
-
} else if (typeof bypassUrl === "string") {
|
|
363
|
-
req.url = bypassUrl;
|
|
364
|
-
} else if (proxyMiddleware) {
|
|
365
|
-
return proxyMiddleware(req, res, next);
|
|
366
|
-
} else {
|
|
367
|
-
next();
|
|
368
423
|
}
|
|
369
|
-
};
|
|
370
|
-
middlewares.push({
|
|
371
|
-
name: "http-proxy-middleware",
|
|
372
|
-
middleware: handler
|
|
373
|
-
});
|
|
374
|
-
middlewares.push({
|
|
375
|
-
name: "http-proxy-middleware-error-handler",
|
|
376
|
-
middleware: (error, req, res, next) => handler(req, res, next)
|
|
377
424
|
});
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
const publicPath =
|
|
381
|
-
this.compiler.options.output.publicPath === "auto"
|
|
382
|
-
? ""
|
|
383
|
-
: this.compiler.options.output.publicPath;
|
|
384
|
-
middlewares.push({
|
|
385
|
-
name: "express-static",
|
|
386
|
-
path: publicPath,
|
|
387
|
-
middleware: express.static(this.options.static.directory)
|
|
425
|
+
}
|
|
388
426
|
});
|
|
389
427
|
|
|
390
|
-
middlewares.forEach(
|
|
391
|
-
if (
|
|
392
|
-
this.app.use(
|
|
428
|
+
middlewares.forEach(middleware => {
|
|
429
|
+
if (typeof middleware === "function") {
|
|
430
|
+
this.app.use(middleware);
|
|
431
|
+
} else if (typeof middleware.path !== "undefined") {
|
|
432
|
+
this.app.use(middleware.path, middleware.middleware);
|
|
393
433
|
} else {
|
|
394
|
-
this.app.use(
|
|
434
|
+
this.app.use(middleware.middleware);
|
|
395
435
|
}
|
|
396
436
|
});
|
|
397
|
-
}
|
|
398
437
|
|
|
399
|
-
|
|
400
|
-
|
|
438
|
+
// @ts-expect-error
|
|
439
|
+
super.setupMiddlewares();
|
|
401
440
|
}
|
|
402
441
|
|
|
403
442
|
private setupHooks() {
|