zerodevx / svelte-img

High-performance responsive/progressive images for SvelteKit
https://zerodevx.github.io/svelte-img/
ISC License
300 stars 11 forks source link

Dynamic imports e.g images for a blog #5

Closed kylesloper closed 11 months ago

kylesloper commented 1 year ago

Struggling to implement this into a site that cannot hardcode the image path into import. This is what I've got currently but facing tonnes of obstacles.

1.Unable to assign import to a variable to use *dynamic imports*
2.Even if that did work, Vite's built in dynamic import is garbage and requires a hard-coded file extension

Tried a custom Image component to pass src and then dynamically import

<script lang="ts">
    // @ts-nocheck
    export let src;
    const imageSrc = import(`./src/assets/${src}?run`);
    import Img from '@zerodevx/svelte-img';
    export let alt
    export let className;
</script>

<Img class={className} src={imageSrc} {alt} />

Any suggestions would be beyond useful. Love the library, just trying to stretch it my specific use case :)

zerodevx commented 1 year ago

I think that's a limitation of imagetools. 😞 It needs to know exactly which images to perform transformations on at compile time.

Tried a custom Image component to pass src and then dynamically import

Your component will work if you statically import the image meta from your calling component, like:

<script>
import src from '$lib/my-img.jpg?run'
</script>

<MyComponent {src} />

In most cases if the images are unknown during run-time, a cloud image service is usually used to generate the image variants.

zerodevx commented 1 year ago

Another pattern which might work in your use-case is to stub your images out. The caveat is, since dynamic imports are not allowed, you know what images you'll be using, and have them stored locally beforehand.

// stub.js

export {default as cat} from '$lib/a/cat.jpg?run'
export {default as dog} from '$lib/a/dog.jpg?run'
...

In your consuming page, import all image metas, then use as needed.

// +page.svelte

<script>
import * as srcs from './stub.js'
import Img from '@zerodevx/svelte-img'

// do some logic
let src = srcs['cat']
</script>

<Img {src} />

Closing this issue for now, feel free to reopen if you have further thoughts on this.

zerodevx commented 1 year ago

I'm reopening this because something like https://github.com/zerodevx/svelte-img/issues/9#issuecomment-1495633018 might work.

AaronNBrock commented 1 year ago

I'm would like this as well, I've not been able to get it to work but I think it could be possible with imagetool, when I printout the dynamically imported image it is able to generate the required images.

However, despite this when I use the <Img src={data.image} /> nothing appears in the DOM.

AaronNBrock commented 1 year ago

I have figured out a way to do this w/ a tad bit of jank, if you use the meta.glob.import as opposed to the dynamic import, you can use query: { run: '' } to add vite-imagetools config then select the image you actually care about, for example:

const images = import.meta.glob('../example/path/*.png', {
    query: { run: '' },
    eager: true,
});

return {
    image: images[`../example/path/${myVar}.png`]?.default || null,
};

I created an issue on the imagetools github asking if this is/can be made possible using the dynamic import directly.

zerodevx commented 11 months ago

I added a section in the docs using vite patterns for glob imports.

Marking this as closed now - feel free to reopen.