Skip to content

Instantly share code, notes, and snippets.

@jeromecoupe
Last active January 21, 2024 16:28
Show Gist options
  • Save jeromecoupe/0b807b0c1050647eb340360902c3203a to your computer and use it in GitHub Desktop.
Save jeromecoupe/0b807b0c1050647eb340360902c3203a to your computer and use it in GitHub Desktop.
Gulp 4 sample gulpfile.js. For a full explanation, have a look at https://www.webstoemp.com/blog/switching-to-gulp4/
"use strict";
// Load plugins
const autoprefixer = require("autoprefixer");
const browsersync = require("browser-sync").create();
const cp = require("child_process");
const cssnano = require("cssnano");
const del = require("del");
const eslint = require("gulp-eslint");
const gulp = require("gulp");
const imagemin = require("gulp-imagemin");
const newer = require("gulp-newer");
const plumber = require("gulp-plumber");
const postcss = require("gulp-postcss");
const rename = require("gulp-rename");
const sass = require("gulp-sass");
const webpack = require("webpack");
const webpackconfig = require("./webpack.config.js");
const webpackstream = require("webpack-stream");
// BrowserSync
function browserSync(done) {
browsersync.init({
server: {
baseDir: "./_site/"
},
port: 3000
});
done();
}
// BrowserSync Reload
function browserSyncReload(done) {
browsersync.reload();
done();
}
// Clean assets
function clean() {
return del(["./_site/assets/"]);
}
// Optimize Images
function images() {
return gulp
.src("./assets/img/**/*")
.pipe(newer("./_site/assets/img"))
.pipe(
imagemin([
imagemin.gifsicle({ interlaced: true }),
imagemin.jpegtran({ progressive: true }),
imagemin.optipng({ optimizationLevel: 5 }),
imagemin.svgo({
plugins: [
{
removeViewBox: false,
collapseGroups: true
}
]
})
])
)
.pipe(gulp.dest("./_site/assets/img"));
}
// CSS task
function css() {
return gulp
.src("./assets/scss/**/*.scss")
.pipe(plumber())
.pipe(sass({ outputStyle: "expanded" }))
.pipe(gulp.dest("./_site/assets/css/"))
.pipe(rename({ suffix: ".min" }))
.pipe(postcss([autoprefixer(), cssnano()]))
.pipe(gulp.dest("./_site/assets/css/"))
.pipe(browsersync.stream());
}
// Lint scripts
function scriptsLint() {
return gulp
.src(["./assets/js/**/*", "./gulpfile.js"])
.pipe(plumber())
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
}
// Transpile, concatenate and minify scripts
function scripts() {
return (
gulp
.src(["./assets/js/**/*"])
.pipe(plumber())
.pipe(webpackstream(webpackconfig, webpack))
// folder only, filename is specified in webpack config
.pipe(gulp.dest("./_site/assets/js/"))
.pipe(browsersync.stream())
);
}
// Jekyll
function jekyll() {
return cp.spawn("bundle", ["exec", "jekyll", "build"], { stdio: "inherit" });
}
// Watch files
function watchFiles() {
gulp.watch("./assets/scss/**/*", css);
gulp.watch("./assets/js/**/*", gulp.series(scriptsLint, scripts));
gulp.watch(
[
"./_includes/**/*",
"./_layouts/**/*",
"./_pages/**/*",
"./_posts/**/*",
"./_projects/**/*"
],
gulp.series(jekyll, browserSyncReload)
);
gulp.watch("./assets/img/**/*", images);
}
// define complex tasks
const js = gulp.series(scriptsLint, scripts);
const build = gulp.series(clean, gulp.parallel(css, images, jekyll, js));
const watch = gulp.parallel(watchFiles, browserSync);
// export tasks
exports.images = images;
exports.css = css;
exports.js = js;
exports.jekyll = jekyll;
exports.clean = clean;
exports.build = build;
exports.watch = watch;
exports.default = build;
@jeromecoupe
Copy link
Author

jeromecoupe commented Sep 16, 2019

