Laravel-mix: How to build multiple css files?

Created on 9 Jan 2017  路  26Comments  路  Source: JeffreyWay/laravel-mix

This works:

mix
  .js('assets/js/admin.js', 'dist/js/')
  .js('assets/js/frontend.js', 'dist/js/')
;

However, this doesn't:

mix
  .sass('assets/sass/admin.scss', 'dist/css/')
  .sass('assets/sass/frontend.scss', 'dist/css/')
;

It results in the following error:

Error: Laravel Mix: Limit your "mix.sass()" calls to one.

Is this a bug or an intended limitation?

Most helpful comment

I just pushed support for this to master. Hasn't been tagged yet, but will soon. So you can soon do:

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .sass('resources/assets/sass/other.scss', 'public/css')

And that will create public/css/app.css and public/css/other.css.

All 26 comments

Ran into the same thing, cant give an array as the first paramater either

It's not a bug, since we told you that you can only call .sass() once right now.

But I have plans to add support for this.

Awesome

I just pushed support for this to master. Hasn't been tagged yet, but will soon. So you can soon do:

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .sass('resources/assets/sass/other.scss', 'public/css')

And that will create public/css/app.css and public/css/other.css.

@JeffreyWay has then been done yet? I'm still getting errors when trying to compile multiple .css files with SASS, just installed a fresh copy of Laravel.

mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css')
.sass('resources/assets/sass/other.scss', 'public/css')

--Not working yet?

@lancevjm It is definitely working as I am using them.

What is your Laravel Mix version anyway?

@ruchern Think its the latest, 0.11.4, I've reloaded everything, fresh laravel, and node modules with laravel-mix, i've uninstalled node and reinstalled and still have the same error. I get an error when compiling. It lists the admin.scss file as a dependency which is not installed. If I remove the extra .scss file then it compiles perfectly. Any ideas?

error:

This dependency was not found:

  • "Path"\resources\assets\sass\admin.scss in multi ./resources/assets/js/app.js ./resources/assets/sass/a
    pp.scss ./resources/assets/sass/admin.scss

To install it, you can run: npm install --save "Path"\resources\assets\sass\admin.scss

It does sounds like your admin.scss is not in resources/assets/sass/admin.scss

omw, I'm so sorry. I had an "_" infront of admin.scss. removed the underscore and updated the Preprocessor.js file for laravel mix (line 57) to the below and all is fine again :-)

test() {
return new RegExp(this.src.file.replace(/\/g, '\\') + '$');
}

@JeffreyWay Hi there. What about *.scss several files in folder?
Right now, instead of this:

mix.sass('resources/assets/sass/global/*.scss', 'public/assets/global/css');
mix.sass('resources/assets/sass/apps/*.scss', 'public/assets/apps/css');
mix.sass('resources/assets/sass/pages/*.scss', 'public/assets/pages/css');

mix.sass('resources/assets/sass/layouts/layout2/*.scss', 'public/assets/layouts/layout2/css');
mix.sass('resources/assets/sass/layouts/layout2/themes/*', 'public/assets/layouts/layout2/css/themes');

I should do something like that:

let fs = require( 'fs' );
let path = require( 'path' );
let process = require( "process" );

let arrayOfPath = [
    {
        from : 'resources/assets/sass/global/',
        to : 'public/assets/global/css'
    },
    {
        from : 'resources/assets/sass/apps/',
        to : 'public/assets/apps/css'
    },
    {
        from : 'resources/assets/sass/pages/',
        to : 'public/assets/pages/css'
    },
    {
        from : 'resources/assets/sass/layouts/layout2/',
        to : 'public/assets/layouts/layout2/css'
    },
    {
        from : 'resources/assets/sass/layouts/layout2/themes/',
        to : 'public/assets/layouts/layout2/css/themes'
    }
];

arrayOfPath.forEach(function (pathway) {
    fs.readdir( pathway.from, function( err, files ) {
        if( err ) {
            console.error( "Could not list the directory.", err );
            process.exit( 1 );
        }
        files.forEach( function( file, index ) {
            if(path.extname(file) === '.scss'){
                mix.sass(pathway.from + file, pathway.to);
            }
        });
    });
});

What you think about that?

@VRuzhentsov In which file i have to write this code??

@VRuzhentsov I think you must use readdir synchronously though.

I tried to use fs in order to do what @VRuzhentsov wants to do, and any calls to mix within the fs.readdir callback do not seem to fire. I'm seeing console.log outputs, but no other outputs per a typical compile. Code below:

