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

'Input file is missing' when src is a variable #13

Open
hmaesta opened this issue Sep 6, 2021 · 10 comments
Open

'Input file is missing' when src is a variable #13

hmaesta opened this issue Sep 6, 2021 · 10 comments

Comments

@hmaesta
Copy link
Contributor

hmaesta commented Sep 6, 2021

<script>
   import Image from 'svimg';
   const src = 'images/birds/orange-bird.jpg';
</script>

<Image {src} />

Like above example, when src is a variable the Input file is missing error is returned.

It also doesn't work when in a loop, like:

<script>
   import Image from 'svimg';
   const animals = [ 'dogs.jpg', 'cats.jpg', 'birds.jpg' ]
</script>

{#each animals as animal}
   <Image src={animal} />
{/each}

That makes impossible to load images from a JSON file, for instance, or using svimg in a repeatable component.


Broken code examples:

I couldn't get a running example online since build breaks with "Input file is missing".

@xiphux
Copy link
Owner

xiphux commented Sep 6, 2021

I can maybe add a note to the documentation but svimg only works with literal image paths and this might be impossible to do automatically. The svelte preprocessor can only preprocess the source code but cannot really execute the Svelte/javascript code, so it cannot actually interpret the end result of this javascript.

@hmaesta
Copy link
Contributor Author

hmaesta commented Sep 10, 2021

That makes sense... 😓

I went for some "benchmarking" and found that:

  • matyunya/svelte-image has the same limitation
  • nuxt/image can manage dynamic references (and another tricks like specifying sizes for each image). Vue build flow is different from Svelte in a way thats not possible to have the same behavior?

Here's a sandbox to show nuxt/image working with a loop.

@xiphux
Copy link
Owner

xiphux commented Sep 10, 2021

I would guess that Nuxt-image hooks into Nuxt's SSR process when the code is actually executed server side. The Svelte preprocessing hook is more for transformation of source code (eg Typescript to Javascript), not actual server side rendering. Since the SSR is being handled by SvelteKit, I would imagine it would require a SvelteKit-specific solution to hook into SSR (if SvelteKit even provides a way to do that - not sure).

In cases like this where I've needed to process images that don't live in the markup, I've thrown together plugins to make use of the svimg preprocessor in other places besides the standard Svelte preprocessing hook, and I added support for svimg to be used as an <s-image> custom element specifically for dynamic use cases like this.

For example, my personal site using svimg is written in Markdown for all of the content. So I put together:

  • rehype-svimg to replace images during Markdown render with s-image instances with the appropriate generated attributes
  • rollup-plugin-markdown-svimg to do the actual generation of those image files during build time

These plugins really just call into a couple exported svimg functions to do all the image generation and get back the appropriate attributes for the component.

So off of the top of my head, if you have images in JSON files, you could potentially have a build plugin that reads your JSON files, runs them through svimg, and adds the generated attributes as additional JSON properties. Then, you could consume that JSON in your Svelte component and set all those attributes including the generated ones onto the component during render.

@rchrdnsh
Copy link

rchrdnsh commented Aug 21, 2022

hmmmm…would you say that kit needs to do this then? Is this kind of thing only possible at the framework level? Been looking for something to solve this usecase, as it is most of my need in regards to images. Maybe…I dunno 70-90% of the time I am rendering images in {#each} blocks…

@xiphux
Copy link
Owner

xiphux commented Aug 21, 2022

Well, it'd have to be hooked into the rendering process in some way to know what the result of your dynamic expressions are. So I think it'd have to be svimg plugging into the sveltekit render process somewhere, but I haven't looked into it yet to know where that is specifically (ie what's best way to hook into the SSR process - I assume there's some way). I've generally tried to stay framework-agnostic, but if there's enough demand I could certainly look into it.

It's also worth thinking about alternative ways to do this. For example, even though your image elements may be rendered in a loop, don't your images live on disk somewhere? (The images aren't generated from nothing, are they?) Can you have a build plugin that uses node apis to get all image files in a directory and run them through to generate the files and component attributes (like the packages in my previous comment do). You could then store off those generated attributes somewhere that your Svelte code could import (like a JSON file or something), and then make use of them with svimg's Custom Element.

@indaco
Copy link

indaco commented Aug 22, 2022

it's a shame!

I also tried to use the combo "mdsvex + rehype-svimg" for single page without success

@rchrdnsh
Copy link

what I'm doing now is this:

---
order: 2
status: marquee
category: words
title: Time
subtitle: Music starts here.
description: 
image: /words/time/time.jpg
alt: Flying at the speed of sound.
---

<script context="module">
  import Clock from '$lib/special/Clock.svelte';
  metadata.animated_image = Clock;

  metadata.srcset_portrait_jpg = TimePortraitJPG;
  metadata.srcset_landscape_jpg = TimeLandscapeJPG;
</script>

where I use vite-imagetools to manually make a srcset for the images in question in their markdown files...I don't have a workflow for looping through images in a svelte file yet, though...

but all of this is quite a manual pain and might not work at all if pulling form a cms or some other data source...

I had not thought about a build plugin, nor do I know really know what that is or how to make one...

If you have any resources or suggestions on that I would be glad to check it out :-)

Ideally I want kit or something else to process images automatically and only when new ones are added or changed on my local device which would then sync up with whatever host I'm using without making the host build the images

for example, I was trying to use AVIF images in this process but Netlify simply would not do it, as it was too costly and time consuming and memory consuming to do so...

@indaco
Copy link

indaco commented Aug 23, 2022

In my case the frontmatter variable contains just the file name without the path to it

The path is built based on the sveltekit route the md file is belong to, so should not be hardcoded as frontmatter variable.

what I'm doing now is this:


---

order: 2

status: marquee

category: words

title: Time

subtitle: Music starts here.

description: 

image: /words/time/time.jpg

alt: Flying at the speed of sound.

---



<script context="module">

  import Clock from '$lib/special/Clock.svelte';

  metadata.animated_image = Clock;



  metadata.srcset_portrait_jpg = TimePortraitJPG;

  metadata.srcset_landscape_jpg = TimeLandscapeJPG;

</script>

where I use vite-imagetools to manually make a srcset for the images in question in their markdown files...I don't have a workflow for looping through images in a svelte file yet, though...

but all of this is quite a manual pain and might not work at all if pulling form a cms or some other data source...

I had not thought about a build plugin, nor do I know really know what that is or how to make one...

If you have any resources or suggestions on that I would be glad to check it out :-)

Ideally I want kit or something else to process images automatically and only when new ones are added or changed on my local device which would then sync up with whatever host I'm using without making the host build the images

for example, I was trying to use AVIF images in this process but Netlify simply would not do it, as it was too costly and time consuming and memory consuming to do so...

@rchrdnsh
Copy link

yeah, my content lives in it's own content folder, and is not co-located in the routes, but gets injected into templates later on...the image path is for the static folder anyway, so...

@xiphux
Copy link
Owner

xiphux commented Aug 27, 2022

There's a lot going on in this issue discussion...

If you're having issues with rehype-svimg, I would suggest putting issues on that repo instead. This issue was supposed to represent the more general limitation around dynamic expressions in the img src and not around directory layout or markdown files.

As of right now, I don't believe this component's preprocessor is compatible with vite-imagetools. By build plugin, I'm referring to a plugin for your app bundling pipeline, whether that's vite or rollup or something else. I had created rollup-plugin-markdown-svimg some time ago, before svelte adopted vite, with the idea being that rehype-svimg was used during markdown rendering to html to convert markdown image format (!(Image caption)[url/to/image.jpg]) to an svimg element, and during bundling the rollup plugin would handle generating the actual image files. Maybe that doesn't work or make sense for your scenario, but that's what I mean by handling it elsewhere in a build plugin.

svimg will only generate images that don't already exist. I'm not familiar with Netlify and its deployment process at all, but you could consider pregenerating the images and committing them to source control if you don't want them to be recreated.

I have a similar directory layout, where routes are in one directory, markdown content is in another, and images are in a static image third directory. My markdown files also similarly reference image filenames without a path, and I added the srcPrefix option to let the render process control where the image lives. So the route file reads the markdown from the relevant content directory, using the srcPrefix to point image urls to the static image directory.

I'm happy to help more with getting rehype-svimg working for markdown images if that's what you're looking for, but it'd be helpful if:

  • It was an issue on the rehype-svimg repo instead, and
  • I could be pointed to some sort of repo or example to look at so I can see what you're trying to do and why it isn't working

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