Comments (9)
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.
@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.
@JonasKruckenberg Thanks a lot for your feedback!
from imagetools.
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.
@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.
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:
- parse the production markup to find relevant src attributes (marked with class = "imagetools" in the pseudo code below),
- transform the images and
- 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.
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:
- resolve all the source files and their imports (so basically what imports what) and build a graph representation of that
- rewrite the graph according to some rules (This includes code-splitting, bundling files and even inlining stuff)
- 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.
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.
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)
- Upgrading Vite-imagetools 5.0.8 throws an error from 4.x version HOT 2
- generateImageID causes tests to fail on CI HOT 3
- Vite example has a typo HOT 1
- Renaming picture fallback to img is not reflected in the document HOT 1
- Waste less effort transforming images
- Dependency on sharp not declared correctly for yarnβs PnP loader HOT 9
- Vite plugin crash HOT 2
- Loading attribute HOT 1
- v6 broken due to missing sharp 0.33 binariers HOT 3
- Some images get rotated for some reason HOT 14
- crop from / "gravity" HOT 1
- Error: Unable to parse color from string: ##ffaa22
- Pre-transform error: Failed to parse source for import analysis because the content contains invalid JS syntax
- How to receive access to original image in `extendOutputFormats` after v7.0.0? HOT 2
- Resize image to fit in box
- Querying for GIF's metadata removes animation
- How to use with SSR
- Use the <Image> component HOT 2
- Plugin output is not reproducible HOT 1
- Wrong output path when building in Laravel project HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from imagetools.