svelte-image
svelte-image copied to clipboard
Svelte-Kit: Can't use Image component
Hi,
Firstly thanks for making this great library. I'm trying to get to get it setup with Svelte-Kit however importing Image gives me this error:
ENOENT: no such file or directory, open '/Users/richard/Documents/Personal sites/r-bt.com/node_modules/blurhash/src/index.ts'
Steps to reproduce
- Create new Svelte-Kit project (issue present on both JS & TS projects
- Install svelte-image
- Add
svelte-imagetosvelte.config.cjs
const image = require('svelte-image');
/** @type {import('@sveltejs/kit').Config} */
module.exports = {
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte'
},
preprocess: {
...image()
}
};
- Import
Imagecomponent - Run the dev server
Can confirm I get this also:
08:57:06 [vite] Internal server error: ENOENT: no such file or directory, open '/Users/michaeloliver/Development/Personal/blog-sveltekit-ts-markdown-list/node_modules/blurhash/src/index.ts'
I am also trying to make it work with sveltekit. Anybody have a solution ?
Same problem.
This package is a deal maker/braker for Svelte, I should be in the official repo.
My two cents, I guess the config file now looks more like:
preprocess: preprocess({
...image()
}),
@Antoine-lb would you able to make it work, or do we need to use other plugins like vite-image-tools ?
@yiioverflow no, I wasn't able to make it work. I didn't try that hard but I ended up exactly where the this issue points to
I fixed it by adding blurhash to optimizeDevs in my vite config. I also needed to add it to the ssr.noExternal array, even though I have it as a dev dependency. It wouldn't work otherwise. So the total config kinda looks like this:
// svelte.config.js
// ...
const config = {
// ...
kit: {
// ...
vite: {
optimizeDeps: {
include: ['blurhash'],
},
ssr: {
noExternal: ['svelte-image'],
},
},
},
};
Also, the preprocess statement has to look like the following:
import preprocess from 'svelte-preprocess';
import svelteImage from 'svelte-image';
const config = {
preprocess: [
preprocess({ /* options */ }),
svelteImage(),
],
// ...
Note that there is a difference between svelte-preprocess and the Svelte preprocess API. In my opinion, svelte-preprocess is pretty poorly named and causes a lot of confusion. This plugin does not use svelte-preprocess, but the preprocess API of svelte, which is why it needs to be passed along with svelte-preprocess, not inside of it.
However, with my project running TypeScript, I couldn't get it to work, as svelte-image kept producing parsing errors when it encountered TypeScript syntax. No idea how to solve this -- this project relying so much on preprocessing for more than just image resizing was probably not the greatest design decision.
@qelix thanks for sharing! There's a PR for blurhash that would package it as ESM, so that you no longer need to include it in optimizeDeps: https://github.com/woltapp/blurhash/pull/58. I don't think that you should need to include svelte-image in ssr.noExternal as that should be done automatically (https://github.com/sveltejs/kit/pull/1148). Whether it's a dependency or dev dependency also shouldn't matter (though it did in the past because SvelteKit had noExternal: Object.keys(pkg.dependencies || {}) in the default config, which is no longer recommended - https://kit.svelte.dev/faq#packages).
Hi, I just merged the https://github.com/woltapp/blurhash/pull/58 PR and release 1.1.4 of the package, so you should be able to move forward with this.
Thanks @omahlama! However, it looks like there's another issue: https://github.com/woltapp/blurhash/issues/142
Things works fine for me in both dev and build mode. @Antoine-lb thanks for the config file guess seems you are correct.
// svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
import adapter from '@sveltejs/adapter-static';
import image from 'svelte-image';
import { preprocess } from 'svelte/compiler';
const config = {
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
adapter: adapter({
// default options are shown
pages: 'build',
assets: 'build',
fallback: null
})
},
preprocess: preprocess({
...image()
})
};
export default config;
Update:
But there seems to be something odd going on in prod build, if I am to reload the page with image image disappears., but If I navigate to another link and came back to the page with image, image is shown. May be this is a bug with Svelte kit Static adapter. paging @benmccann
I fixed it by adding
blurhashtooptimizeDevsin my vite config. I also needed to add it to thessr.noExternalarray, even though I have it as a dev dependency. It wouldn't work otherwise. So the total config kinda looks like this:// svelte.config.js // ... const config = { // ... kit: { // ... vite: { optimizeDeps: { include: ['blurhash'], }, ssr: { noExternal: ['svelte-image'], }, }, }, };Also, the preprocess statement has to look like the following:
import preprocess from 'svelte-preprocess'; import svelteImage from 'svelte-image'; const config = { preprocess: [ preprocess({ /* options */ }), svelteImage(), ], // ...Note that there is a difference between
svelte-preprocessand the Svelte preprocess API. In my opinion,svelte-preprocessis pretty poorly named and causes a lot of confusion. This plugin does not usesvelte-preprocess, but the preprocess API of svelte, which is why it needs to be passed along with svelte-preprocess, not inside of it.However, with my project running TypeScript, I couldn't get it to work, as
svelte-imagekept producing parsing errors when it encountered TypeScript syntax. No idea how to solve this -- this project relying so much on preprocessing for more than just image resizing was probably not the greatest design decision.
Is the typescript issue solved for now? I have the same error, pointing to type declaration.
I've sent a fix for the blurhash source map issue: https://github.com/woltapp/blurhash/pull/155
I just tested with the latest version of blurhash and everything seems to be working now. I've sent a PR to upgrade this project: https://github.com/matyunya/svelte-image/pull/140. But in the meantime, you can upgrade your own projects by upgrading the version in your lock file. I believe this issue can be closed now
However, with my project running TypeScript, I couldn't get it to work, as
svelte-imagekept producing parsing errors when it encountered TypeScript syntax. No idea how to solve this -- this project relying so much on preprocessing for more than just image resizing was probably not the greatest design decision.
@benmccann's PR seems to fix it when using Javascript, but it's still giving me a parse error when using typescript. I put a minium reproducible example, and was wondering if anyone had any idea how I could go about fixing this. Here's the example Here's the error:
CompileError [ParseError]: Unexpected token
at error (/project/sandbox/node_modules/svelte/compiler.js:16675:20)
at Parser$1.error (/project/sandbox/node_modules/svelte/compiler.js:16753:10)
at Parser$1.acorn_error (/project/sandbox/node_modules/svelte/compiler.js:16747:15)
at Object.read_script [as read] (/project/sandbox/node_modules/svelte/compiler.js:8799:17)
at tag (/project/sandbox/node_modules/svelte/compiler.js:15701:34)
at new Parser$1 (/project/sandbox/node_modules/svelte/compiler.js:16712:22)
at Object.parse$I [as parse] (/project/sandbox/node_modules/svelte/compiler.js:16844:21)
at replaceImages (/project/sandbox/node_modules/svelte-image/src/main.js:554:18)
at markup (/project/sandbox/node_modules/svelte-image/src/main.js:680:21)
at async process_markup (file:///project/sandbox/node_modules/svelte/compiler.mjs:46847:23) {
code: 'parse-error',
start: { line: 6, column: 17, character: 199 },
end: { line: 6, column: 17, character: 199 },
pos: 199,
filename: undefined,
frame: "4: import welcome_fallback from '$lib/images/svelte-welcome.png';\n" +
'5: \n' +
'6: let testVariable: number;\n' +
' ^\n' +
'7: </script>\n' +
'8: '
} Error parsing component content