Skip to content

SSR dev server "Pre-transform error: Failed to load url" for relative path #18964

@vanaigr

Description

@vanaigr

Describe the bug

transformIndexHtml() prints the following error when HTML contains a relative link to a script, and url parameter ends in slash (i.e. /example/dir/, and not /example/dir/index.html):

Pre-transform error: Failed to load url /example/filename.js (resolved id: /example/filename.js). Does the file exist?

This can occur when implementing the dev server following the SSR guide.

Cause

This happens because dirname() of the html url is taken which, for a path that ends in slash, removes the directory name. And the file is searched in the parent directory:

} else if (url[0] === '.' || isBareRelative(url)) {
preTransformUrl = path.posix.join(
config.base,
path.posix.dirname(htmlPath),
url,
)
}

When using builtin vite server, it converts urls that end in slash to absolute filesystem paths that end in index.html:

// trailing slash should check for fallback index.html
else if (pathname[pathname.length - 1] === '/') {
const filePath = path.join(root, pathname, 'index.html')
if (fs.existsSync(filePath)) {
const newUrl = url + 'index.html'
debug?.(`Rewriting ${req.method} ${req.url} to ${newUrl}`)
req.url = newUrl
return next()
}
}

but this doesn't happen for the SSR example since:

  1. It uses appType: 'custom', which disables this url preprocessing
  2. The custom handler uses req.originalUrl, which is not modified
  3. The HTML file may not exist

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-bx1fvf91?file=index.js

Steps to reproduce

  1. npm install
  2. npm run dev
  3. Observe the error message in console:
Pre-transform error: Failed to load url /example/filename.js (resolved id: /example/filename.js). Does the file exist?
  1. Ctrl+C
  2. Change /example/dir/ on line 4 to example/dir/index.html
  3. npm run dev
  4. Observe no error

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (2) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    vite: latest => 5.4.11

Used Package Manager

npm

Logs

No response

Validations

Workaround

  1. Don't use originalUrl (it breaks if base is set to some directory). Use req.url`
  2. Remove query parameters an hashes from the url, so that only the path is left
  3. If it ends in /, add index.html to it
  4. Pass this path to transformIndexHtml

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions