Skip to content

Comments

feat(wasm): add SSR support for .wasm?init#21102

Merged
sapphi-red merged 24 commits intovitejs:mainfrom
upsuper-forks:wasm-node
Feb 9, 2026
Merged

feat(wasm): add SSR support for .wasm?init#21102
sapphi-red merged 24 commits intovitejs:mainfrom
upsuper-forks:wasm-node

Conversation

@upsuper
Copy link
Contributor

@upsuper upsuper commented Nov 10, 2025

This PR intends to add WASM support for Vitest and SSR. It should fix #8882 as well as vitest-dev/vitest#6723.

Implementation

The main changes are in the wasm plugin, that provide different helper code based on whether the consumer is server or client. As I'm new to this project, it's not clear to me whether this is the right approach.

I also looked into vite-plugin-wasm for how it handles SSR and vitest. What it does is:

  • explicitly detect whether it's under SSR or whether it's running for Vitest, and
  • if so, force inline WASM into base64 encoded form.

This approach doesn't feel great to me.

Testing

There are two tests I added:

  • A new e2e test ssr-wasm which serves SSR with WASM loaded.
  • New tests inside existing wasm e2e test that checks that WASM can be imported and run within tests.

It's not clear to me whether those tests are in the right location. Please let me know if there are better places for them.

Regarding Vitest

Checking consumer actually doesn't seem to be a reliable way to work in Vitest. Vitest's environment can specify viteEnvironment. Within its builtin environments, jsdom and happy-dom specifies client as their vite environment which, on the Vite side, uses consumer: 'client', even though the tests are still running in Node.js.

I'm going to leave it there given that Vitest's default environment is node, so this mechanism should just work most of the time, and also because I failed to find a way to add test for this behavior.

I tried adding // @vitest-environment jsdom to a spec file, but esbuild complains about

Invariant violation: "new TextEncoder().encode("") instanceof Uint8Array" is incorrectly false

which is probably because jsdom doesn't have the proper implementation for it currently. So I'm not going to dig deeper on this rabbit hole for now.

One trick I found is that some plugins like vite-plugin-solid implicitly changes the test environment, which could potentially cause confusion.

If someone wants to address this part in the future, one possible approach is from vite-plugin-wasm that goes through plugins to find vitest, then combine it with the consumer check to decide which way the file is passed and obtained. It's hacky but I can confirm it works locally.

@upsuper upsuper changed the title Add wasm support for test and SSR feat: Add wasm support for test and SSR Nov 10, 2025
@upsuper upsuper changed the title feat: Add wasm support for test and SSR feat: add wasm support for test and SSR Nov 10, 2025
Copy link
Member

@sapphi-red sapphi-red left a comment

Choose a reason for hiding this comment

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

Thanks, but this isn't working for build.
When I run vite build --ssr src/app.js in playground/ssr-wasm, I expect the wasm files to be copied (or inlined depending on the option) to dist. But that didn't happen.

@sapphi-red sapphi-red added p2-nice-to-have Not breaking anything but nice to have (priority) feat: ssr feat: wasm labels Nov 11, 2025
@upsuper upsuper requested a review from sapphi-red November 12, 2025 02:07
@upsuper
Copy link
Contributor Author

upsuper commented Nov 12, 2025

@sapphi-red Thanks for your review! I have looked into the issue, and now build should be working correctly.

The test should now be covering the build case properly as well, and I've add some tests to verify the build result. Also I have done some manual testing locally and confirmed that it works the way I'd expect.

@upsuper
Copy link
Contributor Author

upsuper commented Nov 17, 2025

Hi @sapphi-red, it has been a week since the last update of this PR, would you mind taking another look at it? Is there anything I can do to help moving it forward?

@sapphi-red

This comment was marked as outdated.

@pkg-pr-new

This comment was marked as outdated.

@vite-ecosystem-ci

This comment was marked as outdated.

@upsuper
Copy link
Contributor Author

upsuper commented Nov 25, 2025

@sapphi-red I updated the PR to handle wasm init specially via replacing the asset placeholder with a different placeholder, and replace it as part of renderChunk in this plugin. The tests continue to pass and I expect it not to affect any existing usage. Please let me know if this can still have problems.

@sapphi-red sapphi-red moved this from Discussing to Approved in Team Board Dec 10, 2025
Copy link
Member

@sapphi-red sapphi-red left a comment

Choose a reason for hiding this comment

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

I'll take a look soon. In the meantime, would you rebase the PR on the latest main branch? The tests may fail without the _VITE_TEST_JS_PLUGIN=1 env var, but don't worry about that.

@sapphi-red sapphi-red changed the title feat: add wasm support for test and SSR feat(wasm): add SSR support for .wasm?init Dec 12, 2025
@upsuper upsuper requested a review from sapphi-red December 12, 2025 11:21
@upsuper
Copy link
Contributor Author

upsuper commented Dec 12, 2025

The tests may fail without the _VITE_TEST_JS_PLUGIN=1 env var, but don't worry about that.

I assume that the current CI failures are from this. I checked ssr-wasm locally, and it seems to work as expected.

@sapphi-red
Copy link
Member

@upsuper Would you enable "Allow edits from maintainers" so that I and other can add changes?

@upsuper
Copy link
Contributor Author

upsuper commented Dec 16, 2025

@upsuper Would you enable "Allow edits from maintainers" so that I and other can add changes?

I'd like to, but unfortunately I can't, because this is forked under an org I use to park all my forks, and GitHub doesn't support "Allow edits from maintainers" for a repo owned by an org.

I've instead invited you as an admin of my fork project. Hope that helps.

@sapphi-red
Copy link
Member

Thanks! I was able to add the changes.

@shulaoda
Copy link
Member

shulaoda commented Feb 5, 2026

@upsuper Could you grant me access to this repository so I can make some updates?

@shulaoda
Copy link
Member

shulaoda commented Feb 5, 2026

@upsuper Could you grant me access to this repository so I can make some updates?

Thanks! I was able to add the changes.

@shulaoda shulaoda marked this pull request as draft February 5, 2026 09:08
graphite-app bot pushed a commit to rolldown/rolldown that referenced this pull request Feb 5, 2026
Related to vitejs/vite#21566

This is because vitejs/vite#21102 will refactor the logic around `wasmHelperPlugin`, and `nativeWasmHelperPlugin` is not aligned with the `fileToUrl` behavior. So I plan to remove it for now and re-port it when it’s needed again later.
@shulaoda shulaoda marked this pull request as ready for review February 6, 2026 03:19
Copy link
Member

@sapphi-red sapphi-red left a comment

Choose a reason for hiding this comment

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

Thanks for your patience 💚

@sapphi-red sapphi-red merged commit 216a3b5 into vitejs:main Feb 9, 2026
20 checks passed
@upsuper upsuper deleted the wasm-node branch February 9, 2026 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat: ssr feat: wasm p2-nice-to-have Not breaking anything but nice to have (priority) trigger: preview

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Support wasm in SSR

3 participants