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

Images don't show in dev mode with Laravel backend #396

Closed
HassanZahirnia opened this issue Sep 19, 2022 · 28 comments · Fixed by #489
Closed

Images don't show in dev mode with Laravel backend #396

HassanZahirnia opened this issue Sep 19, 2022 · 28 comments · Fixed by #489

Comments

@HassanZahirnia
Copy link

If you try this plugin with a Laravel + Vite + Vue stack, all the images will throw a 404 (Not Found) error and not show on the page.

This is because the tool is returning relative paths and normally an asset URL imported through Vite would have an absolute URL, and in the context of a backend such as Laravel the lack of absolute URL breaks the images.

Assuming you're running in dev mode
Without imagetools loader ( normal image importing ):

import Cat from '@/images/cat.png'

console.log(Cat)
// Output: http://localhost:3000/resources/images/cat.png

With imagetools loader:

import Cat from '@/images/cat.png?width=200'

console.log(Cat)
// Output: /@imagetools/5812d5ee51f96cb9c239acca9f2ecc22bd83998a
// Throws a not found error.

Note that build works fine. It's only a dev mode issue.

@benmccann
Copy link
Collaborator

Can you check if #400 would fix the issue you're facing?

@HassanZahirnia
Copy link
Author

Can you check if #400 would fix the issue you're facing?

