@rspack/dev-server 0.0.0-e859caeee2-20221212102225 → 0.0.0-faecddc-20230109081930

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 (43) hide show
  1. package/CHANGELOG.md +110 -7
  2. package/LICENSE +21 -0
  3. package/jest.config.js +3 -2
  4. package/package.json +11 -8
  5. package/src/config.ts +14 -3
  6. package/src/server.ts +34 -4
  7. package/tests/__snapshots__/normalizeOptions.test.ts.snap +11 -1
  8. package/tests/e2e/hot-reaload.test.ts +215 -0
  9. package/tests/e2e-fixtures/react/app.jsx +14 -0
  10. package/tests/e2e-fixtures/react/index.css +3 -0
  11. package/tests/e2e-fixtures/react/index.html +12 -0
  12. package/tests/e2e-fixtures/react/index.jsx +6 -0
  13. package/tests/e2e-fixtures/react/package.json +6 -0
  14. package/tests/e2e-fixtures/react/webpack.config.js +22 -0
  15. package/tests/helpers/emitFile.ts +69 -0
  16. package/tests/helpers/runBrowser.ts +85 -0
  17. package/tests/helpers/tempDir.ts +58 -0
  18. package/tests/normalizeOptions.test.ts +1 -1
  19. package/dist/config.d.ts +0 -19
  20. package/dist/config.d.ts.map +0 -1
  21. package/dist/config.js +0 -55
  22. package/dist/config.js.map +0 -1
  23. package/dist/index.d.ts +0 -2
  24. package/dist/index.d.ts.map +0 -1
  25. package/dist/index.js +0 -6
  26. package/dist/index.js.map +0 -1
  27. package/dist/logger.d.ts +0 -7
  28. package/dist/logger.d.ts.map +0 -1
  29. package/dist/logger.js +0 -28
  30. package/dist/logger.js.map +0 -1
  31. package/dist/reload.d.ts +0 -9
  32. package/dist/reload.d.ts.map +0 -1
  33. package/dist/reload.js +0 -23
  34. package/dist/reload.js.map +0 -1
  35. package/dist/server.d.ts +0 -55
  36. package/dist/server.d.ts.map +0 -1
  37. package/dist/server.js +0 -324
  38. package/dist/server.js.map +0 -1
  39. package/dist/ws.d.ts +0 -13
  40. package/dist/ws.d.ts.map +0 -1
  41. package/dist/ws.js +0 -12
  42. package/dist/ws.js.map +0 -1
  43. package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md CHANGED
@@ -1,15 +1,118 @@
1
1
  # rspack-dev-server
2
2
 
