Lesson 18-20: Transform gulp pipeline to use ESM (to fix issue with `gulp-imagemin`)
sophiabrandt opened this issue · comments
gulp-imagemin in its latest version is now ESM only (see also #24 ).
In my personal project I have changed the gulp pipeline to use ESM and was able to update all dependencies to their latest versions.
I want to leave my code here for anyone who's interested in doing the same, too.
I followed this guide.
1. Update packages
Updated package.json
:
{
"devDependencies": {
"get-google-fonts": "^1.2.2",
"gulp": "^4.0.2",
"gulp-clean-css": "^4.3.0",
"gulp-imagemin": "^8.0.0",
"gulp-sass": "^5.1.0",
"sass": "^1.64.1"
}
}
2. Update gulp to use ESM
Change the file endings of all gulp files to .mjs
:
- gulp-tasks/fonts.mjs
- gulp-tasks/images.mjs
- gulp-tasks/sass.mjs
- gulpfile.mjs
3. Change syntax
gulpfile.mjs
:
import gulp from "gulp";
const { parallel, watch: gulpWatch } = gulp;
// Pull in each task
import fonts from "./gulp-tasks/fonts.mjs";
import images from "./gulp-tasks/images.mjs";
import sass from "./gulp-tasks/sass.mjs";
// Set each directory and contents that we want to watch and
// assign the relevant task. `ignoreInitial` set to true will
// prevent the task being run when we run `gulp watch`, but it
// will run when a file changes.
const watcher = () => {
gulpWatch("./src/images/**/*", { ignoreInitial: true }, images);
gulpWatch("./src/scss/**/*.scss", { ignoreInitial: true }, sass);
};
// The default (if someone just runs `gulp`) is to run each task in parallel
export default parallel(fonts, images, sass);
// This is our watcher task that instructs gulp to watch directories and
// act accordingly
export const watch = watcher;
gulp-tasks/fonts.mjs
:
import GetGoogleFonts from "get-google-fonts";
const fonts = async () => {
// Setup of the library instance by setting where we want
// the output to go. CSS is relative to output font directory
const instance = new GetGoogleFonts({
outputDir: "./dist/fonts",
cssFile: "./fonts.css",
});
// Grabs fonts and CSS from google and puts in the dist folder
const result = await instance.download(
'https://fonts.googleapis.com/css2?family=Literata:ital,wght@0,400;0,700;1,400&family=Red+Hat+Display:wght@400;900'
);
return result;
};
export default fonts;
gulp-tasks/images.mjs
:
import gulp from "gulp";
import imagemin, { mozjpeg, optipng } from "gulp-imagemin";
// Grabs all images, runs them through imagemin
// and plops them in the dist folder
const images = () => {
// We have specific configs for jpeg and png files to try
// to really pull down asset sizes
return gulp
.src("./src/assets/images/**/*")
.pipe(
imagemin(
[
mozjpeg({ quality: 60, progressive: true }),
optipng({ optimizationLevel: 5, interlaced: null }),
],
{
silent: true,
},
),
)
.pipe(gulp.dest("./dist/assets/images"));
};
export default images;
gulp-tasks/sass.mjs
:
import gulp from "gulp";
import cleanCSS from "gulp-clean-css";
import * as dartSass from "sass";
import gulpSass from "gulp-sass";
const sassProcessor = gulpSass(dartSass);
// Flags whether we compress the output etc
const isProduction = process.env.NODE_ENV === 'production';
// An array of outputs that should be sent over to includes
const criticalStyles = ['critical.scss', 'home.scss', 'page.scss', 'work-item.scss'];
// Takes the arguments passed by `dest` and determines where the output file goes
const calculateOutput = ({history}) => {
// By default, we want a CSS file in our dist directory, so the
// HTML can grab it with a <link />
let response = './dist/css';
// Get everything after the last slash
const sourceFileName = /[^(/|\\)]*$/.exec(history[0])[0];
// If this is critical CSS though, we want it to go
// to the _includes directory, so nunjucks can include it
// directly in a <style>
if (criticalStyles.includes(sourceFileName)) {
response = './src/_includes/css';
}
return response;
};
// The main Sass method grabs all root Sass files,
// processes them, then sends them to the output calculator
const sass = () => {
return gulp
.src("./src/scss/*.scss")
.pipe(sassProcessor().on("error", sassProcessor.logError))
.pipe(
cleanCSS(
__prod__
? {
level: 2,
}
: {},
),
)
.pipe(gulp.dest(calculateOutput, { sourceMaps: !__prod__ }));
};
export default sass;