Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@fresh/plugin-vite: dev server fails with loader error when optimizeDeps enabled

The Deno loader plugin in @fresh/plugin-vite (src/plugins/deno.ts) passes Vite module ids to Deno's loader without removing the query string. Vite's dependency optimizer appends ?v=<hash> to dependency ids, so the loader is handed a path that does not exist and the dev server returns 500.

Enabling optimizeDeps at all is enough to trigger it on a freshly scaffolded project. Either environment does it — the repro below uses the client, and moving the same config under environments.ssr fails identically.

Versions

@fresh/core 2.3.3
@fresh/plugin-vite 1.1.2
vite 7.3.6
deno 2.9.4 (aarch64-apple-darwin)

Reproducing

./run.sh

app/ is an unmodified deno run -Ar jsr:@fresh/init@^2 scaffold. The only edit is app/vite.config.ts, which switches optimizeDeps on from an environment variable so both runs differ in nothing else:

const optimize = Deno.env.get('OPTIMIZE_DEPS') === '1'

export default defineConfig({
    plugins: [fresh()],
    ...(optimize ? { optimizeDeps: { include: ['preact'] } } : {}),
    server: { port: 8123 },
})

run.sh starts the dev server each way, clearing Vite's dependency cache first, and requests /:

without optimizeDeps: HTTP 200
with optimizeDeps   : HTTP 500
ENOENT: no such file or directory, open
  '.../preact@10.29.7/node_modules/preact/debug/dist/debug.module.js?v=ff8da874'

Expected: the page renders in both cases. Actual: with optimizeDeps the server 500s, repeatedly, for any module whose id the optimizer has versioned.

Cause

Vite identifies modules by a string that may carry a query. For a dependency the optimizer has versioned, that id is <absolute path>?v=<hash>, where the query is cache-busting metadata rather than part of the filename.

src/plugins/deno.ts passes the id straight to toFileUrl:

const url = path.toFileUrl(id);
const result = await loader.load(url.href, meta.type);

toFileUrl() treats its whole argument as a filesystem path, so ? is percent-encoded instead of being kept as a query delimiter:

/tmp/x/mod.js              →  file:///tmp/x/mod.js
/tmp/x/mod.js?v=9bd7f6e5   →  file:///tmp/x/mod.js%3Fv=9bd7f6e5

The %3F is now part of the filename, no such file exists, and the loader reports ENOENT with the query still visible in the path — which is what makes the error confusing at first sight.

repro.ts demonstrates this on its own, with no Vite or Fresh involved:

deno run -A repro.ts
id as Vite passes it WITHOUT client optimizeDeps
  load       : ok (module)

id as Vite passes it WITH client optimizeDeps (?v=<hash> appended)
  load       : FAILED: Import 'file:///.../mod.js%3Fv=9bd7f6e5' failed, not found.

same id, query stripped first (the workaround)
  load       : ok (module)

Notes

Both environments are affected. The repro enables optimizeDeps for the client. Moving it to environments.ssr produces the same failure, on the SSR build of the same module:

ENOENT: no such file or directory, open
  '.../preact/debug/dist/debug.mjs?v=ca7e3d92'

The failing module is not the one being optimized. The config above adds preact to optimizeDeps, and the error is raised for preact/debug. The optimizer versions dependency ids whether or not it pre-bundles them, so the failure lands on whichever module is versioned first. Excluding one module just moves the error to the next.

Queries are already handled, but case by case. Further down src/plugins/deno.ts:

actualId = actualId.replace("?commonjs-es-import", "")

so one known query is stripped while others are not.

Suggested fix

Strip any query before handing the id to toFileUrl, rather than matching known queries:

const filePath = id.split('?')[0];
const url = path.toFileUrl(filePath);

A plugin with enforce: 'pre' that strips the query in resolveId works as a local workaround, but it has to be applied to every environment that reaches the Deno loader.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages