Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

virtual file system is broken in v6 #18223

Open
7 tasks done
himself65 opened this issue Sep 28, 2024 · 11 comments · May be fixed by #18361
Open
7 tasks done

virtual file system is broken in v6 #18223

himself65 opened this issue Sep 28, 2024 · 11 comments · May be fixed by #18361
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)

Comments

@himself65
Copy link

Describe the bug

import { createServer } from 'vite'

const server = await createServer({
  plugins: [
    {
      name: 'virtual-fs',
      resolveId (id) {
        if (id === 'my-virtual-file') {
          return id + '.js'
        }
      },
      load (id) {
        if (id === 'my-virtual-file.js') {
          return 'export default "Hello, world!"'
        }
      }
    }
  ]
})

console.log(await server.ssrLoadModule('my-virtual-file.js'))

await server.close()

This is working in v5, but broken in v6.

Reproduction

https://stackblitz.com/edit/stackblitz-starters-prwdrf?file=index.js

Steps to reproduce

No response

System Info

N/A

Used Package Manager

npm

Logs

No response

Validations

Copy link

stackblitz bot commented Sep 28, 2024

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Sep 29, 2024

I suppose minimal repro is just load hook:

import { createServer } from 'vite';

const server = await createServer({
  plugins: [
    {
      name: 'virtual-fs',
      load(id) {
        if (id === 'my-virtual-file.js') {
          return 'export default "Hello, world!"';
        }
      },
    },
  ],
});

console.log(await server.ssrLoadModule('my-virtual-file.js'));

On v5 https://stackblitz.com/edit/stackblitz-starters-cr4to5?file=index.js

{ default: 'Hello, world!', [Symbol(Symbol.toStringTag)]: 'Module' }

On v6 https://stackblitz.com/edit/stackblitz-starters-asgtkf?file=index.js

Error: [vite] cannot find entry point module 'my-virtual-file.js'.
    at async ModuleLoader.import (https://stackblitzstartersasgtkf-wdbx.w-credentialless-staticblitz.com/builtins.ddb8d84d.js:154:2688)

@sheremet-va
Copy link
Member

sheremet-va commented Oct 3, 2024

I don't see why this even worked before, to be honest. The my-virtual-file.js in the reproduction is the resolved ID, not the user ID that would be used in an import. For example, this fails in Vite 5 and Vite 6:

import 'my-virtual-file.js'

Reproduction: https://stackblitz.com/edit/stackblitz-starters-a9fxsa?file=actual-fs.js,index.js

This however works as intended (if you provide resolveId hook like in the reproduction):

import 'my-virtual-file'

I'd say making the entry point work the same way as the import is a bug fix.

@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Oct 5, 2024

Interesting, Vite 6's behavior looks legitimate to me.

@himself65 Do you have any reason to do server.ssrLoadModule('my-virtual-file.js') instead of server.ssrLoadModule('my-virtual-file'). It looks like a simply typo to me and I don't think this change would be a blocker anyways, so I'll close this issue for now.

@hi-ogawa hi-ogawa closed this as completed Oct 5, 2024
@himself65
Copy link
Author

yes, in waku we build on top of vite, and we have a file import , when user not provided we will make a fake one. So in this case we wanna ts/js/tsx

@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Oct 6, 2024

yes, in waku we build on top of vite, and we have a file import , when user not provided we will make a fake one. So in this case we wanna ts/js/tsx

@himself65 Are you saying Vite 5 behavior is required for your use case? I cannot tell from your initial reproduction, so it would be great if you can elaborate it further. Maybe this plugin? https://github.com/dai-shi/waku/blob/711be51c02eac6a767fe5651fae6d6417d0679f8/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts#L40

@himself65
Copy link
Author

yes

@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Oct 6, 2024

Probably your reproduction was misleading and the issue might be more like this scenario:

ssrLoadModule("/abs-path-to/entries")
plugin.resolveId: "/abs-path-to/entries" --> "/abs-path-to/entries.jsx"
plugin.load:      "/abs-path-to/entries.jsx" --> ...virtual content...

On Vite 6, resolveId is called differently and maybe that's causing an issue.

 node index.js
[resolveId] { id: '/home/projects/stackblitz-starters-prwdrf/entries' }
{ default: 'Hello, world!', [Symbol(Symbol.toStringTag)]: 'Module' }
 node index.js
[resolveId] { id: '/home/projects/stackblitz-starters-prwdrf/entries' }
[resolveId] { id: '/entries' }
5:52:39 PM [vite] (ssr) Error when evaluating SSR module /home/projects/stackblitz-starters-prwdrf/entries:
|- Error: [vite] cannot find entry point module '/entries'.
    at fetchModule (file:///home/projects/stackblitz-starters-prwdrf/node_modules/vite/dist/node/chunks/dep-BHXIdTzn.js:66013:13)

This seems like an odd case, but not sure. Let me re-open the issue for now.

@hi-ogawa hi-ogawa reopened this Oct 6, 2024
@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Oct 7, 2024

@himself65 I haven't look into the issue, but I would probably try this to provide "optionally virtual entry" from plugin: https://stackblitz.com/edit/stackblitz-starters-t9hvyx?file=index.js

@himself65
Copy link
Author

im not sure the best practice here, entries file is possible to be virtual or real file. I feel the logic is broken after we add virtual: as prefix

@hi-ogawa
Copy link
Collaborator

@himself65 Other than switching to virtual:, you might be able to workaround by removing root from entries https://github.com/dai-shi/waku/blob/711be51c02eac6a767fe5651fae6d6417d0679f8/packages/waku/src/lib/plugins/vite-plugin-rsc-managed.ts#L55-L56 (for example, use /src/entries instead of /abs-path-to/src/entries).

The issue (on Vite, fair to say) is that it stripes root as a part of normalization here, so your plugin's resolveId doesn't consistently see root.

url = normalizeAbsoluteUrl(url, this.root)

@hi-ogawa hi-ogawa added p2-edge-case Bug, but has workaround or limited in scope (priority) and removed pending triage labels Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants