Skip to content

Conversation

@katywings
Copy link
Contributor

@katywings katywings commented Dec 21, 2025

Changes

  1. Implements new css fixture test for virtual modules
  2. Fixes dev css crawling for virtual modules, by using built-in method from vite to fetch module deps
  3. Converts \0virtual:module.css to /@id/__x00__virtual:module.css in manifest, to fix dynamic import of virtual modules
  4. Patches data-vite-dev-id attributes for style tags of virtual modules

Fixes tested with

  • css fixture and nitro 2
  • css fixture and nitro 3.0.1-alpha.1
  • solidbase (nitro 2)
  • nitropage (nitro 3.0.1-alpha.1)

Other information

Before change 2+3: https://github.com/user-attachments/assets/630e827b-5241-403f-9a70-5d4ccbb0db90
After: https://github.com/user-attachments/assets/7d3af2e8-5211-4f05-b8de-9f14ef153549

Before change 4: https://github.com/user-attachments/assets/e8e59e0b-800f-42ab-b8df-f452ea8d0de7
After: https://github.com/user-attachments/assets/a19627dd-232e-41b1-b72f-f54714b5df42

@changeset-bot
Copy link

changeset-bot bot commented Dec 21, 2025

🦋 Changeset detected

Latest commit: d1a23f5

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@katywings katywings self-assigned this Dec 21, 2025
@katywings katywings added bug Something isn't working 2.x targeting SolidStart 2.x versions labels Dec 21, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 21, 2025

Open in StackBlitz

npm i https://pkg.pr.new/solidjs/solid-start/@solidjs/start@2039
npm i https://pkg.pr.new/solidjs/solid-start/@solidjs/vite-plugin-nitro-2@2039

commit: d1a23f5

@netlify
Copy link

netlify bot commented Dec 21, 2025

Deploy Preview for solid-start-landing-page ready!

Name Link
🔨 Latest commit d1a23f5
🔍 Latest deploy log https://app.netlify.com/projects/solid-start-landing-page/deploys/694856ed012fe20008a5c6bc
😎 Deploy Preview https://deploy-preview-2039--solid-start-landing-page.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@katywings katywings marked this pull request as ready for review December 21, 2025 20:23
@katywings katywings changed the title WIP: fix: server render virtual css fix: server render virtual css Dec 21, 2025
@katywings katywings changed the title fix: server render virtual css fix: collect virtual module CSS in vite dev Dec 21, 2025
try {
const res = await vite.fetchModule(file, importer);
if (!("id" in res)) return;
return vite.moduleGraph.getModuleById(res.id);
Copy link
Member

Choose a reason for hiding this comment

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

much cleaner! 🥇

but this is removing the fallback vite.fetchModuleByUrl and relying only in the moduleid- is this not needed or am I missing something else? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

relying only in the moduleid

The new line const res = await vite.fetchModule(file, importer); resolves the raw file url. But it's result doesn't include all fields from the module, that's the reason why I have to also call vite.moduleGraph.getModuleById on the later line. The logic here is:

  1. Resolve raw file url to module id via vite.fetchModule
  2. Get missing module fields via vite.moduleGraph.getModuleById

removing the fallback vite.fetchModuleByUrl

fetchModuleByUrl - is this a typo 🤔? Afaik this API does not exist, but I assume you mean getModuleByUrl / ensureEntryFromUrl?

So to "quickly" comment my thoughts about those:

Removed ensureEntryFromUrl

The new vite.fetchModule call internally already calls ensureEntryFromUrl (https://github.com/vitejs/vite/blob/964c718a382ff46ec1f906d7d6bc3f135a6dcd3f/packages/vite/src/node/ssr/fetchModule.ts#L83), so we don't have to do that manually anymore.

Removed getModuleByUrl

nodePath = resolve(nodePath);
node = await vite.moduleGraph.getModuleByUrl(file);
  • This old logic was already broken, because getModuleByUrl was called with file instead of nodePath 🙈.
  • But assuming that the old logic somehow was correct: getModuleByUrl basically is a small subset of ensureEntryFromUrl.

Removed getModuleById

  • The old logic also partially already was broken to begin with
  • But assuming that the old logic somehow was correct: ensureEntryFromUrl internally calls _resolveUrl and _resolveUrl uses _resolveId to get the id from the url.

Extra words: To be completely honest, deleting all that old logic and replacing it with the simple two lines didn't exactly feel good, especially because we do not have lot's of tests around this. I tried my best to test the new logic, but there's certainly the chance that I missed something. So there is the risk that with the new logic some unexpected cases might pop up where CSS is not server rendered during the alpha. This however gives us the opportunity to then include those cases in the CSS fixture and bring back the few actually needed parts of the old logic, if necessary. What do you think of this plan @atilafassina (and @Brendonovich)?

Copy link
Member

Choose a reason for hiding this comment

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

thanks for the explanation!!

I agree with your reasoning: removing what looks wrong/unnecessary/redundant and watching for edge cases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2.x targeting SolidStart 2.x versions bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants