web-application-framework laravel

This guide walks through installing Vite in a Laravel project that runs inside a Docker container on WSL.

References

What is Vite?

Vite is a frontend build tool that provides a fast development server and commands to build CSS and JavaScript files.
In development, Vite updates CSS and JavaScript dynamically, enabling smooth development. In production, it builds and optimizes your assets for better performance.

Environment

  • Windows 10 64-bit
  • Ubuntu 22.04.3 LTS (running on WSL)
  • Docker Engine 26.0.0
  • Amazon Linux 2023(OS of the Docker container)
  • PHP 8.2.15 (fpm-fcgi)
  • NGINX 1.24.0
  • Laravel 11

Prerequisites

  • You have a Docker container running a Laravel project on WSL (using Docker Compose).
    For running a Laravel project with NGINX, refer to this article.

Installation Steps

  1. Install Node.js
  2. Install Vite
  3. Configure Vite
  4. Configure the Docker Container
  5. Prepare to Test Vite
  6. Verify That Vite is Working

1. Install Node.js

Refer to this guide for Node.js installation.

2. Install Vite

Vite can be installed using the package.json file that is generated by default when creating a Laravel project.
Since Vite is already included in the default package.json, just run the following command in the Laravel project root:

npm install

Here’s an example of the package.json generated in my environment:

package.json :

{
    "private": true,
    "type": "module",
    "scripts": {
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "axios": "^1.6.4",
        "laravel-vite-plugin": "^1.0",
        "vite": "^5.0"
    }
}

3. Configure Vite

To run Vite inside a Docker container, update the vite.config.js in your Laravel project root:

vite.config.js :

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

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
    // Add the following
    server: {
        host: true,
        hmr: {
            host: 'localhost',
        },
    },
});

server.host: specifies the IP address that the server should listen on.
By default, it only listens to localhost, but setting it to 0.0.0.0 or true will allow it to listen to all addresses.
This makes it possible to access the server inside the container from the Docker host.

server.hmr.hostspecifies the IP address for HMR (Hot Module Replacement) communication.
Since the address is within the Docker container, we set it to localhost. HMR allows CSS and JavaScript files to be updated dynamically without reloading the browser.

When your Laravel project is on the Windows file system

If your Laravel project is located under the Windows file system, such as under /mnt/c in WSL, you also need to add the watch setting.
This is necessary to detect changes to HTML or JavaScript files.

vite.config.js :

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

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
    server: {
        host: true,
        hmr: {
            host: 'localhost',
        },
        // Add the following
        watch: {
            usePolling: true,
            interval: 1000,
        },
    },
});

server.watch.usePolling enables polling to detect file changes.
WSL can only detect changes to files on the Windows file system via polling, so set it to true.
Polling can increase CPU usage, so reduce its frequency by setting server.watch.interval to 1000 (1 second).

Polling is generally discouraged due to performance concerns.
It’s better to place your Laravel project outside the Windows file system, such as under /home.

4. Configure the Docker Container

Change the port settings for your Docker container.

In your Laravel project’s Docker container settings, expose port 5173 for Vite’s HMR.
Update your docker-compose.yml as follows:

docker-compose.yml :

services:
  web:  # The container running the Laravel project
    ...
    ports:
    - 8080:80     # Expose port 80 for HTTP
    - 5173:5173   # Expose port 5173 for Vite HMR ← Add this
    ...

5. Prepare to Test Vite

Create a test JavaScript file in the resources/js directory:

test.js :

console.log('test');

Open vite.config.js and add test.js to the entry points:

vite.config.js :

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

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
                'resources/js/test.js', // Added
            ],
            refresh: true,
        }),
    ],
    server: {
        host: true,
        hmr: {
            host: 'localhost',
        },
    },
});

Create a Blade template under resources/views named test.blade.php and load the test.js file with @vite:

test.blade.php :

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <meta charset="utf-8" />
  @vite(['resources/js/test.js'])
</head>
<body>
</body>
</html>

Add the following route to routes/web.php so that accessing / displays the test view:

web.php :

Route::get('/', function () {
    return view('test');
});

6. Verify That Vite is Working

To verify that Vite is working, try two methods: starting the development server and building for production.

Start the Development Server

Start the development server so CSS and JavaScript files are updated dynamically.

In the root directory of your Laravel project, run the following command:

npm run dev

Access / in your browser.
You should see the output from console.log('test') in the browser’s developer console, indicating that resources/js/test.js is working.

If you modify resources/js/test.js as follows:

test.js :

console.log('hello');

You will see the updated result reflected in the browser without a reload, confirming that HMR is working.

Build for Production

To build optimized CSS and JavaScript files, run:

npm run build

The built assets will be output under the public/build/assets directory.

Access / in the browser and check the developer console again.
You should see the output from console.log('test').

When using built files, changes to resources/js/test.js will not automatically reflect in the browser.
You must re-run the build after making changes.