Skip to content

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.

Answer

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.