Query strings don't work in dynamic imports with template literals containing variables
refact0r opened this issue · comments
I am working on a static Sveltekit site.
When I dynamically import an image with
const module = await import(`$lib/images/${name}.jpg?w=400`)
I get
It seems to be applying my defaultDirectives:
return new URLSearchParams({
format: `avif;jpg`,
w: '2000;1000;500',
as: 'picture'
})
but the actual directives in the URL don't work.
Probably not the best possible solution,
You can always make defaultDirectives more specific using conditionals as specified in docs under options:
imagetools({
defaultDirectives: (url) => {
if (url.searchParams.has('spotify')) {
return new URLSearchParams({
tint: 'ffaa22'
})
}
return new URLSearchParams()
}
})
and instead of long string you can use it as your "own" directive.
You can also use more complicated conditions.
I solved it by just appending the rest at the end.
imagetools({
defaultDirectives: (url: URL) => {
const extension = url.pathname.substring(url.pathname.lastIndexOf('.') + 1);
if (['png', 'jpg', 'jpeg'].includes(extension)) {
return new URLSearchParams(
'format=avif;webp;' + extension + '&as=picture&w=2000;1000;500' + url.searchParams
);
}
return new URLSearchParams();
}
}),
But i can also imagine ignoring all defaults by using
imagetools({
defaultDirectives: (url: URL) => {
if (url.searchParams.has('custom')) {
return url.searchParams;
}
return new URLSearchParams();
}
}),
Thanks, this works as a solution.
But it is still quite weird that with normal imports the default directives are overwritten, but with dynamic imports they are not (at least this was the case when I submitted this issue, I have not tried to reproduce since then).
It would be interesting to see if this is still the case, I remember that dynamic imports are behaving slightly differently to regular imports in vite.
@benmccann I think you misunderstood, the problem is that static imports can override the defaultDirectives defined in vite config, but dynamic imports cannot.
I can still reproduce the issue. (repo: https://github.com/refact0r/imagetools-575)
imagetools({
defaultDirectives: () => {
return new URLSearchParams({
blur: '10'
});
}
}),
<script>
import { onMount } from 'svelte';
import static_image from '../../static/favicon.png?blur=1';
let dynamic_image;
let name = 'favicon';
onMount(async () => {
dynamic_image = (await import(`../../static/${name}.png?blur=1`)).default;
});
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<p>static import</p>
<img src={static_image} alt="Svelte logo" />
<p>dynamic import</p>
<img src={dynamic_image} alt="Svelte logo" />
Ok, so there are more parts to this. It's not that you override a defaultDirective, but it's that you use a template literal that has a variable together with a query string. This one will have to be addressed in Vite: vitejs/vite#14449
I'll note that I also hit vitejs/vite#14101 while debugging this
Ah, that makes sense.
This will be fixed in Vite 5. Thanks to @Dunqing for the fix!