@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.
Files changed (100) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +1 -1
  3. package/dist/config.d.ts +19 -14
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +0 -52
  6. package/dist/config.js.map +1 -1
  7. package/dist/server.d.ts +14 -41
  8. package/dist/server.d.ts.map +1 -1
  9. package/dist/server.js +308 -257
  10. package/dist/server.js.map +1 -1
  11. package/jest.config.js +3 -1
  12. package/package.json +10 -9
  13. package/src/config.ts +21 -67
  14. package/src/server.ts +350 -311
  15. package/tests/__snapshots__/normalizeOptions.test.ts.snap +223 -24
  16. package/tests/e2e/hot-reaload.test.ts +35 -39
  17. package/tests/e2e-fixtures/react/node_modules/react/LICENSE +21 -0
  18. package/tests/e2e-fixtures/react/node_modules/react/README.md +37 -0
  19. package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-dev-runtime.development.js +1296 -0
  20. package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-dev-runtime.production.min.js +10 -0
  21. package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-dev-runtime.profiling.min.js +10 -0
  22. package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-runtime.development.js +1314 -0
  23. package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-runtime.production.min.js +11 -0
  24. package/tests/e2e-fixtures/react/node_modules/react/cjs/react-jsx-runtime.profiling.min.js +11 -0
  25. package/tests/e2e-fixtures/react/node_modules/react/cjs/react.development.js +2739 -0
  26. package/tests/e2e-fixtures/react/node_modules/react/cjs/react.production.min.js +26 -0
  27. package/tests/e2e-fixtures/react/node_modules/react/cjs/react.shared-subset.development.js +20 -0
  28. package/tests/e2e-fixtures/react/node_modules/react/cjs/react.shared-subset.production.min.js +10 -0
  29. package/tests/e2e-fixtures/react/node_modules/react/index.js +7 -0
  30. package/tests/e2e-fixtures/react/node_modules/react/jsx-dev-runtime.js +7 -0
  31. package/tests/e2e-fixtures/react/node_modules/react/jsx-runtime.js +7 -0
  32. package/tests/e2e-fixtures/react/node_modules/react/package.json +47 -0
  33. package/tests/e2e-fixtures/react/node_modules/react/react.shared-subset.js +7 -0
  34. package/tests/e2e-fixtures/react/node_modules/react/umd/react.development.js +3342 -0
  35. package/tests/e2e-fixtures/react/node_modules/react/umd/react.production.min.js +31 -0
  36. package/tests/e2e-fixtures/react/node_modules/react/umd/react.profiling.min.js +31 -0
  37. package/tests/e2e-fixtures/react/node_modules/react-dom/LICENSE +21 -0
  38. package/tests/e2e-fixtures/react/node_modules/react-dom/README.md +60 -0
  39. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.browser.development.js +7018 -0
  40. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.min.js +93 -0
  41. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js +7078 -0
  42. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js +101 -0
  43. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.browser.development.js +7003 -0
  44. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js +96 -0
  45. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.node.development.js +7059 -0
  46. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-server.node.production.min.js +102 -0
  47. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-test-utils.development.js +1741 -0
  48. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom-test-utils.production.min.js +40 -0
  49. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom.development.js +29868 -0
  50. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom.production.min.js +323 -0
  51. package/tests/e2e-fixtures/react/node_modules/react-dom/cjs/react-dom.profiling.min.js +367 -0
  52. package/tests/e2e-fixtures/react/node_modules/react-dom/client.js +25 -0
  53. package/tests/e2e-fixtures/react/node_modules/react-dom/index.js +38 -0
  54. package/tests/e2e-fixtures/react/node_modules/react-dom/package.json +62 -0
  55. package/tests/e2e-fixtures/react/node_modules/react-dom/profiling.js +38 -0
  56. package/tests/e2e-fixtures/react/node_modules/react-dom/server.browser.js +17 -0
  57. package/tests/e2e-fixtures/react/node_modules/react-dom/server.js +3 -0
  58. package/tests/e2e-fixtures/react/node_modules/react-dom/server.node.js +17 -0
  59. package/tests/e2e-fixtures/react/node_modules/react-dom/test-utils.js +7 -0
  60. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server-legacy.browser.development.js +7015 -0
  61. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server-legacy.browser.production.min.js +75 -0
  62. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server.browser.development.js +7000 -0
  63. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-server.browser.production.min.js +76 -0
  64. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-test-utils.development.js +1737 -0
  65. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom-test-utils.production.min.js +33 -0
  66. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom.development.js +29869 -0
  67. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom.production.min.js +267 -0
  68. package/tests/e2e-fixtures/react/node_modules/react-dom/umd/react-dom.profiling.min.js +285 -0
  69. package/tests/e2e-fixtures/react/node_modules/scheduler/LICENSE +21 -0
  70. package/tests/e2e-fixtures/react/node_modules/scheduler/README.md +9 -0
  71. package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_mock.development.js +700 -0
  72. package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_mock.production.min.js +20 -0
  73. package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_post_task.development.js +207 -0
  74. package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler-unstable_post_task.production.min.js +14 -0
  75. package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler.development.js +634 -0
  76. package/tests/e2e-fixtures/react/node_modules/scheduler/cjs/scheduler.production.min.js +19 -0
  77. package/tests/e2e-fixtures/react/node_modules/scheduler/index.js +7 -0
  78. package/tests/e2e-fixtures/react/node_modules/scheduler/package.json +36 -0
  79. package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler-unstable_mock.development.js +699 -0
  80. package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler-unstable_mock.production.min.js +19 -0
  81. package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler.development.js +152 -0
  82. package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler.production.min.js +146 -0
  83. package/tests/e2e-fixtures/react/node_modules/scheduler/umd/scheduler.profiling.min.js +146 -0
  84. package/tests/e2e-fixtures/react/node_modules/scheduler/unstable_mock.js +7 -0
  85. package/tests/e2e-fixtures/react/node_modules/scheduler/unstable_post_task.js +7 -0
  86. package/tests/e2e-fixtures/react/package.json +2 -0
  87. package/tests/e2e-fixtures/react/webpack.config.js +6 -2
  88. package/tests/helpers/emitFile.ts +58 -4
  89. package/tests/normalizeOptions.test.ts +58 -16
  90. package/tsconfig.tsbuildinfo +1 -1
  91. package/dist/logger.d.ts +0 -7
  92. package/dist/logger.d.ts.map +0 -1
  93. package/dist/logger.js +0 -28
  94. package/dist/logger.js.map +0 -1
  95. package/dist/ws.d.ts +0 -13
  96. package/dist/ws.d.ts.map +0 -1
  97. package/dist/ws.js +0 -12
  98. package/dist/ws.js.map +0 -1
  99. package/src/logger.ts +0 -30
  100. package/src/ws.ts +0 -18
