javascriptgulpgulp-4

Trouble with splitting gulpfile.js into multiple files in Gulp 4


I am a beginner to Javascript and Gulp. Am learning this based on a udemy course in which Gulp 3 is being used, and I've been looking at docs to convert the code to Gulp 4. It's been fun so far since I am learning more when I am doing the conversions myself, but am stuck on this one. Wonder if you guys can offer some advice.

Issue: When I split the gulpfile.js into separate files to organise my files better, it starts throwing errors. Code below.

styles.js

var gulp = require('gulp'),
    postcss = require('gulp-postcss'),
    autoprefixer = require('autoprefixer'),
    cssvars = require('postcss-simple-vars'),
    nested = require('postcss-nested'),
    cssImport = require('postcss-import');


function styles(cb) {
    return gulp.src('./app/assets/styles/styles.css')
    .pipe(postcss([cssImport, cssvars, nested, autoprefixer]))
    .pipe(gulp.dest('./app/temp/styles'));
    cb();
}

exports.styles = styles;

watch.js

var gulp = require('gulp'),
browserSync = require('browser-sync').create();


function cssInject(cb) {
    return gulp.src('./app/temp/styles/styles.css')
    .pipe(browserSync.stream());
    cb();
}

function browserSyncReload(cb) {
    browserSync.reload();
    cb();
}

function watch(cb) {
    browserSync.init({
        notify: false,
        server: {
            baseDir: "app"
        }
    });
    watch('./app/index.html', browserSyncReload);
    watch('./app/assets/styles/styles.css', gulp.series(cssInject, styles));
    cb();
}

exports.browserSyncReload = browserSyncReload;
exports.watch = watch;

gulpfile.js

var stylesTasks = require('./gulp/tasks/styles.js'),
    watchTasks = require('./gulp/tasks/watch.js');

    
exports.watch = watchTasks.watch;
exports.styles = stylesTasks.styles;
exports.browserSyncReload = watchTasks.browserSyncReload;

When I run "gulp watch", this is what I get.

error

$ gulp watch
[21:14:28] Using gulpfile ~/Projects/travel-site/gulpfile.js
[21:14:28] Starting 'watch'...
internal/async_hooks.js:195
function emitInitNative(asyncId, type, triggerAsyncId, resource) {                      ^

RangeError: Maximum call stack size exceeded
(Use `node --trace-uncaught ...` to show where the exception was thrown)

I found another post with almost identical code, but with a different error - which happened to be one of the errors i was getting earlier as well, and have followed the solution mentioned in that post - and that's when I get this error. Here's the link to the post.

Any help is much appreciated. Thanks for your time.


Solution

  • Answering my own question feels wierd, but I found the solution after playing with it for couple of days. See below.

    I needed to import styles into watch.js, and not gulpfile.js. That was my first mistake. To do this, I added the below line to watch.js

    var styles = require('./styles').styles;
    

    Then my gulpfile.js only needed two lines

    gulpfile.js

    var watchTask = require('./gulp/tasks/watch').watch;
    exports.default = watchTask;
    

    I also removed the variable gulp, instead created variables for src and dest. So, the rest of the code looked like below.

    styles.js

    var {src, dest} = require('gulp'),
        postcss = require('gulp-postcss'),
        autoprefixer = require('autoprefixer'),
        cssvars = require('postcss-simple-vars'),
        nested = require('postcss-nested'),
        cssImport = require('postcss-import');
    
    const styles = function (cb) {
        return src('./app/assets/styles/styles.css')
        .pipe(postcss([cssImport, cssvars, nested, autoprefixer]))
        .pipe(dest('./app/temp/styles'));
        cb();
    }
    
    exports.styles = styles;
    

    watch.js

    var styles = require('./styles').styles;
    var {src, series, watch} = require('gulp'),
        browserSync = require('browser-sync').create();
    
    const cssInject = function (cb) {
        return src('./app/temp/styles/styles.css')
        .pipe(browserSync.stream());
        cb();
    }
    
    const reload = function (cb) {
        browserSync.reload();
        cb();
    }
    
    const watchTask = function (cb) {
        browserSync.init({
            notify: false,
            server: {
                baseDir: "app"
            }
        });
        watch('./app/index.html', reload);
        watch('./app/assets/styles/styles.css', series(cssInject, styles));
        cb();
    }
    
    exports.watch = watchTask;
    

    Hence resolved! hope this helps someone else.