No unfortunately it does not fix the issue :(

Also I think that PR is for a different purpose as they stated:

This PR fixes the paths of images in the Vite build result.

They talking about the build result. This issue I'm having happens in dev mode.

@hopkins385
Copy link

Same here. Getting 404 Errors on all images when running yarn dev in laravel vite environment

Error:

Failed to load resource: the server responded with a status of 404 (Not Found)

html code that corresponds to error

<source type="image/avif" srcset="/@imagetools/23ae5086f5b8fa6391e57bb0800aabc686bd2b37 850w">

Environment

Console Output: (just for reference and version numbers)

  VITE v4.0.1  ready in 503 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help

  LARAVEL v9.43.0  plugin v0.7.1

package.json

  "laravel-vite-plugin": "^0.7.1",
  "vite": "^4.0.1",
  "vite-imagetools": "^4.0.11",
  "vue": "^3.2.45"

vite.config.js

export default defineConfig({
    build: {
        chunkSizeWarningLimit: 600,
    },
    plugins: [
        laravel({
            input: ['resources/css/frontend.css', 'resources/js/frontend.ts'],
            refresh: true,
            buildDirectory: '/build/frontend',
            config: 'frontend',
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
        imagetools({
            /* options */
        }),
    ],
    resolve: {
        alias: {
            '@': path.resolve(__dirname, './resources/js'),
        },
    },
    server: {
        strictPort: true,
        hmr: {
            host: 'localhost',
        },
    },

@DeedleFake
Copy link
Contributor

I have the same exact problem with a Rails backend:

image
image

@DeedleFake
Copy link
Contributor

@HassanZahirnia, if you get a chance, could you double-check that the changes from the above-referenced pull request also fixed it for you with Laravel, please?

@hopkins385
Copy link

hopkins385 commented Jan 20, 2023

nope, unfortunately it does not work. I'm using this package as a plugin in a Laravel 9 and Nuxt 3 environment, in both environments @imagetools is not resolved as url in dev but build works as expected.

@HassanZahirnia
Copy link
Author

@DeedleFake No the issue is not fixed. Honestly not sure why you marked this issue as "fixed" before checking with a Laravel backend first 😅

If possible please re-open this issue @benmccann

@HassanZahirnia
Copy link
Author

HassanZahirnia commented Jan 20, 2023

Hey I've found a similar Vite plugin that uses Sharp underhood, and it's asset paths are correct in dev mode. I thought maybe someone could have a look at it and figure out what they did that would fix this issue, here is the source file:
https://github.com/jack-weilage/vite-image/blob/main/src/index.ts

Although I should mention their plugin does not work in production. So be careful not to grab any production logic from their code.
Either way the focus is on how they've handled the path for dev mode.

@DeedleFake
Copy link
Contributor

Honestly not sure why you marked this issue as "fixed" before checking with a Laravel backend first 😅

To be honest, I'm not sure why I did either. Just wasn't thinking. Sorry.

@benmccann
Copy link
Collaborator

@DeedleFake did you test #489 with any app? I didn't think about this before, but I'm pretty sure https://github.com/JonasKruckenberg/imagetools/pull/489/files#diff-8d1a92b43a2575de2cdad4edc1af1e9586a5f1ee84ec2dad9b7af5ebc2322b13R123 is wrong because Vite's base middleware strips out the base path before passing it to any middlewares. I'm wondering if #489 helps at all or should be reverted entirely?

@benmccann benmccann reopened this Jan 20, 2023
@DeedleFake
Copy link
Contributor

did you test #489 with any app?

Yes, I did. I tested it with the Rails app that I was having the problems I posted above in this issue and it fixed them.

@DeedleFake
Copy link
Contributor

Vite's base middleware strips out the base path before passing it to any middlewares

The issue with the Rails backend was that the Vite dev server never even saw the requests because they didn't start with the base path. The way the Rails integration works is something like this:

  • If the path starts with the Vite base path, send it to the dev server.
  • If it starts with something else, check for configured Rails routes and use one that matches.
  • If none of those match, check for a matching file in the public directory and serve it.
  • If all of the above fails, yield a 404.

So without prefixing the string paths returned by the plugin when it's used in an import in the code, the Vite dev server will never even see them in the first place.

@DeedleFake
Copy link
Contributor

I've never worked with Laravel before, but I set up a simple project and it looks like the problem there is different, but related. In Laravel's case, assets are not routed through the main dev server but are instead sent directly to Vite. For example, in my case the Laravel dev server is running on port 8000, while the Vite dev server is running on port 5173. However, there's a big discrepancy between normal Vite image imports and ones routed through vite-imagetools:

import test from './test.png'
// test is http://[::1]:5173/resources/js/test.png

import test from './test.png?width=50'
// test is @imagetools/0078fa8134eed9d2fc44c1cd1ab4f62b63fe1041

I would speculate that there's another config option for Vite that Laravel is automatically setting to redirect assets to the dev server but that is being missed by vite-imagetools. I don't see anything obvious in the config, though.

@HassanZahirnia
Copy link
Author

@DeedleFake Thanks for looking into Laravel 🙌
The situation you mentioned is same as the one I also described in the first post. The assets need to have an absolute path, except on dev server the path start with the Vite server url (which would be http://localhost:3000 or http://[::1]:5173)

I suggest you to look into the repo I linked earlier. That plugin has a working path setup for dev server. I personally have no experience with Vite plugins so I couldn't figure it out myself.

@DeedleFake
Copy link
Contributor

I suggest you to look into the repo I linked earlier. That plugin has a working path setup for dev server.

I've been doing so, as well as looking at other plugins. The documentation around this particular situation, despite how common you'd think it is, isn't fantastic, unfortunately.

I personally have no experience with Vite plugins so I couldn't figure it out myself.

Neither do I. I'd never looked into how they worked at all before I started working on fixing this. In fact, I'd never used Vite before a week ago or so.

@DeedleFake
Copy link
Contributor

I tried out the repo that you linked above and it has the exact same problem:

image
image

Neither plugin generates absolute paths for their on-demand assets, and I'm not sure what the proper way to do so is.

@benmccann
Copy link
Collaborator

benmccann commented Jan 20, 2023

didn't think about this before, but I'm pretty sure https://github.com/JonasKruckenberg/imagetools/pull/489/files#diff-8d1a92b43a2575de2cdad4edc1af1e9586a5f1ee84ec2dad9b7af5ebc2322b13R123 is wrong because Vite's base middleware strips out the base path before passing it to any middlewares

Okay, I think your change to implement base path support was correct and necessary. I can confirm that images in SvelteKit were broken on the prior release (4.0.13) when using a base path. The way the imagetools middleware is being called it will be invoked before Vite's base middleware strips out the the base path. If on the otherhand we were returning a function that returned the middleware then we'd no longer want to strip out the base path because Vite would do it: https://vitejs.dev/guide/api-plugin.html#configureserver

@benmccann
Copy link
Collaborator

Are you using laravel-vite-plugin 0.7.3? I see the latest release has a fix for the base path, so it might be broken if you're on an older version

@HassanZahirnia
Copy link
Author

HassanZahirnia commented Jan 21, 2023

I tried out the repo that you linked above and it has the exact same problem:

That's weird, it worked for me when I tried it.

Are you using laravel-vite-plugin 0.7.3?

Yeah I'm using the latest. But I have not modified base config so that PR fix does not affect me. Not to mention I believe majority of Laravel users don't change the base config since the default is good enough.

Honestly I think until one of maintainers sit down and try this library with a Laravel backend, there is no way to debug and fix this issue properly.

@benmccann
Copy link
Collaborator

Could you provide a repository that reproduces the issue?

@HassanZahirnia
Copy link
Author

@benmccann Here is a reproduction repo: https://github.com/HassanZahirnia/laravel-imagetools-issue

Just in case you're not familiar with Laravel projects here are the instructions:

  1. Rename .env.example to .env
  2. Run composer install
  3. Run npm install
  4. Run php artisan key:generate
  5. Run php artisan serve in a terminal and keep it open
  6. In another terminal run npm run dev and also keep it open
  7. Visit the url given by the serve command (step 5)
  8. You can see the image fails to load since it's going through vite-imagetools plugin via the ?webp
  9. The file you want to edit/play with is resources/views/pages/welcome.vue

@hopkins385
Copy link

hopkins385 commented Jan 24, 2023

After updating to vite-imagetools v4.0.16 I can confirm the images are getting resolved in Dev mode \o/, in a Nuxt 3 environment. 👍 (Haven't checked Laravel yet)

<img src="/_nuxt/@imagetools/ac439a9cdb37db9a912abbf3f5fd377f36ecdab6">

@HassanZahirnia
Copy link
Author

Glad the tool is starting working with other frameworks such as Nuxt and Rails, but unfortunately the Laravel support is not there yet.

@hopkins385 I checked with 4.0.16 and it still doesn't work.

@hopkins385
Copy link

Agree, I've checked it with Laravel and still not working.

package.json (just for reference)

 "vite": "^4.0.4",
 "laravel-vite-plugin": "^0.7.3",
 "vite-imagetools": "^4.0.16",
 "imagetools-core": "^3.3.0",

@benmccann
Copy link
Collaborator

@driesvints @timacdonald any chance you'd be interested in taking a look at this one? It seems to occur exclusively with laravel-vite-plugin. For context, vite-imagetools is a Vite plugin for optimizing images. A Laravel-based reproduction was provided just above (#396 (comment)), but I don't have PHP or Composer installed on my machine. I'm happy to help from this side.

@timacdonald
Copy link

Hey folks, I have a working solution for this for the Laravel plugin.

For the Laravel folks in the thread, we will can shift out of here and into this issue: laravel/vite-plugin#194

tl;dr; We need to expose a way for developers to say "Please prefix /@imagetools with the Vite dev server URL while in dev mode.

- <img src="/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">
+ <img src="http://[::1]:5173/@imagetools/f0b2f404b13f052c604e632f2fb60381bf61a520">

PR will be up shortly.

@timacdonald
Copy link

See laravel/vite-plugin#195

@HassanZahirnia
Copy link
Author

Thanks for looking into this Tim ^_^ I've already given my impressions on the mentioned PR.

So for Laravel folks I can easily conclude the issue is resolved as Tim has given 2 different ways to solve this.
First is an official support from the laravel-vite-plugin (hope the PR gets merged soon~~) and the second one is a DIY example to get around this issue with existing tools.

Y'all have a great time and happy coding! 🌸😊

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

Successfully merging a pull request may close this issue.

5 participants