let mix = require('laravel-mix');
let fs  = require('fs');

// mix.copy('resources/assets/sass/custom/', 'public/css');

var path = __dirname + "/resources/assets/sass/custom/";

fs.readdir(path, function(err, items) {
    console.log(items);

    for (var i=0; i<items.length; i++) {
        mix.sass(items[i], 'public/css');
    }

    mix.js('resources/assets/js/app.js', 'public/js')
      .sass('resources/assets/sass/app.scss', 'public/css');
});

A previous version of this file was simpler:

mix.js('resources/assets/js/app.js', 'public/js')
      .sass('resources/assets/sass/app.scss', 'public/css');
mix.copy('resources/assets/sass/custom/', 'public/css');

No synchronicity required. The only problem is that this breaks the folder pattern, and forcing a developer to switch between using CSS for custom resources and SCSS for primary resources seems like an unnecessary headache.

Any thoughts?

let mix = require('laravel-mix');

function mix_scss_files(folder) {
    let fs = require('fs');
    var relative_path = "resources/assets/sass" + folder;
    var paths = fs.readdirSync(relative_path);
    for (var i = 0; i < paths.length; i++) {
        if (paths[i].indexOf('.scss') > 0 && paths[i].charAt(0) != '_') {
            var file_path = relative_path + paths[i];
            console.log(file_path);
            mix.sass(file_path, 'public/css' + folder);
        }
    }
}
// sass root folder
mix_scss_files('/');
// sass subfolder resources/assets/sass/custom , trailing slash is necessary
mix_scss_files('/custom/');

mix.js('resources/assets/js/app.js', 'public/js');

That was very helpful, @pmua . Thank you.

I just pushed support for this to master. Hasn't been tagged yet, but will soon. So you can soon do:

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .sass('resources/assets/sass/other.scss', 'public/css')

And that will create public/css/app.css and public/css/other.css.

Does this still work? Mine generates the .css files but they are empty.

@benmcm1994 I'm wondering this too. I'm getting the same problem.

I reverted to an older version (v3) and it works.

You can call sass multiple times and use fs/path to iterate over files for mix.

const fs = require('fs');
const path = require('path');
const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js');

const files = fs.readdirSync(path.resolve(__dirname, 'resources', 'sass', 'site'), 'utf-8')  

for (let file of files) {
   mix.sass(`resources/sass/site/${file}`, 'public/css');
}

Check this out

/*
* Admin JS
* */
mix.setResourceRoot('/public/assets/admin/')
    .js('resources/js/app.js', 'public/assets/admin/')
    .version();
/*
* Admin Styles
* */
mix.styles([
    'public/assets/admin/plugins/bootstrap/css/bootstrap.min.css',
    'public/assets/admin/css/style.min.css',
], 'public/assets/admin/app.css');
mix.sass('resources/sass/app.scss', 'public/assets/admin/app.css').options({
        postCss: [
            require('autoprefixer'),
        ],
    }).version();
/*
* Admin Fonts
* */
mix.copyDirectory('public/assets/admin/fonts', 'public/assets/fonts');

anyone knows why doesnt async readdir works when used like :
fs.readdir(path,function(err,files){ files.forEach(function(file,index){ mix.js('some/path/' + file,'public/js/gallery/'); }); });
it doesnt compile the files when in async mode, it finds the files but doesnt do anything, no errors
it only works in sync mode

@izatunela I think it's ok to use readdirSync in this instance as you're not dealing with potential deadlock issues to list a directory locally or in a CI environment

@cwilby I understand that but I was jut curious as to literally why doesnt it work when I put mix.js(...) in async callback of readdir while it works when using readdirSync?
are there some race conditions that are happening or something?

thank you so much @pmua !

If nothing worked, try something like this:

   mix.sass('resources/assets/app.scss', 'public/css');

And then you can attach another scss file with .styles.

mix.styles('resources/assets/sass/pages/another.scss', 'public/css/another.css');

hi geniuses) i don't very clever but sometimes i read documentation like this:
https://laravel.com/docs/7.x/mix#sass
link rel="stylesheet" href="{{ mix('css/app.css') }}" /
link rel="stylesheet" href="{{ mix('css/carousel/carousel.css') }}" /
best regards

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bomavi picture Bomavi  路  3Comments

kpilard picture kpilard  路  3Comments

hasnatbabur picture hasnatbabur  路  3Comments

rlewkowicz picture rlewkowicz  路  3Comments

wendt88 picture wendt88  路  3Comments