@rspack-canary/test-tools 1.5.6-canary-e598f284-20250921173624 → 1.5.8-canary-e350b761-20250924173613

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 (122) hide show
  1. package/dist/case/builtin.d.ts +2 -0
  2. package/dist/case/builtin.js +173 -13
  3. package/dist/case/cache.d.ts +1 -1
  4. package/dist/case/cache.js +210 -11
  5. package/dist/case/common.d.ts +10 -0
  6. package/dist/case/common.js +237 -0
  7. package/dist/case/compiler.d.ts +7 -4
  8. package/dist/case/compiler.js +144 -109
  9. package/dist/case/config.d.ts +5 -1
  10. package/dist/case/config.js +102 -16
  11. package/dist/case/defaults.d.ts +12 -4
  12. package/dist/case/defaults.js +67 -12
  13. package/dist/case/diagnostic.d.ts +6 -0
  14. package/dist/case/diagnostic.js +123 -14
  15. package/dist/case/diff.d.ts +17 -1
  16. package/dist/case/diff.js +170 -22
  17. package/dist/case/error.d.ts +14 -4
  18. package/dist/case/error.js +117 -10
  19. package/dist/case/hash.d.ts +1 -1
  20. package/dist/case/hash.js +70 -9
  21. package/dist/case/hook.d.ts +35 -4
  22. package/dist/case/hook.js +210 -21
  23. package/dist/case/hot-step.js +307 -9
  24. package/dist/case/hot.d.ts +8 -1
  25. package/dist/case/hot.js +235 -8
  26. package/dist/case/incremental.d.ts +1 -1
  27. package/dist/case/incremental.js +39 -41
  28. package/dist/case/index.d.ts +20 -20
  29. package/dist/case/index.js +44 -34
  30. package/dist/case/native-watcher.js +10 -23
  31. package/dist/case/normal.js +174 -12
  32. package/dist/case/runner.d.ts +18 -0
  33. package/dist/case/runner.js +108 -0
  34. package/dist/case/serial.d.ts +1 -1
  35. package/dist/case/serial.js +8 -12
  36. package/dist/case/stats-api.d.ts +0 -5
  37. package/dist/case/stats-api.js +71 -10
  38. package/dist/case/stats-output.js +197 -11
  39. package/dist/case/treeshaking.js +34 -7
  40. package/dist/case/watch.d.ts +27 -0
  41. package/dist/case/watch.js +321 -21
  42. package/dist/helper/plugins/hot-update.d.ts +2 -2
  43. package/dist/index.d.ts +0 -2
  44. package/dist/index.js +0 -2
  45. package/dist/runner/index.d.ts +2 -7
  46. package/dist/runner/index.js +2 -7
  47. package/dist/runner/{runner/node → node}/index.d.ts +1 -2
  48. package/dist/runner/{runner/node → node}/index.js +2 -2
  49. package/dist/runner/{runner/web → web}/fake.d.ts +1 -2
  50. package/dist/runner/{runner/web → web}/fake.js +7 -7
  51. package/dist/runner/{runner/web → web}/index.d.ts +2 -2
  52. package/dist/runner/{runner/web → web}/index.js +1 -1
  53. package/dist/runner/{runner/web → web}/jsdom.d.ts +1 -2
  54. package/dist/runner/{runner/web → web}/jsdom.js +4 -4
  55. package/dist/test/context.d.ts +3 -5
  56. package/dist/test/context.js +22 -12
  57. package/dist/test/creator.d.ts +13 -12
  58. package/dist/test/creator.js +52 -43
  59. package/dist/test/tester.js +4 -1
  60. package/dist/type.d.ts +42 -11
  61. package/dist/type.js +7 -1
  62. package/package.json +5 -5
  63. package/dist/processor/basic.d.ts +0 -24
  64. package/dist/processor/basic.js +0 -147
  65. package/dist/processor/builtin.d.ts +0 -9
  66. package/dist/processor/builtin.js +0 -171
  67. package/dist/processor/cache.d.ts +0 -20
  68. package/dist/processor/cache.js +0 -131
  69. package/dist/processor/config.d.ts +0 -11
  70. package/dist/processor/config.js +0 -88
  71. package/dist/processor/defaults.d.ts +0 -30
  72. package/dist/processor/defaults.js +0 -72
  73. package/dist/processor/diagnostic.d.ts +0 -15
  74. package/dist/processor/diagnostic.js +0 -104
  75. package/dist/processor/diff.d.ts +0 -30
  76. package/dist/processor/diff.js +0 -140
  77. package/dist/processor/error.d.ts +0 -23
  78. package/dist/processor/error.js +0 -95
  79. package/dist/processor/hash.d.ts +0 -10
  80. package/dist/processor/hash.js +0 -65
  81. package/dist/processor/hook.d.ts +0 -44
  82. package/dist/processor/hook.js +0 -206
  83. package/dist/processor/hot-incremental.d.ts +0 -14
  84. package/dist/processor/hot-incremental.js +0 -43
  85. package/dist/processor/hot-step.d.ts +0 -18
  86. package/dist/processor/hot-step.js +0 -307
  87. package/dist/processor/hot.d.ts +0 -17
  88. package/dist/processor/hot.js +0 -147
  89. package/dist/processor/index.d.ts +0 -20
  90. package/dist/processor/index.js +0 -36
  91. package/dist/processor/multi.d.ts +0 -17
  92. package/dist/processor/multi.js +0 -73
  93. package/dist/processor/normal.d.ts +0 -12
  94. package/dist/processor/normal.js +0 -170
  95. package/dist/processor/simple.d.ts +0 -24
  96. package/dist/processor/simple.js +0 -51
  97. package/dist/processor/snapshot.d.ts +0 -12
  98. package/dist/processor/snapshot.js +0 -66
  99. package/dist/processor/stats-api.d.ts +0 -18
  100. package/dist/processor/stats-api.js +0 -48
  101. package/dist/processor/stats.d.ts +0 -18
  102. package/dist/processor/stats.js +0 -206
  103. package/dist/processor/treeshaking.d.ts +0 -10
  104. package/dist/processor/treeshaking.js +0 -33
  105. package/dist/processor/watch.d.ts +0 -30
  106. package/dist/processor/watch.js +0 -252
  107. package/dist/runner/basic.d.ts +0 -10
  108. package/dist/runner/basic.js +0 -64
  109. package/dist/runner/cache.d.ts +0 -5
  110. package/dist/runner/cache.js +0 -92
  111. package/dist/runner/hot.d.ts +0 -5
  112. package/dist/runner/hot.js +0 -91
  113. package/dist/runner/multiple.d.ts +0 -11
  114. package/dist/runner/multiple.js +0 -52
  115. package/dist/runner/runner/index.d.ts +0 -2
  116. package/dist/runner/runner/index.js +0 -18
  117. package/dist/runner/type.d.ts +0 -42
  118. package/dist/runner/type.js +0 -9
  119. package/dist/runner/watch.d.ts +0 -7
  120. package/dist/runner/watch.js +0 -71
  121. package/dist/test/simple.d.ts +0 -5
  122. package/dist/test/simple.js +0 -43