3
- ## 0.0.0-e859caeee2-20221212102225
3
+ ## 0.0.0-faecddc-20230109081930
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - 3701a8bf58: fix less resolve bug
8
- - Updated dependencies [3701a8bf58]
9
- - @rspack/core@0.0.0-e859caeee2-20221212102225
10
- - @rspack/dev-client@0.0.0-e859caeee2-20221212102225
11
- - @rspack/dev-middleware@0.0.0-e859caeee2-20221212102225
12
- - @rspack/dev-server@0.0.0-e859caeee2-20221212102225
7
+ - 59edc2cb: fix watch options
8
+ - Updated dependencies [59edc2cb]
9
+ - Updated dependencies [3fcfa746]
10
+ - @rspack/core@0.0.0-faecddc-20230109081930
11
+ - @rspack/dev-client@0.0.0-faecddc-20230109081930
12
+ - @rspack/dev-middleware@0.0.0-faecddc-20230109081930
13
+ - @rspack/dev-server@0.0.0-faecddc-20230109081930
14
+
15
+ ## 0.0.21
16
+
17
+ ### Patch Changes
18
+
19
+ - fix watch
20
+ - Updated dependencies
21
+ - @rspack/core@0.0.21
22
+ - @rspack/dev-client@0.0.21
23
+ - @rspack/dev-middleware@0.0.21
24
+ - @rspack/dev-server@0.0.21
25
+
26
+ ## 0.0.20
27
+
28
+ ### Patch Changes
29
+
30
+ - fix load extra css chunk
31
+ - Updated dependencies
32
+ - @rspack/core@0.0.20
33
+ - @rspack/dev-client@0.0.20
34
+ - @rspack/dev-middleware@0.0.20
35
+ - @rspack/dev-server@0.0.20
36
+
37
+ ## 0.0.19
38
+
39
+ ### Patch Changes
40
+
41
+ - 882093b8: support module.resolve
42
+ - Updated dependencies [db66ae2e]
43
+ - Updated dependencies [882093b8]
44
+ - @rspack/core@0.0.19
45
+ - @rspack/dev-client@0.0.19
46
+ - @rspack/dev-middleware@0.0.19
47
+ - @rspack/dev-server@0.0.19
48
+
49
+ ## 0.0.18
50
+
51
+ ### Patch Changes
52
+
53
+ - bump version
54
+ - Updated dependencies
55
+ - @rspack/core@0.0.18
56
+ - @rspack/dev-client@0.0.18
57
+ - @rspack/dev-middleware@0.0.18
58
+ - @rspack/dev-server@0.0.18
59
+
60
+ ## 0.0.17
61
+
62
+ ### Patch Changes
63
+
64
+ - upgrade
65
+ - Updated dependencies
66
+ - @rspack/core@0.0.17
67
+ - @rspack/dev-client@0.0.17
68
+ - @rspack/dev-middleware@0.0.17
69
+ - @rspack/dev-server@0.0.17
70
+
71
+ ## 0.0.16
72
+
73
+ ### Patch Changes
74
+
75
+ - support optional dependency
76
+ - Updated dependencies
77
+ - @rspack/core@0.0.16
78
+ - @rspack/dev-client@0.0.16
79
+ - @rspack/dev-middleware@0.0.16
80
+ - @rspack/dev-server@0.0.16
81
+
82
+ ## 0.0.15
83
+
84
+ ### Patch Changes
85
+
86
+ - bump version
87
+ - Updated dependencies
88
+ - @rspack/core@0.0.15
89
+ - @rspack/dev-client@0.0.15
90
+ - @rspack/dev-middleware@0.0.15
91
+ - @rspack/dev-server@0.0.15
92
+
93
+ ## 0.0.14
94
+
95
+ ### Patch Changes
96
+
97
+ - bump version
98
+ - 11e87c61: fix less resolve bug
99
+ - Updated dependencies
100
+ - Updated dependencies [11e87c61]
101
+ - @rspack/core@0.0.14
102
+ - @rspack/dev-client@0.0.14
103
+ - @rspack/dev-middleware@0.0.14
104
+ - @rspack/dev-server@0.0.14
105
+
106
+ ## 0.0.13
107
+
108
+ ### Patch Changes
109
+
110
+ - 3701a8bf: fix less resolve bug
111
+ - Updated dependencies [3701a8bf]
112
+ - @rspack/core@0.0.13
113
+ - @rspack/dev-client@0.0.13
114
+ - @rspack/dev-middleware@0.0.13
115
+ - @rspack/dev-server@0.0.13
13
116
 
14
117
  ## 0.0.12
