GithubHelp home page GithubHelp logo

Comments (9)

tw1t611 avatar tw1t611 commented on July 23, 2024 5

Hey guys, I don't really get the trick.
So, same scenario for me. I am using google storage to store my images and a headless cms, where I get the image url from.

The setup

svelte.config.js

import adapterStatic from "@sveltejs/adapter-static";
import RemoteAssets from "vite-plugin-remote-assets";
import { imagetools } from "vite-imagetools";

export default {
  kit: {
    adapter: adapterStatic(),
    target: "#svelte",
    vite: {
      plugins: [RemoteAssets, imagetools({ force: true })],
    },
  },
};

Image.svelte

<script>
  import remoteImage from "url from cms here";
  // As far as I know, it should not be possible to write a remote url in an import statement
  // The dynamic import shown above didn't work for me either. 

  export let image;
</script>

<img
  srcset={transformedImage}
  alt={image?.alternativeText || ""}
/>

I am loading the the url at build time using load(). Then the Image component should be prerendered through vite-imagetools. Using vite-iamgetools works fine with locally stored images. I assume I need vite-plugin-remote-assets to store images locally and process the images afterwards.

How would this be implemented using @sveltejs/kit ?

from imagetools.

akuales avatar akuales commented on July 23, 2024 2

@tw1t611 Did you ever find a solution for this? It seems like a pretty common task, but I'm stuck at the same point.

from imagetools.

taut-and-yare avatar taut-and-yare commented on July 23, 2024 1

@JonasKruckenberg Thanks a lot for your feedback!

from imagetools.

JonasKruckenberg avatar JonasKruckenberg commented on July 23, 2024

The answer is yes and no.
Yes you can probably use vite-plugin-remote-assets and your build will pass.
However, doing this is probably not what you want.

Since vite is a bundler it can only understand local files. That's all it does. This is why the vite-plugin-remote-assets fetches the specified file and caches it on your disk.

Your bundled website then includes a copy of the original image that has been transformed.
If this is what you're after then you are in luck: this should just work.

If you still want to fetch the image from that remote url when the website loads (maybe its a dynamic image or something) then vite-imagetools can't help you.

from imagetools.

taut-and-yare avatar taut-and-yare commented on July 23, 2024

@JonasKruckenberg Thanks, in this case, that will have to do. The content in question is coming from graphCMS and it won't be updated very often. I suppose I could trigger a build each time a new post is published.

However, I could not get vite-plugin-remote-assets to work with svelteKit... Will be making an issue there.

In general, I guess I was looking for something like, say, Next's Image component and found vite-imagetools. Works great I have to say, even if not exactly what I was looking for.

from imagetools.

taut-and-yare avatar taut-and-yare commented on July 23, 2024

@JonasKruckenberg

I did manage to get vite-plugin-remote-assets to work. It works as expected: Say I have fetched an image in my markup as <img src="remote-img.jpg". It will be in the production bundle as something likeremote-img-fb5a8607.jpg and the production markup will become <img src="remote-img-fb5a8607.jpg">.

However, unless I am missing something, I can't see how I could use vite-imagetools in this context even if at build-time files are available locally (only after vite-plugin-remote-assets runs).

I guess what would need be done is to somehow "hook" into vite-plugin-remote-assets and after copying the remote images also invoke a default imagetools transformation for each, and rewrite the markup accordingly.

Either that or to invoke a vite-imagetools "script" with defaults ( eg w=400&h=300&webp) that would run after vite-plugin-remote-assets and:

  1. parse the production markup to find relevant src attributes (marked with class = "imagetools" in the pseudo code below),
  2. transform the images and
  3. update the src attributes in the markup.

My page in (svelteKit) pseudocode:

<script context="module">
 ...
 export async function load() {
    const query = gql`
       query PostsIndex {
	 posts {
            ...
	    img {
	      url
	     }
	}
    }`;
  ...
 }
