Map gulp.task over multidimensional array

729 Views Asked by At

Information about the project

I'm developing a more complex website which requires several stylesheets for the frontend and the backend that are loaded only if some specific conditions match.

I'm developing in scss and compiling the files using gulp.

In my gulpfile I then declare an array with all the frontend stylesheets and another array containing the backend ones. Here is how it currently looks like. It's not finished though.

const cssFront     = [ 'style.scss' ];
const cssBack      = [ 'admin.scss', 'settings.admin.scss' ];
let cssFiles       = [ cssFront, cssBack ];

What the code should do

Gulp should now map over all the files in cssFiles and compile the css code of those files.

What I have done

However map-functions only work one dimensional, so I tried to reduce the two dimensional array to a one dimensional one and then map over it.

const sass         = require( 'gulp-sass' );
const autoprefixer = require( 'gulp-autoprefixer' );

const styleSRC     = './src/scss/';
const cssFront     = [ 'style.scss' ];
const cssBack      = [ 'admin.scss', 'settings.admin.scss' ];
let cssFiles       = [ cssFront, cssBack ];
const styleURL     = './assets/css/';
const mapURL       = './';

gulp.task( 'scss', function() {
    cssFiles = cssFiles.reduce(function(a, b){
        return a.concat(b);
    });

    cssFiles.map( function( file ) {
        return gulp.src( styleSRC + file )
        .pipe( sourcemaps.init() )
        .pipe( sass({
            errLogToConsole: true,
            outputStyle: 'compressed'
        }) )
        .on( 'error', console.error.bind( console ) )
        .pipe( autoprefixer({ browsers: [ 'last 2 versions', '> 5%', 'Firefox ESR' ] }) )
        .pipe( rename( { suffix: '.min' } ) )
        .pipe( sourcemaps.write( mapURL ) )
        .pipe( gulp.dest( styleURL ) )
        .pipe( browserSync.stream() );
    });
});

The problem

The reduce-function works well. I did a console.log and the output was:

['style.scss', 'admin.scss', 'settings.admin.scss']

If running the task directly ($ gulp scss) this code works perfectly, the files are all compiled and saved under assets/css/, however if I run $ gulp watch, I receive an error message saying

cssFiles.map is not a function

Due to this error message I assume that there is a better way of writing this gulp.task. I'd be very pleased if anyone could help me out with this.

1

There are 1 best solutions below

1
On BEST ANSWER

Problem in watch task.
When you first run the task - you do reduce for cssFiles (several arrays [ cssFront, cssBack ])

This result is saved in your variable cssFiles with new value ['style.scss', 'admin.scss', 'settings.admin.scss']

When watch task run next time it will reduce already resulted array ['style.scss', 'admin.scss', 'settings.admin.scss'] and new result is string "style.scssadmin.scsssettings.admin.scss" and save in cssFiles variable

after that you get error cssFiles.map is not a function
because "style.scssadmin.scsssettings.admin.scss".map() -> is not a function

You need to do reduce outside the function with you task

cssFiles = cssFiles.reduce(function(a, b){
    return a.concat(b);
});

gulp.task( 'scss', function() {
    cssFiles.map( function( file ) {
        // ...
    });
});