Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions e2e/wasm/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { expect, test } from '@rstest/core';

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (macos-14, 22)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A length overflow while decoding section length @+13

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (windows-latest, 18)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A expected section length @+13

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (macos-14, 20)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A expected section length @+13

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (windows-latest, 20)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A expected section length @+13

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (windows-latest, 22)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A length overflow while decoding section length @+13

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (macos-14, 24)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A length overflow while decoding section length @+13

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (windows-latest, 24)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A length overflow while decoding section length @+13

Check failure on line 1 in e2e/wasm/index.test.ts

View workflow job for this annotation

GitHub Actions / e2e (macos-14, 18)

wasm/index.test.ts > WASM factorial

WebAssembly.instantiate()%3A expected section length @+13

test('WASM factorial', async () => {
const { _Z4facti: AsyncFactorial } = await import('./src/factorial.wasm');

expect(AsyncFactorial(1)).toBe(1);
expect(AsyncFactorial(2)).toBe(2);
expect(AsyncFactorial(3)).toBe(6);
});
Binary file added e2e/wasm/src/factorial.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions e2e/wasm/src/factorial.wasm.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export function _Z4facti(n: number): number;
2 changes: 1 addition & 1 deletion packages/core/src/core/plugins/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const autoExternalNodeModules: (
return callback();
}

if (request.startsWith('@swc/helpers/')) {
if (request.startsWith('@swc/helpers/') || request.endsWith('.wasm')) {
// @swc/helper is a special case (Load by require but resolve to esm)
return callback();
}
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/core/plugins/mockRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ class MockRuntimeRspackPlugin {

module.source!.source = Buffer.from(finalSource);
}

if (module.name === 'async_wasm_loading') {
const finalSource = module.source!.source.toString('utf-8').replace(
// Sets the object configurable so that imported properties can be spied
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment 'Sets the object configurable so that imported properties can be spied' is misleading. This replacement changes readFile( to readWasmFile( to use the custom WASM file loader, not to set object configurability. The comment should be updated to reflect the actual purpose of this transformation.

Suggested change
// Sets the object configurable so that imported properties can be spied
// Replace readFile with readWasmFile to use the custom WASM file loader
Copilot uses AI. Check for mistakes.
// Hard coded in EJS template https://github.com/web-infra-dev/rspack/tree/7df875eb3ca3bb4bcb21836fdf4e6be1f38a057c/crates/rspack_plugin_wasm/src/runtime
'readFile(',
'readWasmFile(',
);

module.source!.source = Buffer.from(finalSource);
}
},
);
});
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/runtime/worker/loadModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ export const loadModule = ({
assetFiles,
interopDefault,
),
readWasmFile: (
wasmPath: string,
callback: (err: Error | null, data?: Buffer) => void,
) => {
const joinedPath = isRelativePath(wasmPath)
? path.join(path.dirname(distPath), wasmPath)
: wasmPath;
const content = assetFiles[path.normalize(joinedPath)];
if (content) {
callback(null, Buffer.from(content, 'utf-8'));
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WASM files are binary data, not UTF-8 text. Using Buffer.from(content, 'utf-8') will corrupt the binary data. The assetFiles dictionary stores file contents as strings, so they should be decoded using base64 encoding (e.g., Buffer.from(content, 'base64')) or the content should be stored and retrieved as binary data without text encoding.

Suggested change
callback(null, Buffer.from(content, 'utf-8'));
callback(null, Buffer.from(content, 'base64'));
Copilot uses AI. Check for mistakes.
} else {
callback(
new Error(`WASM file ${joinedPath} not found in asset files.`),
);
}
},
__rstest_dynamic_import__: defineRstestDynamicImport({
testPath,
interopDefault,
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/utils/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ export async function printError(
fullStack: error.fullStack,
getSourcemap,
});

if (!stackFrames.length && error.stack.length) {
if (
!stackFrames.length &&
Array.isArray(error.stack) &&
error.stack.length
) {
Comment on lines +70 to +74
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Array.isArray(error.stack) check is incorrect. According to the FormattedError type definition, error.stack is typed as string | undefined, not an array. This check will always be false. The condition should simply check if error.stack is a non-empty string.

Suggested change
if (
!stackFrames.length &&
Array.isArray(error.stack) &&
error.stack.length
) {
if (!stackFrames.length) {
Copilot uses AI. Check for mistakes.
logger.log(
color.gray(
"No error stack found, set 'DEBUG=rstest' to show fullStack.",
Expand Down
Loading