Vite Module Resolution
Virtual modules and the \0 prefix convention.
How Vite Resolves Imports
When you write:
import photo from './sunset.jpg?z5'; Vite processes this through plugin hooks:
resolveId- Determine what module ID to useload- Provide the module contenttransform- Modify the content (optional)
Zone5’s Vite plugin implements these hooks to intercept ?z5 imports.
The ?z5 Query Parameter
Detection
The plugin checks for the ?z5 query:
resolveId(id) {
if (id.includes('?z5')) {
// Handle this import
}
} Why Query Parameter
Alternative approaches:
| Approach | Example | Issue |
|---|---|---|
| Custom extension | photo.z5 | File doesn’t exist |
| Prefix | z5:./photo.jpg | Non-standard |
| Query parameter | photo.jpg?z5 | Works with real files |
The query parameter approach:
- Keeps the original file path valid
- Follows Vite conventions (like
?raw,?url) - Allows IDE features to work (go-to-file, etc.)
Virtual Modules
What They Are
A virtual module is content that exists only in memory, not on disk:
// This "file" doesn't exist on disk
import data from ' zone5:processed-photo-abc123'; Vite generates it on-demand from the processed image data.
When Zone5 Uses Them
- User imports
./photo.jpg?z5 - Plugin resolves to
\0zone5:/path/to/photo.jpg - Plugin loads the virtual module with ItemFeature data
Why Not Just Return JSON
The plugin could return JSON directly:
load(id) {
return JSON.stringify(itemFeature);
} But ES modules offer benefits:
- Tree shaking
- Type information
- Standard import syntax
The \0 Prefix Convention
What It Means
The \0 (null character) prefix is a Rollup/Vite convention signaling “this is not a real file.”
resolveId(id) {
if (id.includes('?z5')) {
return `