package/dist/server.js CHANGED
@@ -1,98 +1,171 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
29
  exports.RspackDevServer = void 0;
30
+ const core_1 = require("@rspack/core");
31
+ const dev_middleware_1 = __importStar(require("@rspack/dev-middleware"));
7
32
  const fs_1 = __importDefault(require("fs"));
8
- const chokidar_1 = __importDefault(require("chokidar"));
9
- const http_1 = __importDefault(require("http"));
10
- const logger_1 = require("./logger");
11
33
  const webpack_dev_server_1 = __importDefault(require("webpack-dev-server"));
12
- const express_1 = __importDefault(require("express"));
13
- const dev_middleware_1 = __importDefault(require("@rspack/dev-middleware"));
14
- const ws_1 = require("./ws");
15
- const config_1 = require("./config");
16
- // copy from webpack-dev-server
17
- class RspackDevServer {
18
- constructor(compiler) {
19
- this.compiler = compiler;
20
- this.logger = (0, logger_1.createLogger)("rspack-dev-server");
21
- this.staticWatchers = [];
22
- this.listeners = [];
23
- this.sockets = [];
24
- this.currentHash = "";
25
- this.options = this.normalizeOptions(compiler.options.devServer);
26
- this.rewriteCompilerOptions();
27
- this.addAdditionEntires();
28
- }
29
- normalizeOptions(dev = {}) {
30
- return (0, config_1.resolveDevOptions)(dev, this.compiler.options);
31
- }
32
- rewriteCompilerOptions() {
33
- var _a, _b;
34
- this.compiler.options.devServer = this.options;
35
- if (!this.compiler.options.builtins.react) {
36
- this.compiler.options.builtins.react = {};
37
- }
38
- this.compiler.options.builtins.react.development =
39
- (_a = this.compiler.options.builtins.react.development) !== null && _a !== void 0 ? _a : true;
40
- if (this.options.hot) {
41
- this.compiler.options.builtins.react.refresh =
42
- (_b = this.compiler.options.builtins.react.refresh) !== null && _b !== void 0 ? _b : true;
43
- }
34
+ class RspackDevServer extends webpack_dev_server_1.default {
35
+ constructor(options, compiler) {
36
+ // @ts-expect-error
37
+ super(options, compiler);
44
38
  }
45
- addAdditionEntires() {
39
+ addAdditionEntires(compiler) {
46
40
  var _a;
47
- const entries = [];
41
+ const additionalEntries = [];
42
+ // TODO: align with webpack-dev-server after options.target is aligned
43
+ const isWebTarget = compiler.options.target.includes("web") ||
44
+ compiler.options.target.includes("webworker");
45
+ if (this.options.client && isWebTarget) {
46
+ let webSocketURLStr = "";
47
+ if (this.options.webSocketServer) {
48
+ const webSocketURL = this.options.client
49
+ .webSocketURL;
50
+ const webSocketServer = this.options.webSocketServer;
51
+ const searchParams = new URLSearchParams();
52
+ let protocol;
53
+ // We are proxying dev server and need to specify custom `hostname`
54
+ if (typeof webSocketURL.protocol !== "undefined") {
55
+ protocol = webSocketURL.protocol;
56
+ }
57
+ else {
58
+ protocol = this.options.server.type === "http" ? "ws:" : "wss:";
59
+ }
60
+ searchParams.set("protocol", protocol);
61
+ if (typeof webSocketURL.username !== "undefined") {
62
+ searchParams.set("username", webSocketURL.username);
63
+ }
64
+ if (typeof webSocketURL.password !== "undefined") {
65
+ searchParams.set("password", webSocketURL.password);
66
+ }
67
+ let hostname;
68
+ // SockJS is not supported server mode, so `hostname` and `port` can't specified, let's ignore them
69
+ // TODO show warning about this
70
+ const isSockJSType = webSocketServer.type === "sockjs";
71
+ // We are proxying dev server and need to specify custom `hostname`
72
+ if (typeof webSocketURL.hostname !== "undefined") {
73
+ hostname = webSocketURL.hostname;
74
+ }
75
+ // Web socket server works on custom `hostname`, only for `ws` because `sock-js` is not support custom `hostname`
76
+ else if (typeof webSocketServer.options.host !== "undefined" &&
77
+ !isSockJSType) {
78
+ hostname = webSocketServer.options.host;
79
+ }
80
+ // The `host` option is specified
81
+ else if (typeof this.options.host !== "undefined") {
82
+ hostname = this.options.host;
83
+ }
84
+ // The `port` option is not specified
85
+ else {
86
+ hostname = "0.0.0.0";
87
+ }
88
+ searchParams.set("hostname", hostname);
89
+ let port;
90
+ // We are proxying dev server and need to specify custom `port`
91
+ if (typeof webSocketURL.port !== "undefined") {
92
+ port = webSocketURL.port;
93
+ }
94
+ // Web socket server works on custom `port`, only for `ws` because `sock-js` is not support custom `port`
95
+ else if (typeof webSocketServer.options.port !== "undefined" &&
96
+ !isSockJSType) {
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 (typeof this.options.port === "string" &&
105
+ this.options.port !== "auto") {
106
+ port = Number(this.options.port);
107
+ }
108
+ // The `port` option is not specified or set to `auto`
109
+ else {
110
+ port = "0";
111
+ }
112
+ searchParams.set("port", String(port));
113
+ let pathname = "";
114
+ // We are proxying dev server and need to specify custom `pathname`
115
+ if (typeof webSocketURL.pathname !== "undefined") {
116
+ pathname = webSocketURL.pathname;
117
+ }
118
+ // Web socket server works on custom `path`
119
+ else if (typeof webSocketServer.options.prefix !== "undefined" ||
120
+ typeof webSocketServer.options.path !== "undefined") {
121
+ pathname =
122
+ webSocketServer.options.prefix || webSocketServer.options.path;
123
+ }
124
+ searchParams.set("pathname", pathname);
125
+ const client = /** @type {ClientConfiguration} */ this.options.client;
126
+ if (typeof client.logging !== "undefined") {
127
+ searchParams.set("logging", client.logging);
128
+ }
129
+ if (typeof client.progress !== "undefined") {
130
+ searchParams.set("progress", String(client.progress));
131
+ }
132
+ if (typeof client.overlay !== "undefined") {
133
+ searchParams.set("overlay", typeof client.overlay === "boolean"
134
+ ? String(client.overlay)
135
+ : JSON.stringify(client.overlay));
136
+ }
137
+ if (typeof client.reconnect !== "undefined") {
138
+ searchParams.set("reconnect", typeof client.reconnect === "number"
139
+ ? String(client.reconnect)
140
+ : "10");
141
+ }
142
+ if (typeof this.options.hot !== "undefined") {
143
+ searchParams.set("hot", String(this.options.hot));
144
+ }
145
+ if (typeof this.options.liveReload !== "undefined") {
146
+ searchParams.set("live-reload", String(this.options.liveReload));
147
+ }
148
+ webSocketURLStr = searchParams.toString();
149
+ }
150
+ // TODO: should use providerPlugin
151
+ additionalEntries.push(this.getClientTransport());
152
+ additionalEntries.push(`${require.resolve("@rspack/dev-client")}?${webSocketURLStr}`);
153
+ }
48
154
  if (this.options.hot) {
49
155
  const hotUpdateEntryPath = require.resolve("@rspack/dev-client/devServer");
50
- entries.push(hotUpdateEntryPath);
51
- if ((_a = this.compiler.options.builtins.react) === null || _a === void 0 ? void 0 : _a.refresh) {
156
+ additionalEntries.push(hotUpdateEntryPath);
157
+ if ((_a = compiler.options.builtins.react) === null || _a === void 0 ? void 0 : _a.refresh) {
52
158
  const reactRefreshEntryPath = require.resolve("@rspack/dev-client/react-refresh");
53
- entries.push(reactRefreshEntryPath);
159
+ additionalEntries.push(reactRefreshEntryPath);
54
160
  }
55
161
  }
56
- const devClientEntryPath = require.resolve("@rspack/dev-client");
57
- entries.push(devClientEntryPath);
58
- for (const key in this.compiler.options.entry) {
59
- this.compiler.options.entry[key].import.unshift(...entries);
60
- }
61
- }
62
- static isAbsoluteURL(URL) {
63
- return webpack_dev_server_1.default.isAbsoluteURL(URL);
64
- }
65
- static findIp(gateway) {
66
- return webpack_dev_server_1.default.findIp(gateway);
67
- }
68
- static async internalIP(family) {
69
- return webpack_dev_server_1.default.internalIP(family);
70
- }
71
- static async internalIPSync(family) {
72
- return webpack_dev_server_1.default.internalIPSync(family);
73
- }
74
- static async getHostname(hostname) {
75
- return webpack_dev_server_1.default.getHostname(hostname);
76
- }
77
- static async getFreePort(port, host) {
78
- return webpack_dev_server_1.default.getFreePort(port, host);
79
- }
80
- static findCacheDir() {
81
- // TODO: we need remove the `webpack-dev-server` tag in WebpackDevServer;
82
- return "";
83
- }
84
- getCompilerOptions() {
85
- return this.compiler.options;
86
- }
87
- sendMessage(clients, type, data, params) {
88
- for (const client of clients) {
89
- if (client.readyState === 1) {
90
- client.send(JSON.stringify({ type, data, params }));
91
- }
162
+ for (const key in compiler.options.entry) {
163
+ compiler.options.entry[key].import.unshift(...additionalEntries);
92
164
  }
93
165
  }
94
166
  watchFiles(watchPath, watchOptions) {
95
- const watcher = chokidar_1.default.watch(watchPath, watchOptions);
167
+ const chokidar = require("chokidar");
168
+ const watcher = chokidar.watch(watchPath, watchOptions);
96
169
  // disabling refreshing on changing the content
97
170
  if (this.options.liveReload) {
98
171
  // TODO: remove this after we had memory filesystem
@@ -107,213 +180,191 @@ class RspackDevServer {
107
180
  }
108
181
  this.staticWatchers.push(watcher);
109
182
  }
110
- invalidate(callback = () => { }) {
111
- if (this.middleware) {
112
- this.middleware.invalidate(callback);
183
+ getClientTransport() {
184
+ // WARNING: we can't use `super.getClientTransport`,
185
+ // because we doesn't had same directory structure.
186
+ // and TODO: we need impelement `webpack.providerPlugin`
187
+ let clientImplementation;
188
+ let clientImplementationFound = true;
189
+ const isKnownWebSocketServerImplementation = this.options.webSocketServer &&
190
+ typeof this.options.webSocketServer.type === "string" &&
191
+ (this.options.webSocketServer.type === "ws" ||
192
+ this.options.webSocketServer.type === "sockjs");
193
+ let clientTransport;
194
+ if (this.options.client) {
195
+ if (
196
+ // @ts-ignore
197
+ typeof this.options.client.webSocketTransport !== "undefined") {
198
+ // @ts-ignore
199
+ clientTransport = this.options.client.webSocketTransport;
200
+ }
201
+ else if (isKnownWebSocketServerImplementation) {
202
+ // @ts-ignore
203
+ clientTransport = this.options.webSocketServer.type;
204
+ }
205
+ else {
206
+ clientTransport = "ws";
207
+ }
208
+ }
209
+ else {
210
+ clientTransport = "ws";
211
+ }
212
+ switch (typeof clientTransport) {
213
+ case "string":
214
+ // could be 'sockjs', 'ws', or a path that should be required
215
+ if (clientTransport === "sockjs") {
216
+ clientImplementation = require.resolve("@rspack/dev-client/clients/SockJSClient");
217
+ }
218
+ else if (clientTransport === "ws") {
219
+ clientImplementation = require.resolve("@rspack/dev-client/clients/WebSocketClient");
220
+ }
221
+ else {
222
+ try {
223
+ clientImplementation = require.resolve(clientTransport);
224
+ throw Error("Do not support custom ws client now");
225
+ }
226
+ catch (e) {
227
+ clientImplementationFound = false;
228
+ }
229
+ }
230
+ break;
231
+ default:
232
+ clientImplementationFound = false;
233
+ }
234
+ if (!clientImplementationFound) {
235
+ throw new Error(`${!isKnownWebSocketServerImplementation
236
+ ? "When you use custom web socket implementation you must explicitly specify client.webSocketTransport. "
237
+ : ""}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 `);
113
238
  }
239
+ return clientImplementation;
114
240
  }
115
- async start() {
241
+ async initialize() {
242
+ const compilers = this.compiler instanceof core_1.MultiCompiler
243
+ ? this.compiler.compilers
244
+ : [this.compiler];
245
+ compilers.forEach(compiler => {
246
+ var _a, _b, _c;
247
+ var _d, _e, _f;
248
+ (_a = (_d = compiler.options.builtins).react) !== null && _a !== void 0 ? _a : (_d.react = {});
249
+ if (this.options.hot) {
250
+ (_b = (_e = compiler.options.builtins.react).refresh) !== null && _b !== void 0 ? _b : (_e.refresh = true);
251
+ (_c = (_f = compiler.options.builtins.react).development) !== null && _c !== void 0 ? _c : (_f.development = true);
252
+ }
253
+ else if (compiler.options.builtins.react.refresh) {
254
+ this.logger.warn("builtins.react.refresh needs builtins.react.development and devServer.hot enabled");
255
+ }
256
+ });
257
+ if (this.options.webSocketServer) {
258
+ compilers.forEach(compiler => {
259
+ this.addAdditionEntires(compiler);
260
+ });
261
+ }
116
262
  this.setupHooks();
263
+ // @ts-expect-error: `setupApp` is private function in base class.
117
264
  this.setupApp();
118
- this.createServer();
119
- this.setupWatchStaticFiles();
120
- this.createWebsocketServer();
265
+ // @ts-expect-error: `setupHostHeaderCheck` is private function in base class.
266
+ this.setupHostHeaderCheck();
121
267
  this.setupDevMiddleware();
268
+ // @ts-expect-error: `setupBuiltInRoutes` is private function in base class.
269
+ this.setupBuiltInRoutes();
270
+ // @ts-expect-error: `setupWatchFiles` is private function in base class.
271
+ this.setupWatchFiles();
272
+ // @ts-expect-error: `setupWatchStaticFiles` is private function in base class.
273
+ this.setupWatchStaticFiles();
122
274
  this.setupMiddlewares();
123
- const host = await RspackDevServer.getHostname(this.options.host);
124
- const port = await RspackDevServer.getFreePort(this.options.port, host);
125
- this.options.port = port;
126
- await new Promise(resolve => this.server.listen({
127
- port,
128
- host
129
- }, () => {
130
- this.logger.info(`Loopback: http://localhost:${port}`);
131
- let internalIPv4 = webpack_dev_server_1.default.internalIPSync("v4");
132
- this.logger.info(`Your Network (IPV4) http://${internalIPv4}:${port}`);
133
- resolve({});
134
- }));
135
- }
136
- startCallback(callback) {
137
- throw new Error("Method not implemented.");
138
- }
139
- stopCallback(callback) {
140
- throw new Error("Method not implemented.");
141
- }
142
- listen(port, hostname, fn) {
143
- throw new Error("Method not implemented.");
144
- }
145
- close(callback) {
146
- throw new Error("Method not implemented.");
147
- }
148
- async stop() {
149
- await Promise.all(this.staticWatchers.map(watcher => watcher.close()));
150
- this.middleware = null;
151
- this.staticWatchers = [];
152
- if (this.server) {
153
- this.server.close();
154
- }
155
- if (this.webSocketServer) {
156
- await new Promise(resolve => {
157
- this.webSocketServer.implementation.close(() => {
158
- resolve(void 0);
159
- });
160
- for (const client of this.webSocketServer.clients)
161
- client.terminate();
275
+ // @ts-expect-error: `createServer` is private function in base class.
276
+ this.createServer();
277
+ if (this.options.setupExitSignals) {
278
+ const signals = ["SIGINT", "SIGTERM"];
279
+ let needForceShutdown = false;
280
+ signals.forEach(signal => {
281
+ const listener = () => {
282
+ if (needForceShutdown) {
283
+ process.exit();
284
+ }
285
+ this.logger.info("Gracefully shutting down. To force exit, press ^C again. Please wait...");
286
+ needForceShutdown = true;
287
+ this.stopCallback(() => {
288
+ if (typeof this.compiler.close === "function") {
289
+ this.compiler.close(() => {
290
+ process.exit();
291
+ });
292
+ }
293
+ else {
294
+ process.exit();
295
+ }
296
+ });
297
+ };
298
+ // @ts-expect-error: `listeners` is private function in base class.
299
+ this.listeners.push({ name: signal, listener });
300
+ process.on(signal, listener);
162
301
  });
163
302
  }
164
- }
165
- setupApp() {
166
- this.app = (0, express_1.default)();
167
- }
168
- setupWatchStaticFiles() {
169
- if (this.options.static.watch === false) {
170
- return;
171
- }
172
- this.watchFiles(this.options.static.directory, this.options.static.watch);
303
+ // Proxy WebSocket without the initial http request
304
+ // https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
305
+ // @ts-expect-error: `webSocketProxies` is private function in base class.
306
+ this.webSocketProxies.forEach(webSocketProxy => {
307
+ this.server.on("upgrade", webSocketProxy.upgrade);
308
+ }, this);
173
309
  }
174
310
  setupDevMiddleware() {
175
311
  // @ts-ignored
176
312
  this.middleware = (0, dev_middleware_1.default)(this.compiler, this.options.devMiddleware);
177
313
  }
178
- createWebsocketServer() {
179
- if (this.options.webSocketServer !== false) {
180
- this.webSocketServer = (0, ws_1.createWebsocketServer)(this);
181
- }
182
- }
183
314
  setupMiddlewares() {
184
- const options = this.options;
185
315
  const middlewares = [];
186
- middlewares.push({
187
- name: "rdm",
188
- middleware: this.middleware
189
- });
190
- if (this.compiler.options.experiments.lazyCompilation) {
191
- middlewares.push({
192
- middleware: (req, res, next) => {
193
- if (req.url.indexOf("/lazy-compilation-web/") > -1) {
194
- const path = req.url.replace("/lazy-compilation-web/", "");
195
- if (fs_1.default.existsSync(path)) {
196
- this.compiler.rebuild([path], (error, stats) => {
197
- if (error) {
198
- throw error;
199
- }
200
- res.write("");
201
- res.end();
202
- console.log("lazy compiler success");
316
+ const compilers = this.compiler instanceof core_1.MultiCompiler
317
+ ? this.compiler.compilers
318
+ : [this.compiler];
319
+ if (Array.isArray(this.options.static)) {
320
+ this.options.static.forEach(staticOptions => {
321
+ staticOptions.publicPath.forEach(publicPath => {
322
+ compilers.forEach(compiler => {
323
+ if (compiler.options.builtins.noEmitAssets) {
324
+ middlewares.push({
325
+ name: "rspack-memory-assets",
326
+ path: publicPath,
327
+ middleware: (0, dev_middleware_1.getRspackMemoryAssets)(compiler, this.middleware)
203
328
  });
204
329
  }
205
- }
206
- }
330
+ });
331
+ });
207
332
  });
208
333
  }
209
- // Todo Add options
210
- const connectHistoryApiFallback = require("connect-history-api-fallback");
211
- middlewares.push({
212
- name: "[connect-history-api-fallback]",
213
- middleware: connectHistoryApiFallback({
214
- verbose: true,
215
- logger: console.log.bind(console)
216
- })
217
- });
218
- /**
219
- * supports three kinds of proxy configuration
220
- * {context: 'xxxx', target: 'yyy}
221
- * {['xxx']: { target: 'yyy}}
222
- * [{context: 'xxx',target:'yyy'}, {context: 'aaa', target: 'zzzz'}]
223
- */
224
- if (typeof options.proxy !== "undefined") {
225
- const { createProxyMiddleware } = require("http-proxy-middleware");
226
- function getProxyMiddleware(proxyConfig) {
227
- if (proxyConfig.target) {
228
- const context = proxyConfig.context || proxyConfig.path;
229
- return createProxyMiddleware(context, proxyConfig);
230
- }
231
- if (proxyConfig.router) {
232
- return createProxyMiddleware(proxyConfig);
233
- }
234
- }
235
- if (!Array.isArray(options.proxy)) {
236
- if (Object.prototype.hasOwnProperty.call(options.proxy, "target") ||
237
- Object.prototype.hasOwnProperty.call(options.proxy, "router")) {
238
- options.proxy = [options.proxy];
239
- }
240
- else {
241
- options.proxy = Object.keys(options.proxy).map(context => {
242
- let proxyOptions;
243
- // For backwards compatibility reasons.
244
- const correctedContext = context
245
- .replace(/^\*$/, "**")
246
- .replace(/\/\*$/, "");
247
- if (typeof ( /** @type {ProxyConfigMap} */options.proxy[context]) ===
248
- "string") {
249
- proxyOptions = {
250
- context: correctedContext,
251
- target:
252
- /** @type {ProxyConfigMap} */
253
- options.proxy[context]
254
- };
255
- }
256
- else {
257
- proxyOptions = {
258
- // @ts-ignore
259
- ... /** @type {ProxyConfigMap} */options.proxy[context]
260
- };
261
- proxyOptions.context = correctedContext;
334
+ compilers.forEach(compiler => {
335
+ if (compiler.options.experiments.lazyCompilation) {
336
+ middlewares.push({
337
+ middleware: (req, res, next) => {
338
+ if (req.url.indexOf("/lazy-compilation-web/") > -1) {
339
+ const path = req.url.replace("/lazy-compilation-web/", "");
340
+ if (fs_1.default.existsSync(path)) {
341
+ compiler.rebuild(new Set([path]), new Set(), error => {
342
+ if (error) {
343
+ throw error;
344
+ }
345
+ res.write("");
346
+ res.end();
347
+ console.log("lazy compiler success");
348
+ });
349
+ }
262
350
  }
263
- return proxyOptions;
264
- });
265
- }
266
- }
267
- options.proxy.forEach(proxyConfig => {
268
- const handler = async (req, res, next) => {
269
- let proxyMiddleware = getProxyMiddleware(proxyConfig);
270
- const isByPassFuncDefined = typeof proxyConfig.bypass === "function";
271
- const bypassUrl = isByPassFuncDefined
272
- ? await proxyConfig.bypass(req, res, proxyConfig)
273
- : null;
274
- if (typeof bypassUrl === "boolean") {
275
- req.url = null;
276
- next();
277
- }
278
- else if (typeof bypassUrl === "string") {
279
- req.url = bypassUrl;
280
- }
281
- else if (proxyMiddleware) {
282
- return proxyMiddleware(req, res, next);
283
351
  }
284
- else {
285
- next();
286
- }
287
- };
288
- middlewares.push({
289
- name: "http-proxy-middleware",
290
- middleware: handler
291
352
  });
292
- middlewares.push({
293
- name: "http-proxy-middleware-error-handler",
294
- middleware: (error, req, res, next) => handler(req, res, next)
295
- });
296
- });
297
- }
298
- const publicPath = this.compiler.options.output.publicPath === "auto"
299
- ? ""
300
- : this.compiler.options.output.publicPath;
301
- middlewares.push({
302
- name: "express-static",
303
- path: publicPath,
304
- middleware: express_1.default.static(this.options.static.directory)
353
+ }
305
354
  });
306
- middlewares.forEach(m => {
307
- if (m.path) {
308
- this.app.use(m.path, m.middleware);
355
+ middlewares.forEach(middleware => {
356
+ if (typeof middleware === "function") {
357
+ this.app.use(middleware);
358
+ }
359
+ else if (typeof middleware.path !== "undefined") {
360
+ this.app.use(middleware.path, middleware.middleware);
309
361
  }
310
362
  else {
311
- this.app.use(m.middleware);
363
+ this.app.use(middleware.middleware);
312
364
  }
313
365
  });
314
- }
315
- createServer() {
316
- this.server = http_1.default.createServer(this.app);
366
+ // @ts-expect-error
367
+ super.setupMiddlewares();
317
368
  }
318
369
  setupHooks() {
319
370
  this.compiler.hooks.done.tap("dev-server", stats => {