@kennblvnp Thanks for the kind words. All required packages are listed at the top of the gulpfile. Both the old version of my site (where this came from originally) and the new one are publicly available on Github so that might help too. V1 is on the v1-backup branch.
https://github.com/jeromecoupe/webstoemp/blob/v1-backup/gulpfile.js

@NorthaHuang
Copy link

thank you so mush!
It's help a lot!

@shirblc
Copy link

shirblc commented Oct 26, 2019

Thank you so much for this! I spent so long trying to figure out Gulp 4 after Gulp 3.9 but this made it so much clearer.

@myquery
Copy link

myquery commented Oct 27, 2019

Am new to gulp, but am just curious, where do you import or use the exported functions. Thanks for sharing

@jeromecoupe
Copy link
Author

jeromecoupe commented Oct 31, 2019

@myquery The short answer is that you don't import when using a singe file. CommonJS exports are just Gulp4's way to expose tasks to the CLI to make them public. Non exported tasks are considered private (used only as subtasks) https://gulpjs.com/docs/en/getting-started/creating-tasks#exporting

That being said, you can require / alias them in your main file if your main file is becoming too big / complex. You can have a look at the code of my own site for an example https://github.com/jeromecoupe/webstoemp/blob/master/gulpfile.js

@raugustin93
Copy link

Thank you, this is a perfect reference point.

@fayazrehmani
Copy link

Thanks, but I have a suggestion that it would really help if you can add sample folder structure and text file with commands so it can we started by anyone.

@GV94
Copy link

GV94 commented Dec 3, 2019

Thanks a lot for this, tremendous help when going from v.3.9.1 to v4.x of gulp!

@linorallo
Copy link

It finally worked, thanks a lot!

@poanchen
Copy link

Thanks a lot. Helped me to upgrade to v4 of gulp

@bangsite
Copy link

Thank you a lot for sharing! This helped me so much.

@evasoek
Copy link

evasoek commented Nov 20, 2020

I'm getting the error:
imagemin.jpegtran is not a function

Any idea?

@jeromecoupe
Copy link
Author

jeromecoupe commented Nov 24, 2020

@evasoek yes. imagemin stopped using jpegtran a while ago in favour of mozjpeg.

This is an old Gist and you might want to look at the doc of the various plugins used.

// Optimize Images
function images() {
  return gulp
    .src("./assets/img/**/*")
    .pipe(newer("./_site/assets/img"))
    .pipe(
      imagemin([
        imagemin.gifsicle({ interlaced: true }),
        // the line below is the one that you likely have to change
        imagemin.mozjpeg({ quality: 75, progressive: true }),
        imagemin.optipng({ optimizationLevel: 5 }),
        imagemin.svgo({
          plugins: [
            {
              removeViewBox: false,
              collapseGroups: true
            }
          ]
        })
      ])
    )
    .pipe(gulp.dest("./_site/assets/img"));
}

Despite that, basic principles for Gulp 4 have stayed the same so this is still quite relevant. I ams till using Gulp (in combination with Webpack fr JS) on my personal site, which is available on Github if you are interested.

@evasoek
Copy link

evasoek commented Nov 24, 2020

@evasoek yes. imagemin stopped using jpegtran a while ago in favour of mozjpeg.

This is an old Gist and you might want to look at the doc of the various plugins used.

// Optimize Images
function images() {
  return gulp
    .src("./assets/img/**/*")
    .pipe(newer("./_site/assets/img"))
    .pipe(
      imagemin([
        imagemin.gifsicle({ interlaced: true }),
        // the line below is the one that you likely have to change
        imagemin.mozjpeg({ quality: 75, progressive: true }),
        imagemin.optipng({ optimizationLevel: 5 }),
        imagemin.svgo({
          plugins: [
            {
              removeViewBox: false,
              collapseGroups: true
            }
          ]
        })
      ])
    )
    .pipe(gulp.dest("./_site/assets/img"));
}

Despite that, basic principles for Gulp 4 have stayed the same so this is still quite relevant. I ams till using Gulp (in combination with Webpack fr JS) on my personal site, which is available on Github if you are interested.

Yes I figured, thanks! I got it to work eventually, so it's fine. 😊

@LoesterFranco
Copy link

thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment