Dwight Watson's blog

Migrating from Laravel Mix to Vite

June 26, 2022

Laravel's default asset bundler is about to switch from Laravel Mix (Webpack) to a wrapper around Vite. I've had a crack at migrating over early starting with some older apps that still use Vue with inline templates and Sass.

Because of the awkwardness of moving these older apps over I ran into some funky edge cases which I thought would be worth making a note of in case they were helpful.

Autoloading Vue components

You can use import.meta.globEager to fetch a directory and then loop over it to autoload components. This is similar to how it worked with Webpack - using some string magic to convert the filename to a component name.

const app = createApp({});

const components = import.meta.globEager("./components/**/*.vue");

Object.entries(components).forEach(([path, definition]) => {
  app.component(path.split("/").pop().split(".")[0], definition.default);
});

app.mount("#app");

Importing Font Awesome/Bootstrap through Sass

You can use Sass with Vite by simply installing the sass dependency. Previously you could import third-party stylesheets by prefixing the vendor name with ~ but that is no longer required and you can import the whole path.

$fa-font-path: "@fortawesome/fontawesome-free/webfonts";
@import "@fortawesome/fontawesome-free/scss/fontawesome";
@import "@fortawesome/fontawesome-free/scss/solid";

@import "variables";
$icon-font-path: "bootstrap-sass/assets/fonts/bootstrap/";
@import "bootstrap-sass/assets/stylesheets/bootstrap";

Use the ESM bundler version of Vue

Because my Laravel app isn't a full Vue front-end and instead uses Vue sprinkles I needed to adjust the version of Vue used by Vite. Here's the error received when trying to run the app:

runtime-core.esm-bundler.js:38 [Vue warn]: The `compilerOptions` config option is only respected when using a build of Vue.js that includes the runtime compiler (aka "full build"). Since you are using the runtime-only build, `compilerOptions` must be passed to `@vue/compiler-dom` in the build setup instead.
- For vue-loader: pass it via vue-loader's `compilerOptions` loader option.
- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader
- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom
(anonymous) @ app.js:24
runtime-core.esm-bundler.js:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>

In your vite.config.js you just need to add the resolve key to point vue to the alternate build.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    resolve: {
        alias: {
            vue: "vue/dist/vue.esm-bundler.js"
        }
    },

    plugins: [
        laravel([
            'resources/sass/app.scss',
            'resources/js/app.js',
        ]),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
});

A blog about Laravel & Rails by Dwight Watson;
developer of Roomies.com, myRent.co.nz, High School Notes & StudentVIP.com.au.

Follow me on Twitter, or GitHub.