@rspack/dev-server 0.0.0-0074001a71-20230224065505
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 +234 -0
- package/LICENSE +22 -0
- package/README.md +16 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/reload.d.ts +9 -0
- package/dist/reload.d.ts.map +1 -0
- package/dist/reload.js +23 -0
- package/dist/reload.js.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +401 -0
- package/dist/server.js.map +1 -0
- package/jest.config.js +10 -0
- package/package.json +40 -0
- package/src/config.ts +27 -0
- package/src/index.ts +1 -0
- package/src/reload.ts +31 -0
- package/src/server.ts +474 -0
- package/tests/__snapshots__/normalizeOptions.test.ts.snap +232 -0
- package/tests/e2e/hot-reaload.test.ts +115 -0
- package/tests/e2e-fixtures/react/app.jsx +14 -0
- package/tests/e2e-fixtures/react/index.css +3 -0
- package/tests/e2e-fixtures/react/index.html +12 -0
- package/tests/e2e-fixtures/react/index.jsx +6 -0
- 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 +8 -0
- package/tests/e2e-fixtures/react/webpack.config.js +26 -0
- package/tests/helpers/emitFile.ts +69 -0
- package/tests/helpers/runBrowser.ts +85 -0
- package/tests/helpers/tempDir.ts +58 -0
- package/tests/normalizeOptions.test.ts +107 -0
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +1 -0
package/src/server.ts
ADDED
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import { Compiler, MultiCompiler } from "@rspack/core";
|
|
2
|
+
import type { Socket } from "net";
|
|
3
|
+
import type { FSWatcher, WatchOptions } from "chokidar";
|
|
4
|
+
import rdm, { getRspackMemoryAssets } from "@rspack/dev-middleware";
|
|
5
|
+
import type { Server } from "http";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import WebpackDevServer from "webpack-dev-server";
|
|
8
|
+
import type { ResolvedDevServer, DevServer } from "./config";
|
|
9
|
+
|
|
10
|
+
export class RspackDevServer extends WebpackDevServer {
|
|
11
|
+
/**
|
|
12
|
+
* resolved after `normalizedOptions`
|
|
13
|
+
*/
|
|
14
|
+
options: ResolvedDevServer;
|
|
15
|
+
staticWatchers: FSWatcher[];
|
|
16
|
+
sockets: Socket[];
|
|
17
|
+
server: Server;
|
|
18
|
+
// @ts-expect-error
|
|
19
|
+
public compiler: Compiler | MultiCompiler;
|
|
20
|
+
webSocketServer: WebpackDevServer.WebSocketServerImplementation | undefined;
|
|
21
|
+
|
|
22
|
+
constructor(options: DevServer, compiler: Compiler | MultiCompiler) {
|
|
23
|
+
// @ts-expect-error
|
|
24
|
+
super(options, compiler);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
addAdditionEntires(compiler: Compiler) {
|
|
28
|
+
const additionalEntries: string[] = [];
|
|
29
|
+
const isWebTarget = isWebTarget2(compiler);
|
|
30
|
+
if (this.options.client && isWebTarget) {
|
|
31
|
+
let webSocketURLStr = "";
|
|
32
|
+
|
|
33
|
+
if (this.options.webSocketServer) {
|
|
34
|
+
const webSocketURL = this.options.client
|
|
35
|
+
.webSocketURL as WebpackDevServer.WebSocketURL;
|
|
36
|
+
const webSocketServer = this.options.webSocketServer;
|
|
37
|
+
const searchParams = new URLSearchParams();
|
|
38
|
+
|
|
39
|
+
let protocol: string;
|
|
40
|
+
|
|
41
|
+
// We are proxying dev server and need to specify custom `hostname`
|
|
42
|
+
if (typeof webSocketURL.protocol !== "undefined") {
|
|
43
|
+
protocol = webSocketURL.protocol;
|
|
44
|
+
} else {
|
|
45
|
+
protocol = this.options.server.type === "http" ? "ws:" : "wss:";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
searchParams.set("protocol", protocol);
|
|
49
|
+
|
|
50
|
+
if (typeof webSocketURL.username !== "undefined") {
|
|
51
|
+
searchParams.set("username", webSocketURL.username);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (typeof webSocketURL.password !== "undefined") {
|
|
55
|
+
searchParams.set("password", webSocketURL.password);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let hostname: string;
|
|
59
|
+
|
|
60
|
+
// SockJS is not supported server mode, so `hostname` and `port` can't specified, let's ignore them
|
|
61
|
+
// TODO show warning about this
|
|
62
|
+
const isSockJSType = webSocketServer.type === "sockjs";
|
|
63
|
+
|
|
64
|
+
// We are proxying dev server and need to specify custom `hostname`
|
|
65
|
+
if (typeof webSocketURL.hostname !== "undefined") {
|
|
66
|
+
hostname = webSocketURL.hostname;
|
|
67
|
+
}
|
|
68
|
+
// Web socket server works on custom `hostname`, only for `ws` because `sock-js` is not support custom `hostname`
|
|
69
|
+
else if (
|
|
70
|
+
typeof webSocketServer.options.host !== "undefined" &&
|
|
71
|
+
!isSockJSType
|
|
72
|
+
) {
|
|
73
|
+
hostname = webSocketServer.options.host;
|
|
74
|
+
}
|
|
75
|
+
// The `host` option is specified
|
|
76
|
+
else if (typeof this.options.host !== "undefined") {
|
|
77
|
+
hostname = this.options.host;
|
|
78
|
+
}
|
|
79
|
+
// The `port` option is not specified
|
|
80
|
+
else {
|
|
81
|
+
hostname = "0.0.0.0";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
searchParams.set("hostname", hostname);
|
|
85
|
+
|
|
86
|
+
let port: number | string;
|
|
87
|
+
|
|
88
|
+
// We are proxying dev server and need to specify custom `port`
|
|
89
|
+
if (typeof webSocketURL.port !== "undefined") {
|
|
90
|
+
port = webSocketURL.port;
|
|
91
|
+
}
|
|
92
|
+
// Web socket server works on custom `port`, only for `ws` because `sock-js` is not support custom `port`
|
|
93
|
+
else if (
|
|
94
|
+
typeof webSocketServer.options.port !== "undefined" &&
|
|
95
|
+
!isSockJSType
|
|
96
|
+
) {
|
|
97
|
+
port = webSocketServer.options.port;
|
|
98
|
+
}
|
|
99
|
+
// The `port` option is specified
|
|
100
|
+
else if (typeof this.options.port === "number") {
|
|
101
|
+
port = this.options.port;
|
|
102
|
+
}
|
|
103
|
+
// The `port` option is specified using `string`
|
|
104
|
+
else if (
|
|
105
|
+
typeof this.options.port === "string" &&
|
|
106
|
+
this.options.port !== "auto"
|
|
107
|
+
) {
|
|
108
|
+
port = Number(this.options.port);
|
|
109
|
+
}
|
|
110
|
+
// The `port` option is not specified or set to `auto`
|
|
111
|
+
else {
|
|
112
|
+
port = "0";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
searchParams.set("port", String(port));
|
|
116
|
+
|
|
117
|
+
let pathname = "";
|
|
118
|
+
|
|
119
|
+
// We are proxying dev server and need to specify custom `pathname`
|
|
120
|
+
if (typeof webSocketURL.pathname !== "undefined") {
|
|
121
|
+
pathname = webSocketURL.pathname;
|
|
122
|
+
}
|
|
123
|
+
// Web socket server works on custom `path`
|
|
124
|
+
else if (
|
|
125
|
+
typeof webSocketServer.options.prefix !== "undefined" ||
|
|
126
|
+
typeof webSocketServer.options.path !== "undefined"
|
|
127
|
+
) {
|
|
128
|
+
pathname =
|
|
129
|
+
webSocketServer.options.prefix || webSocketServer.options.path;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
searchParams.set("pathname", pathname);
|
|
133
|
+
|
|
134
|
+
const client = /** @type {ClientConfiguration} */ this.options.client;
|
|
135
|
+
|
|
136
|
+
if (typeof client.logging !== "undefined") {
|
|
137
|
+
searchParams.set("logging", client.logging);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (typeof client.progress !== "undefined") {
|
|
141
|
+
searchParams.set("progress", String(client.progress));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (typeof client.overlay !== "undefined") {
|
|
145
|
+
searchParams.set(
|
|
146
|
+
"overlay",
|
|
147
|
+
typeof client.overlay === "boolean"
|
|
148
|
+
? String(client.overlay)
|
|
149
|
+
: JSON.stringify(client.overlay)
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (typeof client.reconnect !== "undefined") {
|
|
154
|
+
searchParams.set(
|
|
155
|
+
"reconnect",
|
|
156
|
+
typeof client.reconnect === "number"
|
|
157
|
+
? String(client.reconnect)
|
|
158
|
+
: "10"
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (typeof this.options.hot !== "undefined") {
|
|
163
|
+
searchParams.set("hot", String(this.options.hot));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (typeof this.options.liveReload !== "undefined") {
|
|
167
|
+
searchParams.set("live-reload", String(this.options.liveReload));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
webSocketURLStr = searchParams.toString();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// TODO: should use providerPlugin
|
|
174
|
+
additionalEntries.push(this.getClientTransport());
|
|
175
|
+
|
|
176
|
+
additionalEntries.push(
|
|
177
|
+
`${require.resolve("@rspack/dev-client")}?${webSocketURLStr}`
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (this.options.hot) {
|
|
182
|
+
const hotUpdateEntryPath = require.resolve(
|
|
183
|
+
"@rspack/dev-client/devServer"
|
|
184
|
+
);
|
|
185
|
+
additionalEntries.push(hotUpdateEntryPath);
|
|
186
|
+
|
|
187
|
+
if (compiler.options.builtins.react?.refresh) {
|
|
188
|
+
const reactRefreshEntryPath = require.resolve(
|
|
189
|
+
"@rspack/dev-client/react-refresh"
|
|
190
|
+
);
|
|
191
|
+
additionalEntries.push(reactRefreshEntryPath);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
for (const key in compiler.options.entry) {
|
|
196
|
+
compiler.options.entry[key].import.unshift(...additionalEntries);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
watchFiles(watchPath: string | string[], watchOptions?: WatchOptions): void {
|
|
201
|
+
const chokidar = require("chokidar");
|
|
202
|
+
const watcher = chokidar.watch(watchPath, watchOptions);
|
|
203
|
+
|
|
204
|
+
// disabling refreshing on changing the content
|
|
205
|
+
if (this.options.liveReload) {
|
|
206
|
+
// TODO: remove this after we had memory filesystem
|
|
207
|
+
if (this.options.hot) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
watcher.on("change", item => {
|
|
212
|
+
if (this.webSocketServer) {
|
|
213
|
+
this.sendMessage(
|
|
214
|
+
this.webSocketServer.clients,
|
|
215
|
+
"static-changed",
|
|
216
|
+
item
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
this.staticWatchers.push(watcher);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
getClientTransport(): string {
|
|
226
|
+
// WARNING: we can't use `super.getClientTransport`,
|
|
227
|
+
// because we doesn't had same directory structure.
|
|
228
|
+
// and TODO: we need impelement `webpack.providerPlugin`
|
|
229
|
+
let clientImplementation: string | undefined;
|
|
230
|
+
let clientImplementationFound = true;
|
|
231
|
+
const isKnownWebSocketServerImplementation =
|
|
232
|
+
this.options.webSocketServer &&
|
|
233
|
+
typeof this.options.webSocketServer.type === "string" &&
|
|
234
|
+
(this.options.webSocketServer.type === "ws" ||
|
|
235
|
+
this.options.webSocketServer.type === "sockjs");
|
|
236
|
+
|
|
237
|
+
let clientTransport: string | undefined;
|
|
238
|
+
|
|
239
|
+
if (this.options.client) {
|
|
240
|
+
if (
|
|
241
|
+
// @ts-ignore
|
|
242
|
+
typeof this.options.client.webSocketTransport !== "undefined"
|
|
243
|
+
) {
|
|
244
|
+
// @ts-ignore
|
|
245
|
+
clientTransport = this.options.client.webSocketTransport;
|
|
246
|
+
} else if (isKnownWebSocketServerImplementation) {
|
|
247
|
+
// @ts-ignore
|
|
248
|
+
clientTransport = this.options.webSocketServer.type;
|
|
249
|
+
} else {
|
|
250
|
+
clientTransport = "ws";
|
|
251
|
+
}
|
|
252
|
+
} else {
|
|
253
|
+
clientTransport = "ws";
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
switch (typeof clientTransport) {
|
|
257
|
+
case "string":
|
|
258
|
+
// could be 'sockjs', 'ws', or a path that should be required
|
|
259
|
+
if (clientTransport === "sockjs") {
|
|
260
|
+
clientImplementation = require.resolve(
|
|
261
|
+
"@rspack/dev-client/clients/SockJSClient"
|
|
262
|
+
);
|
|
263
|
+
} else if (clientTransport === "ws") {
|
|
264
|
+
clientImplementation = require.resolve(
|
|
265
|
+
"@rspack/dev-client/clients/WebSocketClient"
|
|
266
|
+
);
|
|
267
|
+
} else {
|
|
268
|
+
try {
|
|
269
|
+
clientImplementation = require.resolve(clientTransport);
|
|
270
|
+
throw Error("Do not support custom ws client now");
|
|
271
|
+
} catch (e) {
|
|
272
|
+
clientImplementationFound = false;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
default:
|
|
277
|
+
clientImplementationFound = false;
|
|
278
|
+
}
|
|
279
|
+
if (!clientImplementationFound) {
|
|
280
|
+
throw new Error(
|
|
281
|
+
`${
|
|
282
|
+
!isKnownWebSocketServerImplementation
|
|
283
|
+
? "When you use custom web socket implementation you must explicitly specify client.webSocketTransport. "
|
|
284
|
+
: ""
|
|
285
|
+
}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 `
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return clientImplementation;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async initialize() {
|
|
293
|
+
const compilers =
|
|
294
|
+
this.compiler instanceof MultiCompiler
|
|
295
|
+
? this.compiler.compilers
|
|
296
|
+
: [this.compiler];
|
|
297
|
+
|
|
298
|
+
compilers.forEach(compiler => {
|
|
299
|
+
compiler.options.builtins.react ??= {};
|
|
300
|
+
if (this.options.hot) {
|
|
301
|
+
compiler.options.builtins.react.refresh ??= true;
|
|
302
|
+
compiler.options.builtins.react.development ??= true;
|
|
303
|
+
} else if (compiler.options.builtins.react.refresh) {
|
|
304
|
+
this.logger.warn(
|
|
305
|
+
"builtins.react.refresh needs builtins.react.development and devServer.hot enabled"
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
if (this.options.webSocketServer) {
|
|
311
|
+
compilers.forEach(compiler => {
|
|
312
|
+
this.addAdditionEntires(compiler);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
this.setupHooks();
|
|
317
|
+
// @ts-expect-error: `setupApp` is private function in base class.
|
|
318
|
+
this.setupApp();
|
|
319
|
+
// @ts-expect-error: `setupHostHeaderCheck` is private function in base class.
|
|
320
|
+
this.setupHostHeaderCheck();
|
|
321
|
+
this.setupDevMiddleware();
|
|
322
|
+
// @ts-expect-error: `setupBuiltInRoutes` is private function in base class.
|
|
323
|
+
this.setupBuiltInRoutes();
|
|
324
|
+
// @ts-expect-error: `setupWatchFiles` is private function in base class.
|
|
325
|
+
this.setupWatchFiles();
|
|
326
|
+
// @ts-expect-error: `setupWatchStaticFiles` is private function in base class.
|
|
327
|
+
this.setupWatchStaticFiles();
|
|
328
|
+
this.setupMiddlewares();
|
|
329
|
+
// @ts-expect-error: `createServer` is private function in base class.
|
|
330
|
+
this.createServer();
|
|
331
|
+
|
|
332
|
+
if (this.options.setupExitSignals) {
|
|
333
|
+
const signals = ["SIGINT", "SIGTERM"];
|
|
334
|
+
|
|
335
|
+
let needForceShutdown = false;
|
|
336
|
+
|
|
337
|
+
signals.forEach(signal => {
|
|
338
|
+
const listener = () => {
|
|
339
|
+
if (needForceShutdown) {
|
|
340
|
+
process.exit();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
this.logger.info(
|
|
344
|
+
"Gracefully shutting down. To force exit, press ^C again. Please wait..."
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
needForceShutdown = true;
|
|
348
|
+
|
|
349
|
+
this.stopCallback(() => {
|
|
350
|
+
if (typeof this.compiler.close === "function") {
|
|
351
|
+
this.compiler.close(() => {
|
|
352
|
+
process.exit();
|
|
353
|
+
});
|
|
354
|
+
} else {
|
|
355
|
+
process.exit();
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// @ts-expect-error: `listeners` is private function in base class.
|
|
361
|
+
this.listeners.push({ name: signal, listener });
|
|
362
|
+
|
|
363
|
+
process.on(signal, listener);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Proxy WebSocket without the initial http request
|
|
368
|
+
// https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
|
|
369
|
+
// @ts-expect-error: `webSocketProxies` is private function in base class.
|
|
370
|
+
this.webSocketProxies.forEach(webSocketProxy => {
|
|
371
|
+
this.server.on("upgrade", webSocketProxy.upgrade);
|
|
372
|
+
}, this);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private setupDevMiddleware() {
|
|
376
|
+
// @ts-ignored
|
|
377
|
+
this.middleware = rdm(this.compiler, this.options.devMiddleware);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private setupMiddlewares() {
|
|
381
|
+
const middlewares: WebpackDevServer.Middleware[] = [];
|
|
382
|
+
const compilers =
|
|
383
|
+
this.compiler instanceof MultiCompiler
|
|
384
|
+
? this.compiler.compilers
|
|
385
|
+
: [this.compiler];
|
|
386
|
+
|
|
387
|
+
if (Array.isArray(this.options.static)) {
|
|
388
|
+
this.options.static.forEach(staticOptions => {
|
|
389
|
+
staticOptions.publicPath.forEach(publicPath => {
|
|
390
|
+
compilers.forEach(compiler => {
|
|
391
|
+
if (compiler.options.builtins.noEmitAssets) {
|
|
392
|
+
middlewares.push({
|
|
393
|
+
name: "rspack-memory-assets",
|
|
394
|
+
path: publicPath,
|
|
395
|
+
middleware: getRspackMemoryAssets(compiler, this.middleware)
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
compilers.forEach(compiler => {
|
|
404
|
+
if (compiler.options.experiments.lazyCompilation) {
|
|
405
|
+
middlewares.push({
|
|
406
|
+
middleware: (req, res, next) => {
|
|
407
|
+
if (req.url.indexOf("/lazy-compilation-web/") > -1) {
|
|
408
|
+
const path = req.url.replace("/lazy-compilation-web/", "");
|
|
409
|
+
if (fs.existsSync(path)) {
|
|
410
|
+
compiler.rebuild(new Set([path]), new Set(), error => {
|
|
411
|
+
if (error) {
|
|
412
|
+
throw error;
|
|
413
|
+
}
|
|
414
|
+
res.write("");
|
|
415
|
+
res.end();
|
|
416
|
+
console.log("lazy compiler success");
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
middlewares.forEach(middleware => {
|
|
426
|
+
if (typeof middleware === "function") {
|
|
427
|
+
this.app.use(middleware);
|
|
428
|
+
} else if (typeof middleware.path !== "undefined") {
|
|
429
|
+
this.app.use(middleware.path, middleware.middleware);
|
|
430
|
+
} else {
|
|
431
|
+
this.app.use(middleware.middleware);
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// @ts-expect-error
|
|
436
|
+
super.setupMiddlewares();
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
private setupHooks() {
|
|
440
|
+
this.compiler.hooks.done.tap("dev-server", stats => {
|
|
441
|
+
// send Message
|
|
442
|
+
if (this.webSocketServer) {
|
|
443
|
+
this.sendMessage(this.webSocketServer.clients, "ok"); // TODO: send hash
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// TODO: use WebpackDevServer.isWebTarget instead of this once we have a new webpack-dev-server version
|
|
450
|
+
function isWebTarget2(compiler: Compiler): boolean {
|
|
451
|
+
if (
|
|
452
|
+
compiler.options.resolve.conditionNames &&
|
|
453
|
+
compiler.options.resolve.conditionNames.includes("browser")
|
|
454
|
+
) {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
const target = compiler.options.target;
|
|
458
|
+
const webTargets = [
|
|
459
|
+
"web",
|
|
460
|
+
"webworker",
|
|
461
|
+
"electron-preload",
|
|
462
|
+
"electron-renderer",
|
|
463
|
+
"node-webkit",
|
|
464
|
+
undefined,
|
|
465
|
+
null
|
|
466
|
+
];
|
|
467
|
+
if (Array.isArray(target)) {
|
|
468
|
+
return target.some(r => webTargets.includes(r));
|
|
469
|
+
}
|
|
470
|
+
if (typeof target === "string") {
|
|
471
|
+
return webTargets.includes(target);
|
|
472
|
+
}
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`normalize options snapshot additional entires should added 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"main": [
|
|
6
|
+
"<prefix>/dist/clients/WebSocketClient.js",
|
|
7
|
+
"<prefix>/rspack-dev-client/dist/index.js?protocol=ws%3A&hostname=0.0.0.0&port=8080&pathname=%2Fws&logging=info&overlay=true&reconnect=10&hot=true&live-reload=true",
|
|
8
|
+
"<prefix>/rspack-dev-client/dist/devServer.js",
|
|
9
|
+
"<prefix>/rspack-dev-client/dist/reactRefresh.js",
|
|
10
|
+
"<prefix>/something",
|
|
11
|
+
],
|
|
12
|
+
}
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
exports[`normalize options snapshot no options 1`] = `
|
|
16
|
+
{
|
|
17
|
+
"allowedHosts": "auto",
|
|
18
|
+
"bonjour": false,
|
|
19
|
+
"client": {
|
|
20
|
+
"logging": "info",
|
|
21
|
+
"overlay": true,
|
|
22
|
+
"reconnect": 10,
|
|
23
|
+
"webSocketURL": {},
|
|
24
|
+
},
|
|
25
|
+
"compress": true,
|
|
26
|
+
"devMiddleware": {},
|
|
27
|
+
"historyApiFallback": false,
|
|
28
|
+
"host": undefined,
|
|
29
|
+
"hot": true,
|
|
30
|
+
"liveReload": true,
|
|
31
|
+
"magicHtml": true,
|
|
32
|
+
"open": [],
|
|
33
|
+
"port": 8080,
|
|
34
|
+
"server": {
|
|
35
|
+
"options": {},
|
|
36
|
+
"type": "http",
|
|
37
|
+
},
|
|
38
|
+
"setupExitSignals": true,
|
|
39
|
+
"static": [
|
|
40
|
+
{
|
|
41
|
+
"directory": "<PROJECT_ROOT>/public",
|
|
42
|
+
"publicPath": [
|
|
43
|
+
"/",
|
|
44
|
+
],
|
|
45
|
+
"serveIndex": {
|
|
46
|
+
"icons": true,
|
|
47
|
+
},
|
|
48
|
+
"staticOptions": {},
|
|
49
|
+
"watch": {
|
|
50
|
+
"alwaysStat": true,
|
|
51
|
+
"atomic": false,
|
|
52
|
+
"followSymlinks": false,
|
|
53
|
+
"ignoreInitial": true,
|
|
54
|
+
"ignorePermissionErrors": true,
|
|
55
|
+
"ignored": undefined,
|
|
56
|
+
"interval": undefined,
|
|
57
|
+
"persistent": true,
|
|
58
|
+
"usePolling": false,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
"watchFiles": [],
|
|
63
|
+
"webSocketServer": {
|
|
64
|
+
"options": {
|
|
65
|
+
"path": "/ws",
|
|
66
|
+
},
|
|
67
|
+
"type": "ws",
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
exports[`normalize options snapshot port string 1`] = `
|
|
73
|
+
{
|
|
74
|
+
"allowedHosts": "auto",
|
|
75
|
+
"bonjour": false,
|
|
76
|
+
"client": {
|
|
77
|
+
"logging": "info",
|
|
78
|
+
"overlay": true,
|
|
79
|
+
"reconnect": 10,
|
|
80
|
+
"webSocketURL": {},
|
|
81
|
+
},
|
|
82
|
+
"compress": true,
|
|
83
|
+
"devMiddleware": {},
|
|
84
|
+
"historyApiFallback": false,
|
|
85
|
+
"host": undefined,
|
|
86
|
+
"hot": true,
|
|
87
|
+
"liveReload": true,
|
|
88
|
+
"magicHtml": true,
|
|
89
|
+
"open": [],
|
|
90
|
+
"port": 9000,
|
|
91
|
+
"server": {
|
|
92
|
+
"options": {},
|
|
93
|
+
"type": "http",
|
|
94
|
+
},
|
|
95
|
+
"setupExitSignals": true,
|
|
96
|
+
"static": [
|
|
97
|
+
{
|
|
98
|
+
"directory": "<PROJECT_ROOT>/public",
|
|
99
|
+
"publicPath": [
|
|
100
|
+
"/",
|
|
101
|
+
],
|
|
102
|
+
"serveIndex": {
|
|
103
|
+
"icons": true,
|
|
104
|
+
},
|
|
105
|
+
"staticOptions": {},
|
|
106
|
+
"watch": {
|
|
107
|
+
"alwaysStat": true,
|
|
108
|
+
"atomic": false,
|
|
109
|
+
"followSymlinks": false,
|
|
110
|
+
"ignoreInitial": true,
|
|
111
|
+
"ignorePermissionErrors": true,
|
|
112
|
+
"ignored": undefined,
|
|
113
|
+
"interval": undefined,
|
|
114
|
+
"persistent": true,
|
|
115
|
+
"usePolling": false,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
"watchFiles": [],
|
|
120
|
+
"webSocketServer": {
|
|
121
|
+
"options": {
|
|
122
|
+
"path": "/ws",
|
|
123
|
+
},
|
|
124
|
+
"type": "ws",
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
exports[`normalize options snapshot react.development and react.refresh should be true in default when hot enabled 1`] = `
|
|
130
|
+
{
|
|
131
|
+
"builtins": {
|
|
132
|
+
"copy": undefined,
|
|
133
|
+
"css": {
|
|
134
|
+
"modules": {
|
|
135
|
+
"exportsOnly": false,
|
|
136
|
+
"localIdentName": "[hash]",
|
|
137
|
+
"localsConvention": "asIs",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
"decorator": {
|
|
141
|
+
"emitMetadata": true,
|
|
142
|
+
"legacy": true,
|
|
143
|
+
},
|
|
144
|
+
"define": {},
|
|
145
|
+
"devFriendlySplitChunks": false,
|
|
146
|
+
"emotion": undefined,
|
|
147
|
+
"html": [],
|
|
148
|
+
"minifyOptions": {
|
|
149
|
+
"dropConsole": false,
|
|
150
|
+
"passes": 1,
|
|
151
|
+
"pureFuncs": [],
|
|
152
|
+
},
|
|
153
|
+
"noEmitAssets": false,
|
|
154
|
+
"postcss": {
|
|
155
|
+
"pxtorem": undefined,
|
|
156
|
+
},
|
|
157
|
+
"presetEnv": undefined,
|
|
158
|
+
"progress": undefined,
|
|
159
|
+
"react": {
|
|
160
|
+
"development": true,
|
|
161
|
+
"refresh": true,
|
|
162
|
+
},
|
|
163
|
+
"treeShaking": true,
|
|
164
|
+
},
|
|
165
|
+
"devServer": {
|
|
166
|
+
"allowedHosts": "auto",
|
|
167
|
+
"bonjour": false,
|
|
168
|
+
"client": {
|
|
169
|
+
"logging": "info",
|
|
170
|
+
"overlay": true,
|
|
171
|
+
"reconnect": 10,
|
|
172
|
+
"webSocketURL": {},
|
|
173
|
+
},
|
|
174
|
+
"compress": true,
|
|
175
|
+
"devMiddleware": {},
|
|
176
|
+
"historyApiFallback": false,
|
|
177
|
+
"host": undefined,
|
|
178
|
+
"hot": true,
|
|
179
|
+
"liveReload": true,
|
|
180
|
+
"magicHtml": true,
|
|
181
|
+
"open": [],
|
|
182
|
+
"port": 8080,
|
|
183
|
+
"server": {
|
|
184
|
+
"options": {},
|
|
185
|
+
"type": "http",
|
|
186
|
+
},
|
|
187
|
+
"setupExitSignals": true,
|
|
188
|
+
"static": [
|
|
189
|
+
{
|
|
190
|
+
"directory": "<PROJECT_ROOT>/public",
|
|
191
|
+
"publicPath": [
|
|
192
|
+
"/",
|
|
193
|
+
],
|
|
194
|
+
"serveIndex": {
|
|
195
|
+
"icons": true,
|
|
196
|
+
},
|
|
197
|
+
"staticOptions": {},
|
|
198
|
+
"watch": {
|
|
199
|
+
"alwaysStat": true,
|
|
200
|
+
"atomic": false,
|
|
201
|
+
"followSymlinks": false,
|
|
202
|
+
"ignoreInitial": true,
|
|
203
|
+
"ignorePermissionErrors": true,
|
|
204
|
+
"ignored": undefined,
|
|
205
|
+
"interval": undefined,
|
|
206
|
+
"persistent": true,
|
|
207
|
+
"usePolling": false,
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
"watchFiles": [],
|
|
212
|
+
"webSocketServer": {
|
|
213
|
+
"options": {
|
|
214
|
+
"path": "/ws",
|
|
215
|
+
},
|
|
216
|
+
"type": "ws",
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
`;
|
|
221
|
+
|
|
222
|
+
exports[`normalize options snapshot react-refresh client added when react/refresh enabled 1`] = `
|
|
223
|
+
{
|
|
224
|
+
"main": [
|
|
225
|
+
"<prefix>/dist/clients/WebSocketClient.js",
|
|
226
|
+
"<prefix>/rspack-dev-client/dist/index.js?protocol=ws%3A&hostname=0.0.0.0&port=8080&pathname=%2Fws&logging=info&overlay=true&reconnect=10&hot=true&live-reload=true",
|
|
227
|
+
"<prefix>/rspack-dev-client/dist/devServer.js",
|
|
228
|
+
"<prefix>/rspack-dev-client/dist/reactRefresh.js",
|
|
229
|
+
"<prefix>/something",
|
|
230
|
+
],
|
|
231
|
+
}
|
|
232
|
+
`;
|