Bipul Roy
Bipul Roy

Reputation: 566

Getting ` Error [ERR_REQUIRE_ESM]` while running `gulp` command

I'm new to Gulp and trying to automate some tasks. Here's my environment setup: npm version: 8.1.0, node version 17.0.1, gulp CLI version 2.3.0 and gulp version 4.0.2

And here's my gulpfile.js:

// list of dependencies ( things require to run the below funcitions)
const { src, dest, watch, series } = require('gulp');
const sass = require('gulp-sass');
const prefix = require('gulp-autoprefixer');
const minify = require('gulp-clean-css');
const terser = require('gulp-terser');
const imagemin = require('gulp-imagemin');
const imagewebp = require('gulp-webp');



// create functions


// SCSS
function compilescss() {
    return src('src/scss/*.scss')
        .pipe(sass())
        .pipe(prefix('last 2 versions'))
        .pipe(minify())
        .pipe(dest('/dist/css'))
}


// JS
function jsmin(){
    return src('src/js/*.js')
        .pipe(terser())
        .pipe(dest('dist/js'))
}

// images
function optimizeimg() {
    return src('src/img/*.{jpg,png}')
        .pipe(imagemin([
            imagemin.mozjpeg({quality: 80, progressive: true}),
            imagemin.optipng({optiminzationLevel: 2})
        ]))
        .pipe(dest('dist/img'))
}


// webp images
function webpImage() {
    return src('dist/img/*.{jpg, png}')
        .pipe(imagewebp())
        .pipe('dist/img')
}


// create watchlist
function watchTask(){
    watch('src/scss/*.scss', compilescss);
    watch('src/js/*.js', jsmin);
    watch('src/img/*.{jpg,png}', optimizeimg);
    watch('dist/img/*.{jpg,png}', webpImage);
}



// default gulp
exports.default = series(
    compilescss,
    jsmin,
    optimizeimg,
    webpImage,
    watchTask
);

When I'm trying to run gulp command in the terminal. I'm getting errors like - Error [ERR_REQUIRE_ESM]: require() of ES Module E:\Projects\portfolio\node_modules\gulp-imagemin\index.js from E:\Projects\portfolio\gulpfile.js not supported.

enter image description here

I've tried solutions like - adding type:"module" in package.json and instead of require() used import but I couldn't make it work. So how can I fix this??? Thanks!

Upvotes: 19

Views: 28963

Answers (6)

Neffi Bathla
Neffi Bathla

Reputation: 9

I was getting the same error so first go through the npm doc of the gulp plugin and see if there is an addition change. Also for now try this

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

instead of

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

Upvotes: 0

Daniel Tkach
Daniel Tkach

Reputation: 736

Another option: You'll need to switch to using dynamic import() syntax instead of require(). However, in a gulpfile, this can be a bit tricky because dynamic imports return a promise, and Gulp is generally expecting things to be available immediately.

Here's how you can use dynamic imports with gulp-imagemin:

let imagemin;
import('gulp-imagemin').then((gulpImagemin) => {
  imagemin = gulpImagemin;
});

const images = () => {
  if (!imagemin) {
    throw new Error('gulp-imagemin not loaded');
  }

  return gulp.src('src/images/**/*')
    .pipe(imagemin())
    .pipe(gulp.dest('dist/images'));
};

exports.images = images;

This way, gulp-imagemin is imported asynchronously when the gulpfile is loaded, and then it's available by the time any tasks run. But note that if you run gulp images immediately after starting your script, gulp-imagemin might not have loaded yet. You should ensure all your imports are loaded before starting your Gulp tasks.

If you find this approach to be too complex or error-prone, another solution is to stick with versions of your dependencies that are CommonJS modules, not ES modules, as some other answers described above.

Upvotes: 0

MikeMcC399
MikeMcC399

Reputation: 355

The (currently) latest gulp-imagemin (v8.0.0) version is a pure ESM package according to the v8.0.0 release notes. A solution to this issue using dynamic import has been posted to How to import a Javascript file that is ESM from a CommonJS module? Gulp. Error: [ERR_REQUIRE_ESM].

Upvotes: 1

Suhayb
Suhayb

Reputation: 3271

According to node docs Node.js has two module systems: CommonJS modules and ECMAScript modules.

You can tell Node.js to use the ECMAScript modules loader via the .mjs file extension, the package.json "type" field, or the --input-type flag. Outside those cases, Node.js will use the CommonJS module loader. See Determining module system for more details.

So basically use es6 syntax and rename the file extension to .mjs this way node treats this file as ECMA

import gulp from 'gulp';
import imagemin from 'gulp-imagemin';

export default () =>
  gulp
    .src('public/media/**/*')
    .pipe(imagemin())
    .pipe(gulp.dest('dist/public/media'));

Upvotes: 2

noraj
noraj

Reputation: 4662

Moving to something like that would probably work:

import gulp from 'gulp';
const { src, dest, watch, series } = gulp;
import dartSass from 'sass';
import gulpSass from 'gulp-sass';
const sass = gulpSass(dartSass);
import prefix from 'gulp-autoprefixer';
import minify from 'gulp-clean-css';
import terser from 'gulp-terser';
import imagemin from 'gulp-imagemin';
import imagewebp from 'gulp-webp';

I have made a guide: Moving gulpfile from CommonJS (CJS) to ECMAScript Modules (ESM)

Upvotes: 13

SNyamathi
SNyamathi

Reputation: 786

gulp-imagemin 8.0.0 and above are now ESM only. You can downgrade gulp-imagemin to 7.1.0 which is commonjs and it should work fine.

This package is now pure ESM. Please read this.

https://github.com/sindresorhus/gulp-imagemin/releases/tag/v8.0.0

Upvotes: 30

Related Questions