15
118
 
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Rspack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/jest.config.js CHANGED
@@ -2,6 +2,7 @@
2
2
  module.exports = {
3
3
  preset: "ts-jest",
4
4
  testEnvironment: "node",
5
- testMatch: ["<rootDir>/tests/*.test.ts"],
6
- cache: false
5
+ testMatch: ["<rootDir>/tests/*.test.ts", "<rootDir>/tests/e2e/*.test.ts"],
6
+ cache: false,
7
+ testTimeout: process.env.CI ? 60000 : 30000
7
8
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rspack/dev-server",
3
3
  "description": "",
4
- "version": "0.0.0-e859caeee2-20221212102225",
4
+ "version": "0.0.0-faecddc-20230109081930",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "",
@@ -9,10 +9,13 @@
9
9
  "devDependencies": {
10
10
  "tsm": "^2.2.2",
11
11
  "typescript": "^4.7.4",
12
+ "@types/ws": "8.5.3",
12
13
  "@types/node": "16.11.7",
13
14
  "@types/express": "4.17.14",
14
15
  "@types/connect-history-api-fallback": "1.3.5",
15
- "@rspack/core": "0.0.0-e859caeee2-20221212102225"
16
+ "fs-extra": "11.1.0",
17
+ "puppeteer": "19.4.0",
18
+ "@rspack/core": "0.0.0-faecddc-20230109081930"
16
19
  },
17
20
  "dependencies": {
18
21
  "express": "4.18.1",
@@ -21,16 +24,16 @@
21
24
  "webpack-dev-server": "4.11.1",
22
25
  "connect-history-api-fallback": "2.0.0",
23
26
  "http-proxy-middleware": "2.0.6",
24
- "@rspack/dev-client": "0.0.0-e859caeee2-20221212102225",
25
- "@rspack/dev-middleware": "0.0.0-e859caeee2-20221212102225",
26
- "@rspack/dev-server": "0.0.0-e859caeee2-20221212102225"
27
+ "@rspack/dev-client": "0.0.0-faecddc-20230109081930",
28
+ "@rspack/dev-server": "0.0.0-faecddc-20230109081930",
29
+ "@rspack/dev-middleware": "0.0.0-faecddc-20230109081930"
27
30
  },
28
31
  "peerDependencies": {
29
- "@rspack/core": "0.0.0-e859caeee2-20221212102225"
32
+ "@rspack/core": "0.0.0-faecddc-20230109081930"
30
33
  },
31
34
  "scripts": {
32
- "build": "rm -rf lib/ && tsc",
35
+ "build": "rm -rf dist/ && tsc",
33
36
  "dev": "tsc -w",
34
- "test": "jest --verbose"
37
+ "test": "rm -rf .test-temp && jest --verbose"
35
38
  }
36
39
  }
package/src/config.ts CHANGED
@@ -5,12 +5,11 @@ import type {
5
5
  } from "@rspack/core";
6
6
  import type { WatchOptions } from "chokidar";
7
7
  import path from "path";
8
- import { resolveWatchOption } from "@rspack/core";
9
8
  import { ProxyOptions } from "@rspack/core/src/config/devServer";
10
9
 
