Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query strings don't work in dynamic imports with template literals containing variables #575

Closed
refact0r opened this issue Jul 3, 2023 · 8 comments

Comments

@refact0r
Copy link

refact0r commented Jul 3, 2023

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
image
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.

@ZakkProjects
Copy link

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();
			}
		}),

@refact0r
Copy link
Author

refact0r commented Sep 3, 2023

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).

@JonasKruckenberg
Copy link
Owner

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
Copy link
Collaborator

This seems to work for me

Screenshot from 2023-09-21 16-19-41

Can anyone provide a project that reproduces this? Otherwise I'll assume it works and close the issue

@refact0r
Copy link
Author

@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" />

image

@benmccann
Copy link
Collaborator

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

@benmccann benmccann changed the title Can't override defaultDirectives in dynamic import Query strings don't work in dynamic imports with template literals containing variables Sep 22, 2023
@refact0r
Copy link
Author

Ah, that makes sense.

@benmccann
Copy link
Collaborator

This will be fixed in Vite 5. Thanks to @Dunqing for the fix!

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

No branches or pull requests

4 participants