Getting ` Error [ERR_REQUIRE_ESM]` while running `gulp` command
Asked Answered
N

6

19

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!

Novah answered 6/11, 2021 at 9:21 Comment(0)
M
29

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

Missive answered 15/11, 2021 at 1:42 Comment(5)
Yes. I actually got the solution but thanks for the answer.Novah
npm install --save-dev [email protected]Novah
Pinning the dependency version is barely a workaround. The solution would be to show how to convert the GULP file to ESM.Dowland
@BipulRoy could you please share your solution. I am also having the same problemsUnaneled
The 7.1.0 has the vulnerabilities.Rigging
D
13

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)

Dowland answered 20/7, 2022 at 23:32 Comment(1)
Doooh thank you !! I believe the link should probably replace the text of this answer to avoid link rot.Docilla
F
1

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'));
Foreigner answered 30/9, 2022 at 15:33 Comment(0)
B
1

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].

Burnt answered 25/10, 2022 at 17:47 Comment(2)
Although I added the above as a potential solution, my personal preference is to go through the full migration from CommonJS to ESM (require => import). It may not always be completely simple, also because Node.js LTS has just changed to 18 which can produce some breaking changes, however if you do migrate to ESM you will have something supportable for longer.Burnt
It's not always simple just to change the all the require statements to imports in the gulpfile.js source. Something like import gulp from 'gulp'; throws the error - SyntaxError: Cannot use import statement outside a module. It seems that some packages prefer require and others import . . .Boarfish
I
0

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.

Ikeikebana answered 13/5, 2023 at 16:54 Comment(0)
A
0

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');
Armijo answered 18/12, 2023 at 21:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.