Using Laravel Vite with Bootstrap and Sass

David
30 June 2022

This week, Laravel has announced they're migrating from Webpack to Vite.

Every new project will use Vite to bundle frontend assets, but they also published a migration guide to migrate existing projects. However, if your project uses Sass (like Bootstrap requires) to bundle assets, the upgrade guide does not cover that case.

There's still no official guide to set up Bootstrap with Vite, but they're working on it, and you can already preview it.

If we merge both guides, the migration process is still simple and fast!

Migrating from Laravel Mix to Vite with Bootstrap and Sass

First, you will need to install Vite and the Laravel Vite Plugin using your npm package manager of choice:

npm install --save-dev vite laravel-vite-plugin

As your current project already uses Boostrap and Sass, you probably already have its dependencies. If you are setting up a new project, you will need to install it:

npm install --save-dev sass bootstrap @popperjs/core

Configure Vite

Create a vite.config.js file at the root of your project:

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

export default defineConfig({
    plugins: [
        laravel([
            'resources/js/app.js',
        ]),
    ],
    resolve: {
        alias: {
            '~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
        }
    },
})

In your existing Bootstrap project, you probably also referred your CSS/Sass file directly in Laravel Mix. With Vite, we only use the JavaScript file as entry point and then import our CSS/Sass file from JavaScript.

NPM script

Update your NPM scripts in package.json:

  "scripts": {
-     "dev": "npm run development",
-     "development": "mix",
-     "watch": "mix watch",
-     "watch-poll": "mix watch -- --watch-options-poll=1000",
-     "hot": "mix watch --hot",
-     "prod": "npm run production",
-     "production": "mix --production"
+     "dev": "vite",
+     "build": "vite build"
  }

Vite compatible imports

Vite only supports ES modules, so if you are upgrading an existing application, you will need to replace any require() statements with import. You may refer to this pull request for an example.

Import Bootstrap

  1. Import Bootstrap's CSS. Add the following to resources/sass/app.scss to import all of Bootstrap’s source Sass:
// Import all of Bootstrap's CSS
@import "~bootstrap/scss/bootstrap";
  1. Load the CSS and import Bootstrap's JavaScript. Modify your resources/js/app.js or resources/js/bootstrap.js to load the CSS and import all of Bootstrap's JS. Popper will be imported automatically through Bootstrap:
- const bootstrap = require('bootstrap')
- window.bootstrap = bootstrap
+ // Import our custom CSS
+ import '../sass/app.scss'
+ 
+ // Import all of Bootstrap's JS
+ import * as bootstrap from 'bootstrap'

Replace mix() with @vite

When using Vite, you will need to use the @vite Blade directive instead of the mix() helper.

This will automatically detect whether you are running in serve or build mode and include all of the required <script> and <link rel="stylesheet"> for you:

- <link rel="stylesheet" href="{{ mix('css/app.css') }}">
- <script src="{{ mix('js/app.js') }}" defer></script>
+ @vite(['resources/js/app.js'])

You shouldn't include your CSS file here as it'll be imported through JavaScript.

Remove Laravel Mix

Finally, the Laravel Mix package and its Webpack dependencies can now be uninstalled:

npm remove laravel-mix resolve-url-loader sass-loader
rm webpack.mix.js

Depending on your deploy strategy, you may wish to add Vite's build directory to your .gitignore file:

/public/build