vite-plugin: HMR not working with Laravel Sail in WSL2

  • Laravel Vite Plugin Version: 2.9.13
  • Laravel Version: 9.19.0
  • Node Version: 16.15.1
  • NPM Version: 8.11.0
  • Windows 10 with WSL2
  • Docker Desktop 4.8.1 (78998) using WSL2 backend

Description:

Setting up a new Laravel project with Sail on Windows. The app and asset bundling works, but HMR is not triggered when updating resources, or even when manually refreshing the tab.

The blade template calls @vite(['resources/css/app.css', 'resources/js/app.js']) in the <head> section. App loads successfully, including styles. The dev tools console shows both [vite] connecting... and [vite] connected. Saving a change to a resource file does not trigger a browser update, and even manually refreshing does not work. (The route loads, but with stale resources).

Steps To Reproduce:

  • Connect to WSL instance in Terminal, and install Laravel via curl -s https://laravel.build/example-app | bash
  • cd and run npm install
  • From the WSL connected Terminal npm run dev. (I can see ready in 3523ms and my APP_URL)
  • Load the app in the browser (e.g. http://example-app.test) with a view that uses the @ vite helper
  • The page loads as expected, console shows [vite] connected
  • Changing and saving resources/css/app.css does not update the browser. Dev console shows no requests or errors
  • Force refreshing shows no changes
  • Manually opening the CSS link in a new tab (e.g. http://127.0.0.1:3000/resources/css/app.css) shows the updated content. If you save another change to the CSS and refresh this tab the changes will show
  • Changing the <link href> attribute on the style link in the main tab to append a cache-bust query parameter (e.g. http://127.0.0.1:3000/resources/css/app.css?v=2) does trigger the new style
  • Apart from manually changing the URL like that I need to stop and restart the npm run build server and then reload the tab to see changes.

Vite Config

Using the default vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
    ],
});

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 21 (5 by maintainers)

Most upvoted comments

Wait for the latest release and there will be a fix for this issue.

refer to https://github.com/laravel/vite-plugin/pull/42#issue-1289410988

and add this in your vite config

server: {
        hmr: {
            host: 'localhost',
        },
    }

Hey @mike-healy, that fix primarily helps when running Vite inside a Docker container that is inside WSL. I don’t think it will solve your issue as you are already able to connect to Vite’s dev server.

I believe you’ll want to set server.watch.usePolling in your vite.config.js file:

server: {
    watch: {
        usePolling: true,
    }
}

Thanks @bradleybernard and @jessarcher . I got it working by running the npm dev server outside of WSL (and I did not need that server hmr localhost block once I did either).

So in my case I needed to install nvm and node directly on Windows using this guide. (I already had them inside the WSL2 Ubuntu virtual machine)

Then I started Sail from within WSL, the dev server from outside of WSL2 and the hot reloading worked perfectly 😃

Just wanted to comment on this since this solved my issue with Laravel + Vite + Homestead!

I was running into an issue where HMR wasn’t working and ws connection was failling so Vite didn’t HMR any updates to files.

My setup (as a data point):

  • Laravel Homestead running as a VM
  • Vite server running locally (outside homestead ssh tunnel)

With that setup, things weren’t working “out of the box” after following the migration guide and running the dev server: npm run dev.

I went to the repo and looked through closed issues and found this one. So I added the snippet above to my vite.config.js:

server: {
        hmr: {
            host: 'localhost',
        },
    }

That solved the problem! My browser is able to successfully establish a websocket connection to the Vite build server and HMR then worked! @jessarcher I think it’s worth calling out in the migration guide, especially since Laravel Homestead is an official Laravel tool, I’m sure more folks will run into this.

Thanks again for all your work on this (+ others). Now that it is setup, loving it!!

Hey @timacdonald .

  • Visiting at http://localhost and http://example-app.test work the same way for me (same problems & the same parts work).
  • I was not using polling before. I just tried it. It very barely kind of works. When I save the CSS file I get an instant message in the console saying [vite] css hot updated: /resources/css/app.css, but then it takes a huge amount of time for the request to actually happen (about 15 seconds). The other requests like loading the app take more like 400-1500ms
  • I do actually need the hmr: { host: 'localhost' } too, otherwise it attempts to load assets from http://0.0.0.0 which fails.

If I open a new tab directly to http://localhost:5173/resources/css/app.css and manually refresh it loads in ~30ms.

Even without polling there is some sort of connection to the dev server, because if I stop it, the console instantly shows a message saying the connection was lost, and I start to see the ping requests giving 404s. Yet saving the CSS file does not trigger HMR (without polling).

@timacdonald , @jessarcher FWIW I am having the same issue as before with v0.3.0 of the plugin in WSL. The initial app response works, including CSS. Changes do not hot reload, even if I refresh the tab. I have to stop and start the dev server too see CSS changes take effect.

I am using this block in the config

server: {
        hmr: {
            host: 'localhost'
        },
    },

As before if run the dev server from my host machine things work as expected.