[RFC] Proper Import Attributes support #18534
Replies: 11 comments 10 replies
-
|
Great discussion. What I have to say is probably already part of your current plan, but it's worth adding that it would be good to prioritize accepting the standard |
Beta Was this translation helpful? Give feedback.
-
|
About moving from import txt from './foo.txt?raw'to import txt from './foo.txt' with { type: 'raw' }I think this is good from an authoring POV. We'll still need to use the We can probably have |
Beta Was this translation helpful? Give feedback.
-
|
This would be a huge benefit to the quality of experience that me and my team get from working with Vite and Vitest. Hopefully it is something that can come to life very soon! Getting in position to both support native and non-standard types will prepare Vite to support the specification of future attributes type (like |
Beta Was this translation helpful? Give feedback.
-
|
If the same type name were implemented natively, there would be a possibility of differences. |
Beta Was this translation helpful? Give feedback.
-
|
We just discussed this again at the Vite team meeting yesterday, and we are now leaning towards option (2) described here - i.e., plugin hooks will receive the unique id with the attributes serialized as query strings. In other words: import txt from './foo.txt' with { type: 'raw' }Would essentially become syntax sugar (but more standardized and type-friendly) for: import txt from './foo.txt?type=raw'And in plugin hooks: transform(code, id, { rawId, attributes }) {
// id: "./foo.txt?type=raw"
// rawId: "./foo.txt"
// attributes: { type: raw }
}If there are no import attributes, then Some reasoning behind this:
|
Beta Was this translation helpful? Give feedback.
-
|
We will need microsoft/TypeScript#46135 to support the worker&url one |
Beta Was this translation helpful? Give feedback.
-
|
Regarding the type namespace, I think it's a legit concern, maybe we could make the default key import foo1 from './foo.css' with { type: 'css' } // runtime behaviour
import foo2 from './foo.css' with { vite: 'css' } // override default behaviour with vite
import foo3 from './foo.css' with { type: 'url' } // same as `./foo.css?url`
import foo4 from './foo.css' with { vite: 'url' } // same as foo3 |
Beta Was this translation helpful? Give feedback.
-
|
It may not be a common use case, but it is possible that the written source code is not bundled with Vite. In fact, it may not be bundled at all. That said, i'd suggest to:
// vite.config.ts
export default {
resolve: {
importAttributes: ( id: string, attributes: Record<string, any> ): Record<string, any> => {
return { ...attributes, 'vite-type': 'inline' };
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Still no support in vite? Unless i'm missing something? |
Beta Was this translation helpful? Give feedback.
-
|
We are now in a weird situation where using a plugin like https://www.npmjs.com/package/rollup-plugin-css-modules works fine for |
Beta Was this translation helpful? Give feedback.
-
|
// Before
import cssText from "./foo.css?inline";
// After
import cssText from "./foo.css" with { type: "css", inline: true };
// Before
import MyWorker from "./worker?worker&inline";
// After
import MyWorker from "./worker" with { type: "worker", inline: true }; |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Context: Import Attributes is now stage 4: https://github.com/tc39/proposal-import-attributes
Related PR / issues:
There are few different aspects regarding properly import attributes support in Vite:
PluginContainer)resolveIdRollup Behavior Alignment
Currently in Rollup, support for import attributes is somewhat lacking. Only the
resolveIdhook receives parsed attributes via the 3rd options argument:loadandtransformdo not have access to this information via arguments.In Vite we already augment
resolveId,load, andtransformhooks with an extraoptionsargument to pass the SSR flag (relevant docs):In Rolldown, we should provide the
attributesproperty viaoptionsinresolveId,load, andtransformso we can do:This information should also be made available to equivalent hooks in the Rust plugin API.
ID uniqueness
Should we include serialized attributes as part of the module ID? Internally this is definitely a yes as this is required to ensure unique id -> module mapping, the question is more about the public module IDs provided to plugin hooks:
There are multiple issues if we include serialized attributes in ids provided to hooks:
resolveIdfor bare specifiersThe potential breakage seems to be too costly.
The downside of not including attributes in ids is this makes ids no longer unique. A practical case where this can cause issues is plugins that use ids as keys for custom caching behavior. However, this should be rare in practice and the impact surface is much smaller than including attributes.
Proposed actions:
idspassed to hooks - keep them working like before.resolveId, add the following attributes to theoptionsobject:importerAttributes: JsonValuefullId: stringfullImporterId: stringload, add a 2ndoptionsargument in the shape of{ attributes: JsonValue, fullId: string }transform, add the following to the 3rdoptionsargument:{ attributes: JsonValue, fullId: string }With this, the only possible breakage would be users using
idas custom cache keys. The migration is also relatively simple: useoptions.fullIdas the key instead. The serialization format of attributes infullIdis now also free from constraints as long as they are guaranteed to be unique.The naming of
fullIdis open to suggestions.Migrating Vite magic queries to import attributes
In Vite, many built-in features and plugins rely on query strings in module IDs for this type of metadata, for example:
?raw?url?inline(for CSS & Workers)?worker/?sharedworker(for Workers)?init(for WebAssembly)With import attributes being standardized, I think we should eventually deprecate query string usage and move towards import attributes.
Examples
Raw Text
Before
After
Asset URL
Before
After
Inline CSS
Before
After
Worker Import
Before
After
@vitejs/plugin-vueblock importsBefore
After
typenamespaceIn the above examples, we are using
typewith values that map to the current built-in features of Vite. According to the spec:So in theory, it is possible for future platform specs to make use of the
typefield - e.g. native CSS Modules. It is also possible for different JavaScript runtimes / environments to provide different handling of import attributes.We have a few options here:
type. E.g.aswith { 'vite-type': 'inline-css' }orwith { type: 'vite-inline-css' }.Option (2) has the benefit of being more explicit about these being Vite features, but is much more verbose.
Beta Was this translation helpful? Give feedback.
All reactions