Skip to content

fix(assets): allow ?raw imports of public files#22495

Open
ATOM00blue wants to merge 1 commit into
vitejs:mainfrom
ATOM00blue:fix/raw-public-import
Open

fix(assets): allow ?raw imports of public files#22495
ATOM00blue wants to merge 1 commit into
vitejs:mainfrom
ATOM00blue:fix/raw-public-import

Conversation

@ATOM00blue
Copy link
Copy Markdown

Description

Importing a non-asset file from publicDir with ?raw currently throws a hard error during import analysis:

import redirects from '/_redirects?raw'
// Error: Cannot import non-asset file /_redirects?raw which is inside /public ...

This is inconsistent: the asset plugin's load hook already knows how to read public files for ?raw requests (checkPublicFile(id, config) || cleanUrl(id)), so ?raw is a legitimate way to inline a public file's contents. The error even suggests ?url&raw as a workaround, which doesn't actually make sense (you get the raw text, not a URL).

There were two reasons ?raw didn't work for public files:

  1. importAnalysis only exempted ?url (and asset types) from the "non-asset file inside /public" guard, so ?raw on a non-asset public file (e.g. /_redirects, /foo.js) threw before the asset plugin ran.
  2. Even past that, the dev public middleware served such files statically (it only let ?url fall through to be transformed), so the import resolved to the raw source served as a module rather than a string.

Fix

Treat ?raw the same way ?url is already treated for public files:

  • importAnalysis: don't throw the non-asset error when the request has ?raw.
  • asset plugin resolveId: resolve public files for ?raw so the existing load handler picks them up.
  • dev public middleware: let ?raw requests fall through to the transform pipeline.

The existing hard error is preserved for plain public imports without ?raw/?url (e.g. import x from '/foo.js'), which remain genuine mistakes.

Testing

Added a ?raw public-file import to the assets playground (/raw.js?raw) asserting the file contents are inlined. Verified it fails before the change and passes after, in both serve and build modes. Also manually checked extensionless (/_redirects?raw), asset-extension (/foo.txt?raw), and additional-query (?raw&v=1) cases all return export default "<content>".

Fixes #21277

Importing a non-asset file from publicDir with ?raw (e.g.
`/_redirects?raw`) threw a hard error in import analysis, even though
the asset plugin already reads public files for ?raw requests. The
dev public middleware also served such files statically instead of
letting them be transformed, so the import resolved to raw source
rather than a string module.

Treat ?raw like ?url for public files: skip the non-asset error,
resolve them in the asset plugin, and let the public middleware fall
through to the transform pipeline.

Fixes vitejs#21277
Copilot AI review requested due to automatic review settings May 22, 2026 01:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for importing files from publicDir using the ?raw query so they’re transformed into raw string exports (similar to existing ?url handling), and validates the behavior in the playground.

Changes:

  • Allow /public/*?raw requests to bypass the public static middleware so they can be transformed.
  • Treat ?raw as a valid asset-style import query for absolute (/) public paths during import analysis and asset handling.
  • Add a playground demo and an E2E test for ?raw imports from /public.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
playground/assets/index.html Adds UI output + JS import to display raw contents imported from /public
playground/assets/tests/assets.spec.ts Adds a new test asserting ?raw import behavior for a /public JS file
packages/vite/src/node/server/middlewares/static.ts Ensures ?raw public requests are passed to transform pipeline (like ?url)
packages/vite/src/node/plugins/importAnalysis.ts Allows /public imports when ?raw is present (avoids public-file restriction)
packages/vite/src/node/plugins/asset.ts Includes rawRE in asset filter/guard so /public/*?raw is handled by asset plugin

Comment on lines +210 to +215
expect(await page.textContent('.public-js-raw-import-content'))
.toMatchInlineSnapshot(`
"document.querySelector('.raw-js').textContent =
'[success] Raw js from /public loaded'
"
`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IDE throws error on ?url&raw import

2 participants