@@ -1,11 +1,311 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.createHotStepCase = createHotStepCase;
4
- const hot_step_1 = require("../processor/hot-step");
5
- const runner_1 = require("../runner");
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const helper_1 = require("../helper");
10
+ const placeholder_1 = require("../helper/expect/placeholder");
6
11
  const creator_1 = require("../test/creator");
7
12
  const type_1 = require("../type");
13
+ const common_1 = require("./common");
14
+ const hot_1 = require("./hot");
15
+ const NOOP_SET = new Set();
16
+ const escapeLocalName = (str) => str.split(/[-<>:"/|?*.]/).join("_");
17
+ const SELF_HANDLER = (file, options) => {
18
+ let res = [];
19
+ const hotUpdateGlobal = (_, modules) => {
20
+ res = Object.keys(modules);
21
+ };
22
+ const hotUpdateGlobalKey = escapeLocalName(`${options.output?.hotUpdateGlobal || "webpackHotUpdate"}${options.output?.uniqueName || ""}`);
23
+ global.self ??= {};
24
+ global.self[hotUpdateGlobalKey] = hotUpdateGlobal;
25
+ require(file);
26
+ delete global.self[hotUpdateGlobalKey];
27
+ if (!Object.keys(global.self).length) {
28
+ delete global.self;
29
+ }
30
+ return res;
31
+ };
32
+ const NODE_HANDLER = (file) => {
33
+ return Object.keys(require(file).modules) || [];
34
+ };
35
+ const GET_MODULE_HANDLER = {
36
+ web: SELF_HANDLER,
37
+ webworker: SELF_HANDLER,
38
+ "async-node": NODE_HANDLER,
39
+ node: NODE_HANDLER
40
+ };
8
41
  const creators = new Map();
42
+ function createHotStepProcessor(name, target) {
43
+ const processor = (0, hot_1.createHotProcessor)(name, target);
44
+ const entries = {};
45
+ const hashes = [];
46
+ function matchStepSnapshot(env, context, step, options, stats, runtime) {
47
+ const getModuleHandler = GET_MODULE_HANDLER[options.target];
48
+ env.expect(typeof getModuleHandler).toBe("function");
49
+ const lastHash = hashes[hashes.length - 1];
50
+ const snapshotPath = context.getSource(`__snapshots__/${options.target}/${step}.snap.txt`);
51
+ const title = `Case ${node_path_1.default.basename(name)}: Step ${step}`;
52
+ const hotUpdateFile = [];
53
+ const hotUpdateManifest = [];
54
+ const changedFiles = step === 0
55
+ ? []
56
+ : processor.hotUpdateContext.changedFiles.map((i) => (0, helper_1.escapeSep)(node_path_1.default.relative(context.getSource(), i)));
57
+ changedFiles.sort();
58
+ const resultHashes = {
59
+ [lastHash || "LAST_HASH"]: "LAST_HASH",
60
+ [stats.hash]: "CURRENT_HASH"
61
+ };
62
+ // TODO: find a better way
63
+ // replace [runtime] to [runtime of id] to prevent worker hash
64
+ const runtimes = {};
65
+ for (const [id, runtime] of Object.entries(entries)) {
66
+ if (typeof runtime === "string") {
67
+ if (runtime !== id) {
68
+ runtimes[runtime] = `[runtime of ${id}]`;
69
+ }
70
+ }
71
+ else if (Array.isArray(runtime)) {
72
+ for (const r of runtime) {
73
+ if (r !== id) {
74
+ runtimes[r] = `[runtime of ${id}]`;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ const replaceContent = (rawStr) => {
80
+ let str = rawStr;
81
+ const replaceContentConfig = context.getTestConfig().snapshotContent;
82
+ if (replaceContentConfig) {
83
+ str = replaceContentConfig(str);
84
+ }
85
+ return (0, placeholder_1.normalizePlaceholder)(Object.entries(resultHashes)
86
+ .reduce((str, [raw, replacement]) => {
87
+ return str.split(raw).join(replacement);
88
+ }, str)
89
+ .replace(/\/\/ (\d+)\s+(?=var cssReload)/, "")
90
+ .replaceAll(/var data = "(?:.*)"/g, match => {
91
+ return decodeURIComponent(match).replaceAll(/\\/g, "/");
92
+ }));
93
+ };
94
+ const replaceFileName = (str) => {
95
+ return Object.entries({
96
+ ...resultHashes,
97
+ ...runtimes
98
+ }).reduce((str, [raw, replacement]) => {
99
+ return str.split(raw).join(replacement);
100
+ }, str);
101
+ };
102
+ const fileList = stats
103
+ .assets.map(i => {
104
+ const fileName = i.name;
105
+ const renderName = replaceFileName(fileName);
106
+ const content = replaceContent(fs_extra_1.default.readFileSync(context.getDist(fileName), "utf-8"));
107
+ if (fileName.endsWith("hot-update.js")) {
108
+ const modules = getModuleHandler(context.getDist(fileName), options);
109
+ const runtime = [];
110
+ for (const i of content.matchAll(/\/\/ (webpack\/runtime\/[\w_-]+)\s*\n/g)) {
111
+ runtime.push(i[1]);
112
+ }
113
+ modules.sort();
114
+ runtime.sort();
115
+ hotUpdateFile.push({
116
+ name: renderName,
117
+ content,
118
+ modules,
119
+ runtime
120
+ });
121
+ return `- Update: ${renderName}, size: ${content.length}`;
122
+ }
123
+ if (fileName.endsWith("hot-update.json")) {
124
+ const manifest = JSON.parse(content);
125
+ manifest.c?.sort();
126
+ manifest.r?.sort();
127
+ manifest.m?.sort();
128
+ hotUpdateManifest.push({
129
+ name: renderName,
130
+ content: JSON.stringify(manifest)
131
+ });
132
+ return `- Manifest: ${renderName}, size: ${i.size}`;
133
+ }
134
+ if (fileName.endsWith(".js")) {
135
+ return `- Bundle: ${renderName}`;
136
+ }
137
+ })
138
+ .filter(Boolean);
139
+ fileList.sort();
140
+ hotUpdateManifest.sort((a, b) => (a.name > b.name ? 1 : -1));
141
+ hotUpdateFile.sort((a, b) => (a.name > b.name ? 1 : -1));
142
+ if (runtime?.javascript) {
143
+ runtime.javascript.outdatedModules.sort();
144
+ runtime.javascript.updatedModules.sort();
145
+ runtime.javascript.updatedRuntime.sort();
146
+ runtime.javascript.acceptedModules.sort();
147
+ runtime.javascript.disposedModules.sort();
148
+ for (const value of Object.values(runtime.javascript.outdatedDependencies)) {
149
+ value.sort();
150
+ }
151
+ }
152
+ const content = `
153
+ # ${title}
154
+
155
+ ## Changed Files
156
+ ${changedFiles.map(i => `- ${i}`).join("\n")}
157
+
158
+ ## Asset Files
159
+ ${fileList.join("\n")}
160
+
161
+ ## Manifest
162
+ ${hotUpdateManifest
163
+ .map(i => `
164
+ ### ${i.name}
165
+
166
+ \`\`\`json
167
+ ${i.content}
168
+ \`\`\`
169
+ `)
170
+ .join("\n\n")}
171
+
172
+ ## Update
173
+
174
+ ${hotUpdateFile
175
+ .map(i => `
176
+ ### ${i.name}
177
+
178
+ #### Changed Modules
179
+ ${i.modules.map(i => `- ${i}`).join("\n")}
180
+
181
+ #### Changed Runtime Modules
182
+ ${i.runtime.map(i => `- ${i}`).join("\n")}
183
+
184
+ #### Changed Content
185
+ \`\`\`js
186
+ ${i.content}
187
+ \`\`\`
188
+ `)
189
+ .join("\n\n")}
190
+
191
+
192
+ ${runtime
193
+ ? `
194
+ ## Runtime
195
+ ### Status
196
+
197
+ \`\`\`txt
198
+ ${runtime.statusPath.join(" => ")}
199
+ \`\`\`
200
+
201
+ ${runtime.javascript
202
+ ? `
203
+
204
+ ### JavaScript
205
+
206
+ #### Outdated
207
+
208
+ Outdated Modules:
209
+ ${runtime.javascript.outdatedModules.map(i => `- ${i}`).join("\n")}
210
+
211
+
212
+ Outdated Dependencies:
213
+ \`\`\`json
214
+ ${JSON.stringify(runtime.javascript.outdatedDependencies || {}, null, 2)}
215
+ \`\`\`
216
+
217
+ #### Updated
218
+
219
+ Updated Modules:
220
+ ${runtime.javascript.updatedModules.map(i => `- ${i}`).join("\n")}
221
+
222
+ Updated Runtime:
223
+ ${runtime.javascript.updatedRuntime.map(i => `- \`${i}\``).join("\n")}
224
+
225
+
226
+ #### Callback
227
+
228
+ Accepted Callback:
229
+ ${runtime.javascript.acceptedModules.map(i => `- ${i}`).join("\n")}
230
+
231
+ Disposed Callback:
232
+ ${runtime.javascript.disposedModules.map(i => `- ${i}`).join("\n")}
233
+ `
234
+ : ""}
235
+
236
+ `
237
+ : ""}
238
+
239
+ `
240
+ .replaceAll(/%3A(\d+)%2F/g, (match, capture) => {
241
+ return match.replace(capture, "PORT");
242
+ })
243
+ .trim();
244
+ env.expect(content).toMatchFileSnapshot(snapshotPath);
245
+ }
246
+ const originRun = processor.run;
247
+ processor.run = async function (env, context) {
248
+ context.setValue(name, "hotUpdateStepChecker", (hotUpdateContext, stats, runtime) => {
249
+ const statsJson = stats.toJson({
250
+ assets: true,
251
+ chunks: true
252
+ });
253
+ const chunks = Array.from(
254
+ // Some chunk fields are missing from rspack
255
+ stats?.compilation.chunks || NOOP_SET);
256
+ for (const entry of chunks.filter(i => i.hasRuntime())) {
257
+ if (!entries[entry.id] && entry.runtime) {
258
+ entries[entry.id] =
259
+ // Webpack uses `string | SortableSet<string>` for `entry.runtime`
260
+ typeof entry.runtime === "string"
261
+ ? [entry.runtime]
262
+ : Array.from(entry.runtime);
263
+ }
264
+ }
265
+ const compiler = context.getCompiler(name, type_1.ECompilerType.Rspack);
266
+ const compilerOptions = compiler.getOptions();
267
+ matchStepSnapshot(env, context, hotUpdateContext.updateIndex, compilerOptions, statsJson, runtime);
268
+ hashes.push(stats.hash);
269
+ });
270
+ context.setValue(name, "hotUpdateStepErrorChecker", (_, stats, runtime) => {
271
+ hashes.push(stats.hash);
272
+ });
273
+ await originRun(env, context);
274
+ };
275
+ processor.check = async function (env, context) {
276
+ const compiler = (0, common_1.getCompiler)(context, name);
277
+ const stats = compiler.getStats();
278
+ if (!stats || !stats.hash) {
279
+ env.expect(false);
280
+ return;
281
+ }
282
+ const statsJson = stats.toJson({ assets: true, chunks: true });
283
+ const chunks = Array.from(
284
+ // Some chunk fields are missing from rspack
285
+ stats?.compilation.chunks || NOOP_SET);
286
+ for (const entry of chunks.filter(i => i.hasRuntime())) {
287
+ if (entry.runtime) {
288
+ entries[entry.id] =
289
+ // Webpack uses `string | SortableSet<string>` for `entry.runtime`
290
+ typeof entry.runtime === "string"
291
+ ? [entry.runtime]
292
+ : Array.from(entry.runtime);
293
+ }
294
+ }
295
+ let matchFailed = null;
296
+ try {
297
+ matchStepSnapshot(env, context, 0, compiler.getOptions(), statsJson);
298
+ }
299
+ catch (e) {
300
+ matchFailed = e;
301
+ }
302
+ hashes.push(stats.hash);
303
+ if (matchFailed) {
304
+ throw matchFailed;
305
+ }
306
+ };
307
+ return processor;
308
+ }
9
309
  function getCreator(target) {
10
310
  if (!creators.has(target)) {
11
311
  creators.set(target, new creator_1.BasicCaseCreator({
@@ -13,14 +313,12 @@ function getCreator(target) {
13
313
  describe: false,
14
314
  target,
15
315
  steps: ({ name, target }) => [
16
- new hot_step_1.HotSnapshotProcessor({
17
- name,
18
- target: target,
19
- compilerType: type_1.ECompilerType.Rspack,
20
- configFiles: ["rspack.config.js", "webpack.config.js"]
21
- })
316
+ createHotStepProcessor(name, target)
22
317
  ],
23
- runner: runner_1.HotRunnerFactory,
318
+ runner: {
319
+ key: (context, name, file) => name,
320
+ runner: hot_1.createHotRunner
321
+ },
24
322
  concurrent: true
25
323
  }));
26
324
  }
@@ -1,2 +1,9 @@
1
- import { ECompilerType, type TCompilerOptions } from "../type";
1
+ import { type ECompilerType, type ITestContext, type ITestEnv, type ITestProcessor, type ITestRunner, type TCompilerOptions, type THotUpdateContext } from "../type";
2
+ type TTarget = TCompilerOptions<ECompilerType.Rspack>["target"];
3
+ export declare function createHotProcessor(name: string, target: TTarget, incremental?: boolean): THotProcessor;
2
4
  export declare function createHotCase(name: string, src: string, dist: string, target: TCompilerOptions<ECompilerType.Rspack>["target"]): void;
5
+ type THotProcessor = ITestProcessor & {
6
+ hotUpdateContext: THotUpdateContext;
7
+ };
8
+ export declare function createHotRunner<T extends ECompilerType = ECompilerType.Rspack>(context: ITestContext, name: string, file: string, env: ITestEnv): ITestRunner;
9
+ export {};
package/dist/case/hot.js CHANGED
@@ -1,11 +1,66 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createHotProcessor = createHotProcessor;
3
7
  exports.createHotCase = createHotCase;
4
- const hot_1 = require("../processor/hot");
8
+ exports.createHotRunner = createHotRunner;
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const core_1 = __importDefault(require("@rspack/core"));
11
+ const helper_1 = require("../helper");
12
+ const checkArrayExpectation_1 = __importDefault(require("../helper/legacy/checkArrayExpectation"));
13
+ const plugins_1 = require("../helper/plugins");
14
+ const plugin_1 = require("../plugin");
5
15
  const runner_1 = require("../runner");
6
16
  const creator_1 = require("../test/creator");
7
17
  const type_1 = require("../type");
18
+ const common_1 = require("./common");
19
+ const runner_2 = require("./runner");
8
20
  const creators = new Map();
21
+ function createHotProcessor(name, target, incremental = false) {
22
+ const hotUpdateContext = {
23
+ updateIndex: 0,
24
+ totalUpdates: 1,
25
+ changedFiles: []
26
+ };
27
+ const processor = {
28
+ config: async (context) => {
29
+ const compiler = (0, common_1.getCompiler)(context, name);
30
+ let options = defaultOptions(context, target, hotUpdateContext);
31
+ options = await (0, common_1.config)(context, name, ["rspack.config.js", "webpack.config.js"], options);
32
+ overrideOptions(context, options, target, hotUpdateContext);
33
+ if (incremental) {
34
+ options.experiments ??= {};
35
+ options.experiments.incremental ??= "advance-silent";
36
+ }
37
+ compiler.setOptions(options);
38
+ },
39
+ compiler: async (context) => {
40
+ await (0, common_1.compiler)(context, name);
41
+ },
42
+ build: async (context) => {
43
+ await (0, common_1.build)(context, name);
44
+ },
45
+ run: async (env, context) => {
46
+ context.setValue(name, "hotUpdateContext", hotUpdateContext);
47
+ await (0, common_1.run)(env, context, name, context => findBundle(context, name, target, hotUpdateContext));
48
+ },
49
+ check: async (env, context) => {
50
+ await (0, common_1.check)(env, context, name);
51
+ },
52
+ afterAll: async (context) => {
53
+ if (context.getTestConfig().checkSteps === false) {
54
+ return;
55
+ }
56
+ if (hotUpdateContext.updateIndex + 1 !== hotUpdateContext.totalUpdates) {
57
+ throw new Error(`Should run all hot steps (${hotUpdateContext.updateIndex + 1} / ${hotUpdateContext.totalUpdates}): ${name}`);
58
+ }
59
+ }
60
+ };
61
+ processor.hotUpdateContext = hotUpdateContext;
62
+ return processor;
63
+ }
9
64
  function getCreator(target) {
10
65
  if (!creators.has(target)) {
11
66
  creators.set(target, new creator_1.BasicCaseCreator({
@@ -13,14 +68,12 @@ function getCreator(target) {
13
68
  describe: true,
14
69
  target,
15
70
  steps: ({ name, target }) => [
16
- new hot_1.HotProcessor({
17
- name,
18
- target: target,
19
- compilerType: type_1.ECompilerType.Rspack,
20
- configFiles: ["rspack.config.js", "webpack.config.js"]
21
- })
71
+ createHotProcessor(name, target)
22
72
  ],
23
- runner: runner_1.HotRunnerFactory,
73
+ runner: {
74
+ key: (context, name, file) => name,
75
+ runner: createHotRunner
76
+ },
24
77
  concurrent: true
25
78
  }));
26
79
  }
@@ -30,3 +83,177 @@ function createHotCase(name, src, dist, target) {
30
83
  const creator = getCreator(target);
31
84
  creator.create(name, src, dist);
32
85
  }
86
+ function defaultOptions(context, target, updateOptions) {
87
+ const options = {
88
+ context: context.getSource(),
89
+ mode: "development",
90
+ devtool: false,
91
+ output: {
92
+ path: context.getDist(),
93
+ filename: "bundle.js",
94
+ chunkFilename: "[name].chunk.[fullhash].js",
95
+ publicPath: "https://test.cases/path/",
96
+ library: { type: "commonjs2" }
97
+ },
98
+ optimization: {
99
+ moduleIds: "named"
100
+ },
101
+ target,
102
+ experiments: {
103
+ css: true,
104
+ // test incremental: "safe" here, we test default incremental in Incremental-*.test.js
105
+ incremental: "safe",
106
+ rspackFuture: {
107
+ bundlerInfo: {
108
+ force: false
109
+ }
110
+ },
111
+ inlineConst: true,
112
+ lazyBarrel: true
113
+ }
114
+ };
115
+ options.plugins ??= [];
116
+ options.plugins.push(new core_1.default.HotModuleReplacementPlugin(), new plugins_1.TestHotUpdatePlugin(updateOptions));
117
+ return options;
118
+ }
119
+ function overrideOptions(context, options, target, updateOptions) {
120
+ if (!options.entry) {
121
+ options.entry = "./index.js";
122
+ }
123
+ options.module ??= {};
124
+ for (const cssModuleType of ["css/auto", "css/module", "css"]) {
125
+ options.module.generator ??= {};
126
+ options.module.generator[cssModuleType] ??= {};
127
+ options.module.generator[cssModuleType].exportsOnly ??=
128
+ target === "async-node";
129
+ }
130
+ options.module.rules ??= [];
131
+ options.module.rules.push({
132
+ use: [
133
+ {
134
+ loader: node_path_1.default.resolve(__dirname, "../helper/loaders/hot-update.js"),
135
+ options: updateOptions
136
+ }
137
+ ],
138
+ enforce: "pre"
139
+ });
140
+ options.plugins ??= [];
141
+ options.plugins.push(new core_1.default.LoaderOptionsPlugin(updateOptions));
142
+ if (!global.printLogger) {
143
+ options.infrastructureLogging = {
144
+ level: "error"
145
+ };
146
+ }
147
+ if (options.lazyCompilation) {
148
+ options.plugins.push(new plugin_1.LazyCompilationTestPlugin());
149
+ }
150
+ }
151
+ function findBundle(context, name, target, updateOptions) {
152
+ const compiler = context.getCompiler(name);
153
+ if (!compiler)
154
+ throw new Error("Compiler should exists when find bundle");
155
+ const testConfig = context.getTestConfig();
156
+ if (typeof testConfig.findBundle === "function") {
157
+ return testConfig.findBundle(updateOptions.updateIndex, compiler.getOptions());
158
+ }
159
+ const files = [];
160
+ const prefiles = [];
161
+ const stats = compiler.getStats();
162
+ if (!stats)
163
+ throw new Error("Stats should exists when find bundle");
164
+ const info = stats.toJson({ all: false, entrypoints: true });
165
+ if (target === "web" || target === "webworker") {
166
+ for (const file of info.entrypoints.main.assets) {
167
+ if ((0, helper_1.isJavaScript)(file.name)) {
168
+ files.push(file.name);
169
+ }
170
+ else {
171
+ prefiles.push(file.name);
172
+ }
173
+ }
174
+ }
175
+ else {
176
+ const assets = info.entrypoints.main.assets.filter(s => (0, helper_1.isJavaScript)(s.name));
177
+ files.push(assets[assets.length - 1].name);
178
+ }
179
+ return [...prefiles, ...files];
180
+ }
181
+ function createHotRunner(context, name, file, env) {
182
+ const compiler = context.getCompiler(name);
183
+ const compilerOptions = compiler.getOptions();
184
+ const testConfig = context.getTestConfig();
185
+ const source = context.getSource();
186
+ const dist = context.getDist();
187
+ const hotUpdateContext = context.getValue(name, "hotUpdateContext");
188
+ const next = async (callback) => {
189
+ const usePromise = typeof callback === "function";
190
+ try {
191
+ hotUpdateContext.updateIndex++;
192
+ const stats = await compiler.build();
193
+ if (!stats) {
194
+ throw new Error("Should generate stats during build");
195
+ }
196
+ const jsonStats = stats.toJson({
197
+ // errorDetails: true
198
+ });
199
+ const compilerOptions = compiler.getOptions();
200
+ const checker = context.getValue(name, jsonStats.errors?.length
201
+ ? "hotUpdateStepErrorChecker"
202
+ : "hotUpdateStepChecker");
203
+ if (checker) {
204
+ checker(hotUpdateContext, stats, runner.getGlobal("__HMR_UPDATED_RUNTIME__"));
205
+ }
206
+ await (0, checkArrayExpectation_1.default)(source, jsonStats, "error", `errors${hotUpdateContext.updateIndex}`, "Error", compilerOptions);
207
+ await (0, checkArrayExpectation_1.default)(source, jsonStats, "warning", `warnings${hotUpdateContext.updateIndex}`, "Warning", compilerOptions);
208
+ if (usePromise) {
209
+ // old callback style hmr cases
210
+ callback(null, jsonStats);
211
+ }
212
+ else {
213
+ // new promise style hmr cases
214
+ return jsonStats;
215
+ }
216
+ }
217
+ catch (e) {
218
+ if (usePromise) {
219
+ callback(e);
220
+ }
221
+ else {
222
+ throw e;
223
+ }
224
+ }
225
+ };
226
+ const nextHMR = async (m, options) => {
227
+ const jsonStats = await next();
228
+ const updatedModules = await m.hot.check(options || true);
229
+ if (!updatedModules) {
230
+ throw new Error("No update available");
231
+ }
232
+ return jsonStats;
233
+ };
234
+ const runner = new runner_1.WebRunner({
235
+ dom: context.getValue(name, "documentType") || type_1.EDocumentType.JSDOM,
236
+ env,
237
+ stats: (0, runner_2.cachedStats)(context, name),
238
+ name: name,
239
+ runInNewContext: false,
240
+ testConfig: {
241
+ documentType: testConfig.documentType || type_1.EDocumentType.Fake,
242
+ ...testConfig,
243
+ moduleScope(ms, stats, options) {
244
+ const moduleScope = ms;
245
+ if (typeof testConfig.moduleScope === "function") {
246
+ testConfig.moduleScope(moduleScope, stats, compilerOptions);
247
+ }
248
+ moduleScope.NEXT = next;
249
+ moduleScope.NEXT_HMR = nextHMR;
250
+ return moduleScope;
251
+ }
252
+ },
253
+ cachable: true,
254
+ source,
255
+ dist,
256
+ compilerOptions
257
+ });
258
+ return runner;
259
+ }
@@ -1,4 +1,4 @@
1
- import { ECompilerType, type TCompilerOptions } from "../type";
1
+ import { type ECompilerType, type TCompilerOptions } from "../type";
2
2
  export declare function createHotIncrementalCase(name: string, src: string, dist: string, target: TCompilerOptions<ECompilerType.Rspack>["target"], webpackCases: boolean): void;
3
3
  export type WatchIncrementalOptions = {
4
4
  ignoreNotFriendlyForIncrementalWarnings?: boolean;