</script>
<div>
  {#each posts as post}
    {#if post.img}
	<img src={post.img.url} class="imagetools" />
    {/if}
  {/each}
</div>

from imagetools.

JonasKruckenberg avatar JonasKruckenberg commented on July 23, 2024

I guess what would need be done is to somehow "hook" into vite-plugin-remote-assets and after copying the remote images also invoke a default imagetools transformation for each, and rewrite the markup accordingly.

I'm gonna assume that, because you said you're new to vite, that you are also new to the way rollup works, so let me explain:
The job of a frontend bundler is to take take your source files and turn them into an optimized version (kinda like a compiler).
This happens in stages:

  1. resolve all the source files and their imports (so basically what imports what) and build a graph representation of that
  2. rewrite the graph according to some rules (This includes code-splitting, bundling files and even inlining stuff)
  3. write the modified graph as files to disk. This is your output.

The way rollup (and by extension site, since it uses pretty much the same approach) handles this, is by exposing hooks.
You for example have a hook called resolveId that lets plugin customize the first step (resolving imports) or another hook called transform which handles the second step.

It's important to note that all of the hooks that actually transform anything, get called once per import, so every import can be resolved individually. If a plugin changed anything in the dependency-graph (or the file itself) these changes will be passed on to later plugins and hooks.

The remote-assets-plugin goes through your whole project in the second phase and turning remote urls into local file paths.
This new local file path wasn't present when vice first started, so this import gets reemitted into the plugin pipeline where it can then be picked up by imagetools.

so the following configuration should work:

vite.config.ts

import { defineConfig } from 'vite'
import remoteAssets from 'site-plugin-remote-assets'
import { imagetools } from 'site-imagetools'

export default defineConfig({
    plugins: [
        remoteAssets(),
        imagetools()
    ]
})

from imagetools.

taut-and-yare avatar taut-and-yare commented on July 23, 2024

This new local file path wasn't present when vice first started, so this import gets reemitted into the plugin pipeline where it can then be picked up by imagetools.

Firstly, thanks for taking the time to explain!

But my problem remains in that I have not found how to call imagetools on these new files as I don't know their names at the time... From your explaination on how vite works, the new files generated by remote-assets will be reemmitted into the pipeline for imagetools to process, but how am I to do this in my code??

If you look in the simplified code below, I have access to an array of posts that have (or haven't) an img.url. These, I can put into image tags like so:

<script>
// Here I have access to posts array with the remote urls
// How can I invoke image-tools for every local-url that'll be generated for each remote url  in the array?
</script>
<div>
  {#each posts as post}
    {#if post.img}
	<img src={post.img.url} />  <!-- and what do I put here? -->
    {/if}
  {/each}
</div>

And then they are "replaced" at build by the remote-assets plugin : so <img src="https://some-remote-url.jpg"> becomes <img src="/some-local-url-fb5a8607.jpg">.

All imagetools examples and documentation I found mention this syntax: import MyImg from /known-path/known-filename?w=400&h=300&webp. But this:

import Img from 'known-path/unknown-filename?w=400&h=300&webp'

<img src={Img.src}>

... won't do as at the time when I write the markup code, I do not know the filename (a hash is attached to the filenames by the remote-assets plugin). But even if I new it, I couldn't have used at this stage as the remote-assets plugin would first need the original remote-url in order to replace the src attribute.

Can you suggest a way of achieving this? Thank you again.

from imagetools.

JonasKruckenberg avatar JonasKruckenberg commented on July 23, 2024

Ohhh, I See what the problem is now! You're trying to circumvent the plugin system in a way it doesn't work though. You have to access to the intermediate output of plugins without writing one yourself.
Your issue is that the url query parameters are not preserved, since Vite-plugin-remote-assets doesn't carry them over. (And also probably shouldn't since that would result in weird behavior on the server-side)
One thing you can try is the following:

import remoteImage from 'https://example.com/foo.jpg' // this will be turned into node_modules/.remote-assets/foo.jpg
// this weird replacing makes it easier for Vite to resolve the path
const transformedImage = await import(`/node_modules/.remote-assets/${remoteImage.replace('/node_modules/.remote-assets/')}?width=500&height=200`)

// transformedImage should now point to the transformed image

from imagetools.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.