petitemo's avatar

How do I condition the use of certain assets to road groups in a Laravel project with Vite?

I have a Laravel 10 project using Vite. I succeed in compiling assets with this configuration :

vite.config.js

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

var config = {
    plugins: [
        laravel({
            input: [
                'resources/sass/app/appMaster.scss', 
                'resources/sass/admin/adminMaster.scss',
                'resources/sass/errors/errorsMaster.scss', 
                'resources/js/app.js'],
            refresh: true,

        }),
    ],
    build: {
        assetsDir: '',
    },
    server: {
        hmr: {
            host: 'localhost',
        },
    }

}

export default defineConfig(({command, mode, ssrBuild}) => {
    if (command === 'serve') {
        config.publicDir = 'public';
        config.build = {
            assetsDir: '',
            copyPublicDir: false,
            emptyOutDir: true,
        };
    }

    return config;
});

layout.blade.php

[...]
@vite(['resources/sass/app/appMaster.scss', 'resources/sass/admin/adminMaster.scss', 'resources/sass/errors/errorsMaster.scss', 'resources/js/app.js'])
[...]

As you can see my scss is split into three files. I have some routes groups and I don't want for example the adminMaster.scss to be used in app route group.

With laravel mix in an older project I'm using some middlewares to compiling assets according to the route group.

How can I do that with Vite?

I'm wondering if I have to make a different configuration because I understand that with

@vite(['resources/sass/app/appMaster.scss', 'resources/sass/admin/adminMaster.scss', 'resources/sass/errors/errorsMaster.scss', 'resources/js/app.js']) 

all scss files are loading and can't be conditioned.

Is anyone already did it or have an idea?

Thanks

0 likes
5 replies
gych's avatar

Not sure but have you tried to use @if directives already?

Something like this:

@vite(['resources/sass/app/appMaster.scss', 'resources/js/app.js'])

@if(Request::is('admin/*'))
    @vite(['resources/sass/admin/adminMaster.scss'])
@endif

@if(Request::is('errors/*'))
    @vite(['resources/sass/errors/errorsMaster.scss'])
@endif
petitemo's avatar

@gych It's a great idea! But have some different routes files and I want to acondition according to routes files, I searched for a laravel directive like Request::is() for routes files but I found nothing. Do you know if something like this exists? I also tried to deal it with middleware like this : Kernel.php

        'admin' => [
            'web',
            'auth:admin',
            \App\Http\Middleware\AssetsAdmin::class,
        ],

AssetsAdmin.php

<?php

namespace App\Http\Middleware;

use Closure;
use Assets;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AssetsAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        Assets::css('adminMaster-XXXXXXXX.css');

        return $next($request);
    }
}

But Vite generates css files with a random key. I'm wondering if it's correcet to deal it with regex? Is it better to do this way?

gych's avatar

@petitemo This won't work with regex because its not able to figure out the complete name of the builded asset.

Can you try by using Vite:asset() instead

Add this to the file:

use Illuminate\Support\Facades\Vite;

Use this in the handle method

Vite::asset(adminMaster.css)
petitemo's avatar

@gych It seems right but it doesn't work on development (npm run dev): no error but css doesn't load. And with build (npm run build): it throw me an error : Unable to locate file in Vite manifest: adminMaster.css. Here is the part of the manifest.json file that is concerned :

  "resources/sass/admin/adminMaster.scss": {
    "file": "adminMaster-hkIQ4DnX.css",
    "isEntry": true,
    "src": "resources/sass/admin/adminMaster.scss"
  },
martinbean's avatar

@petitemo Surely your admin panel is using a different layout to the rest of the site?

<!-- resources/views/layouts/frontend.blade.php -->
@vite([
    'resources/sass/app/appMaster.scss',
    'resources/js/app.js',
])
<!-- resources/views/layouts/admin.blade.php -->
@vite([
    'resources/sass/admin/adminMaster.scss',
])

Please or to participate in this conversation.