11
10
  export interface ResolvedDev {
12
11
  host: string;
13
- port: number;
12
+ port: number | string;
14
13
  static: {
15
14
  directory: string;
16
15
  watch: false | WatchOptions;
@@ -23,6 +22,18 @@ export interface ResolvedDev {
23
22
  proxy: ProxyOptions;
24
23
  }
25
24
 
25
+ function resolveStaticWatchOptions(watch: WatchOptions = {}) {
26
+ const ignored = watch.ignored ?? [
27
+ "**/dist/**",
28
+ "**/node_modules/**",
29
+ "**/.git/**"
30
+ ];
31
+ return {
32
+ ...watch,
33
+ ignored
34
+ };
35
+ }
36
+
26
37
  export function resolveDevOptions(
27
38
  devConfig: Dev,
28
39
  compilerOptions: RspackOptionsNormalized
@@ -38,7 +49,7 @@ export function resolveDevOptions(
38
49
  if (devConfig.static?.watch === false) {
39
50
  watch = false;
40
51
  } else if (devConfig.static?.watch === true) {
41
- watch = resolveWatchOption({});
52
+ watch = resolveStaticWatchOptions({});
42
53
  } else if (devConfig.static?.watch) {
43
54
  watch = devConfig.static?.watch;
44
55
  }
package/src/server.ts CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  RequestHandler as ExpressRequestHandler,
9
9
  ErrorRequestHandler as ExpressErrorRequestHandler
10
10
  } from "express";
11
- import type { DevMiddleware } from "@rspack/dev-middleware";
11
+ import { DevMiddleware, getRspackMemoryAssets } from "@rspack/dev-middleware";
12
12
  import type { Server } from "http";
13
13
  import type { ResolvedDev } from "./config";
14
14
  import fs from "fs";
@@ -64,6 +64,7 @@ export class RspackDevServer {
64
64
  }
65
65
 
66
66
  rewriteCompilerOptions() {
67
+ this.compiler.options.devServer = this.options;
67
68
  if (!this.compiler.options.builtins.react) {
68
69
  this.compiler.options.builtins.react = {};
69
70
  }
@@ -72,6 +73,10 @@ export class RspackDevServer {
72
73
  if (this.options.hot) {
73
74
  this.compiler.options.builtins.react.refresh =
74
75
  this.compiler.options.builtins.react.refresh ?? true;
76
+ } else if (this.compiler.options.builtins.react.refresh) {
77
+ this.logger.warn(
78
+ "[Builtins] react.refresh need react.development and devServer.hot enabled."
79
+ );
75
80
  }
76
81
  }
77
82
 
@@ -187,6 +192,7 @@ export class RspackDevServer {
187
192
  this.setupMiddlewares();
188
193
  const host = await RspackDevServer.getHostname(this.options.host);
189
194
  const port = await RspackDevServer.getFreePort(this.options.port, host);
195
+ this.options.port = port;
190
196
  await new Promise(resolve =>
191
197
  this.server.listen(
192
198
  {
@@ -219,15 +225,30 @@ export class RspackDevServer {
219
225
  }
220
226
 
221
227
  async stop(): Promise<void> {
228
+ this.compiler.close(() => {});
222
229
  await Promise.all(this.staticWatchers.map(watcher => watcher.close()));
223
- this.middleware = null;
224
230
  this.staticWatchers = [];
231
+
232
+ if (this.middleware) {
233
+ await new Promise((resolve, reject) => {
234
+ this.middleware.close((error: Error) => {
235
+ if (error) {
236
+ reject(error);
237
+ return;
238
+ }
239
+ resolve(undefined);
240
+ });
241
+ });
242
+ }
243
+ this.middleware = null;
244
+
225
245
  if (this.server) {
226
246
  this.server.close();
227
247
  }
228
248
  if (this.webSocketServer) {
229
249
  await new Promise(resolve => {
230
250
  this.webSocketServer.implementation.close(() => {
251
+ this.webSocketServer = null;
231
252
  resolve(void 0);
232
253
  });
233
254
  for (const client of this.webSocketServer.clients) client.terminate();
@@ -271,7 +292,7 @@ export class RspackDevServer {
271
292
  if (req.url.indexOf("/lazy-compilation-web/") > -1) {
272
293
  const path = req.url.replace("/lazy-compilation-web/", "");
273
294
  if (fs.existsSync(path)) {
274
- this.compiler.rebuild([path], (error, stats) => {
295
+ this.compiler.rebuild(new Set([path]), new Set(), error => {
275
296
  if (error) {
276
297
  throw error;
277
298
  }
@@ -375,9 +396,18 @@ export class RspackDevServer {
375
396
  });
376
397
  });
377
398
  }
399
+ const publicPath =
400
+ this.compiler.options.output.publicPath === "auto"
401
+ ? ""
402
+ : this.compiler.options.output.publicPath;
403
+ middlewares.push({
404
+ name: "rspack-memory-assets",
405
+ path: publicPath,
406
+ middleware: getRspackMemoryAssets(this.compiler)
407
+ });
378
408
  middlewares.push({
379
409
  name: "express-static",
380
- path: this.compiler.options.output.publicPath ?? "/",
410
+ path: publicPath,
381
411
  middleware: express.static(this.options.static.directory)
382
412
  });
383
413
 
@@ -52,7 +52,6 @@ exports[`normalize options snapshot react.development and react.refresh should b
52
52
  "decorator": {
53
53
  "emitMetadata": true,
54
54
  "legacy": true,
55
- "useDefineForClassFields": true,
56
55
  },
57
56
  "define": {},
58
57
  "html": [],
@@ -66,7 +65,18 @@ exports[`normalize options snapshot react.development and react.refresh should b
66
65
  },
67
66
  },
68
67
  "devServer": {
68
+ "devMiddleware": {},
69
+ "host": undefined,
69
70
  "hot": true,
71
+ "liveReload": true,
72
+ "open": true,
73
+ "port": undefined,
74
+ "proxy": undefined,
75
+ "static": {
76
+ "directory": "<PROJECT_ROOT>/dist",
77
+ "watch": {},
78
+ },
79
+ "webSocketServer": {},
70
80
  },
71
81
  }
72
82
  `;
@@ -0,0 +1,215 @@
1
+ import { RspackDevServer } from "@rspack/dev-server";
2
+ import { createCompiler } from "@rspack/core";
3
+ import { initFixture, installDeps } from "../helpers/tempDir";
4
+ import { editFile, waitingForBuild } from "../helpers/emitFile";
5
+ import path from "path";
6
+ import runBrowser from "../helpers/runBrowser";
7
+ import type { Browser, Page } from "puppeteer";
8
+ import fs from "fs";
9
+ // FIXME: A concurrency problem occurs when executing on ci
10
+ // describe("reload and hot should works", () => {
11
+ // let browser: Browser;
12
+ // let server: RspackDevServer;
13
+
14
+ // afterEach(async () => {
15
+ // if (browser) {
16
+ // await browser.close();
17
+ // }
18
+ // if (server) {
19
+ // await server.stop();
20
+ // }
21
+ // });
22
+
23
+ // it("reload should works", async () => {
24
+ // console.log("=== first start ===");
25
+ // const tempDir = await initFixture("react");
26
+ // await installDeps(tempDir);
27
+ // const config = require(path.resolve(tempDir, "./webpack.config.js"));
28
+ // const compiler = createCompiler({
29
+ // ...config,
30
+ // context: tempDir,
31
+ // devServer: {
32
+ // hot: false,
33
+ // liveReload: true
34
+ // }
35
+ // });
36
+ // server = new RspackDevServer(compiler);
37
+ // await server.start();
38
+ // const launched = await runBrowser();
39
+ // ({ browser } = launched);
40
+ // const { page } = launched;
41
+
42
+ // const consoleMessages: string[] = [];
43
+ // page.on("console", message => {
44
+ // const text = message.text();
45
+ // consoleMessages.push(text);
46
+ // });
47
+
48
+ // await page.goto(`http://localhost:${server.options.port}`);
49
+ // await page.click(".test-button");
50
+ // expect(await getText(page, ".test-button-content")).toBe("1");
51
+ // expect(await getText(page, ".placeholder")).toBe("__PLACE_HOLDER__");
52
+ // await editFile(path.resolve(tempDir, "./app.jsx"), code =>
53
+ // code.replace("__PLACE_HOLDER__", "update")
54
+ // );
55
+ // expect(await getText(page, ".test-button-content")).toBe("0");
56
+ // await page.click(".test-button");
57
+ // expect(await getText(page, ".placeholder")).toBe("update");
58
+ // await editFile(path.resolve(tempDir, "./index.css"), code =>
59
+ // code.replace("rgba(0, 0, 0, 0)", "rgba(255, 0, 0, 0)")
60
+ // );
61
+ // expect(await getText(page, ".test-button-content")).toBe("0");
62
+ // expect((await getComputedStyle(page, "body")).backgroundColor).toBe(
63
+ // "rgba(255, 0, 0, 0)"
64
+ // );
65
+ // console.log("=== first end ===");
66
+ // });
67
+
68
+ // it("hot should works", async () => {
69
+ // console.log("=== second start ===");
70
+ // const tempDir = await initFixture("react");
71
+ // await installDeps(tempDir);
72
+ // const config = require(path.resolve(tempDir, "./webpack.config.js"));
73
+ // const compiler = createCompiler({
74
+ // ...config,
75
+ // context: tempDir
76
+ // });
77
+ // server = new RspackDevServer(compiler);
78
+ // await server.start();
79
+
80
+ // const launched = await runBrowser();
81
+ // ({ browser } = launched);
82
+ // const { page } = launched;
83
+
84
+ // const consoleMessages: string[] = [];
85
+ // page.on("console", message => {
86
+ // const text = message.text();
87
+ // consoleMessages.push(text);
88
+ // });
89
+
90
+ // await page.goto(`http://localhost:${server.options.port}`);
91
+
92
+ // await page.click(".test-button");
93
+ // expect(await getText(page, ".test-button-content")).toBe("1");
94
+ // expect(await getText(page, ".placeholder")).toBe("__PLACE_HOLDER__");
95
+ // await editFile(path.resolve(tempDir, "./app.jsx"), code =>
96
+ // code.replace("__PLACE_HOLDER__", "update")
97
+ // );
98
+ // expect(await getText(page, ".placeholder")).toBe("update");
99
+ // await editFile(path.resolve(tempDir, "./index.css"), code =>
100
+ // code.replace("rgba(0, 0, 0, 0)", "rgba(255, 0, 0, 0)")
101
+ // );
102
+ // expect((await getComputedStyle(page, "body")).backgroundColor).toBe(
103
+ // "rgba(255, 0, 0, 0)"
104
+ // );
105
+ // expect(await getText(page, ".test-button-content")).toBe("1");
106
+ // expect(consoleMessages).toContain("App hot update...");
107
+ // console.log("=== second end ===");
108
+ // });
109
+ // });
110
+
111
+ describe("reload and hot should works", () => {
112
+ // TODO: skip it temporary
113
+ it.skip("reload and hot should works", async () => {
114
+ // reload should works
115
+ let tempDir = await initFixture("react");
116
+ await installDeps(tempDir);
117
+ let config = require(path.resolve(tempDir, "./webpack.config.js"));
118
+ let compiler = createCompiler({
119
+ ...config,
120
+ context: tempDir,
121
+ devServer: {
122
+ hot: false,
123
+ liveReload: true
124
+ }
125
+ });
126
+ let server = new RspackDevServer(compiler);
127
+ await server.start();
128
+ await waitingForBuild(server.options.port);
129
+ console.log("=== before goto page ===");
130
+ let { browser, page } = await runBrowser();
131
+
132
+ await page.goto(`http://localhost:${server.options.port}`);
133
+ await page.click(".test-button");
134
+ expect(await getText(page, ".test-button-content")).toBe("1");
135
+ expect(await getText(page, ".placeholder")).toBe("__PLACE_HOLDER__");
136
+
137
+ const appFilePath = path.resolve(tempDir, "./app.jsx");
138
+ await editFile(appFilePath, code =>
139
+ code.replace("__PLACE_HOLDER__", "update")
140
+ );
141
+ console.log(
142
+ "after emit file: ",
143
+ appFilePath,
144
+ fs.readFileSync(appFilePath, "utf-8")
145
+ );
146
+ expect(await getText(page, ".test-button-content")).toBe("0");
147
+ await page.click(".test-button");
148
+ expect(await getText(page, ".placeholder")).toBe("update");
149
+ await editFile(path.resolve(tempDir, "./index.css"), code =>
150
+ code.replace("rgba(0, 0, 0, 0)", "rgba(255, 0, 0, 0)")
151
+ );
152
+ expect(await getText(page, ".test-button-content")).toBe("0");
153
+ expect((await getComputedStyle(page, "body")).backgroundColor).toBe(
154
+ "rgba(255, 0, 0, 0)"
155
+ );
156
+ await server.stop();
157
+ await browser.close();
158
+ console.log("=== first end ===");
159
+
160
+ // hot should works;
161
+ console.log("=== second start ===");
162
+ tempDir = await initFixture("react");
163
+ await installDeps(tempDir);
164
+ config = require(path.resolve(tempDir, "./webpack.config.js"));
165
+ compiler = createCompiler({
166
+ ...config,
167
+ context: tempDir
168
+ });
169
+ server = new RspackDevServer(compiler);
170
+ await server.start();
171
+ await waitingForBuild(server.options.port);
172
+ console.log("=== before goto page ===");
173
+
174
+ ({ browser, page } = await runBrowser());
175
+ const consoleMessages: string[] = [];
176
+ page.on("console", message => {
177
+ const text = message.text();
178
+ consoleMessages.push(text);
179
+ });
180
+ await page.goto(`http://localhost:${server.options.port}`);
181
+ await page.click(".test-button");
182
+ expect(await getText(page, ".test-button-content")).toBe("1");
183
+ expect(await getText(page, ".placeholder")).toBe("__PLACE_HOLDER__");
184
+ await editFile(path.resolve(tempDir, "./app.jsx"), code =>
185
+ code.replace("__PLACE_HOLDER__", "update")
186
+ );
187
+ expect(await getText(page, ".placeholder")).toBe("update");
188
+ await editFile(path.resolve(tempDir, "./index.css"), code =>
189
+ code.replace("rgba(0, 0, 0, 0)", "rgba(255, 0, 0, 0)")
190
+ );
191
+ expect((await getComputedStyle(page, "body")).backgroundColor).toBe(
192
+ "rgba(255, 0, 0, 0)"
193
+ );
194
+ expect(await getText(page, ".test-button-content")).toBe("1");
195
+ expect(consoleMessages).toContain("App hot update...");
196
+ await server.stop();
197
+ await browser.close();
198
+ console.log("=== second end ===");
199
+ });
200
+ });
201
+
202
+ async function getComputedStyle(
203
+ page: Page,
204
+ selector: string
205
+ ): Promise<CSSStyleDeclaration> {
206
+ await page.waitForSelector(selector);
207
+ return await page.$eval(selector, ele =>
208
+ JSON.parse(JSON.stringify(window.getComputedStyle(ele)))
209
+ );
210
+ }
211
+
212
+ async function getText(page: Page, selector: string) {
213
+ await page.waitForSelector(selector);
214
+ return await page.$eval(selector, ele => ele.textContent);
215
+ }
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import "./index.css";
3
+
4
+ export const App = () => {
5
+ const [count, setCount] = React.useState(0);
6
+ return (
7
+ <div>
8
+ <div className="test-button" onClick={() => setCount(() => count + 1)}>
9
+ <span className="test-button-content">{count}</span>
10
+ </div>
11
+ <div className="placeholder">__PLACE_HOLDER__</div>
12
+ </div>
13
+ );
14
+ };
@@ -0,0 +1,3 @@
1
+ body {
2
+ background-color: rgba(0, 0, 0, 0);
3
+ }
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Document</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ </body>
12
+ </html>
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import { App } from "./app";
4
+
5
+ const container = createRoot(document.getElementById("root"));
6
+ container.render(<App />);
@@ -0,0 +1,6 @@
1
+ {
2
+ "dependencies": {
3
+ "react": "18.2.0",
4
+ "react-dom": "18.2.0"
5
+ }
6
+ }
@@ -0,0 +1,22 @@
1
+ module.exports = {
2
+ mode: "development",
3
+ entry: "./index.jsx",
4
+ devServer: {
5
+ hot: true
6
+ },
7
+ stats: "none",
8
+ infrastructureLogging: {
9
+ debug: false
10
+ },
11
+ builtins: {
12
+ html: [
13
+ {
14
+ template: "./index.html",
15
+ publicPath: "/"
16
+ }
17
+ ],
18
+ define: {
19
+ "process.env.NODE_ENV": JSON.stringify("development")
20
+ }
21
+ }
22
+ };