I found a code in a website for converting png, jpg to webp but it doesnt work for me. I have two jpg files in /images/ folder
const imagemin = require("imagemin"),
webp = require("imagemin-webp");
const outputFolder = "./images/webp";
const produceWebP = async () => {
await imagemin(["images/*.png"], {
destination: outputFolder,
plugins: [
webp({
lossless: true,
}),
],
});
console.log("PNGs processed");
await imagemin(["images/*.{jpg,jpeg}"], {
destination: outputFolder,
plugins: [
webp({
quality: 65,
}),
],
});
console.log("JPGs and JPEGs processed");
};
produceWebP();
When i run node index.js i take the message you see in the photo
The issue here is in Error [ERR_REQUIRE_ESM]: Must use import to load ES Module
.
There are two types of modules in NodeJS: CommonJS and ECMAScript modules (ESM).
CommonJS uses const webp = require("imagemin-webp")
syntax.
While ESM uses import webp from "imagemin-webp"
syntax to achieve the same result.
Your index.js
is CommonJS and the imagemin npm module is ESM and the error ocures when you try to use require()
call to import ESM module.
There are two possible solutions for this:
index.js
from CommonJS to ESM (preferred)import()
call instead of require()
to import ESM module from CommonJSFirst (and preferred) option is to convert your code to ESM:
index.js
to index.mjs
(.mjs
extension indicates ESM syntax)require()
calls to import something from 'library'
callsnode index.mjs
index.mjs
:
// using ES import syntax here
import imagemin from "imagemin";
import webp from "imagemin-webp";
// the rest of the file is unchanged
const outputFolder = "./images/webp";
const produceWebP = async () => {
await imagemin(["images/*.png"], {
destination: outputFolder,
plugins: [
webp({
lossless: true,
}),
],
});
console.log("PNGs processed");
await imagemin(["images/*.{jpg,jpeg}"], {
destination: outputFolder,
plugins: [
webp({
quality: 65,
}),
],
});
console.log("JPGs and JPEGs processed");
};
produceWebP();
Second option is to use asynchronous import()
call to import ESM modules from CommonJS module as indicated in NodeJS docs.
It is not preferred because import()
is asynchronous, I'd like to use await
to get the result like await import()
but this in-turn requires to be called inside another async
function.
index.js
:
const outputFolder = "./images/webp";
const produceWebP = async () => {
// Load ESM modules using import(),
// it returns a Promise which resolves to
// default export as 'default' and other named exports.
// In this case we need default export.
const imagemin = (await import("imagemin")).default;
const webp = (await import("imagemin-webp")).default;
await imagemin(["images/*.png"], {
destination: outputFolder,
plugins: [
webp({
lossless: true,
}),
],
});
console.log("PNGs processed");
await imagemin(["images/*.{jpg,jpeg}"], {
destination: outputFolder,
plugins: [
webp({
quality: 65,
}),
],
});
console.log("JPGs and JPEGs processed");
};
produceWebP();
P.S. Please note that ESM can export more than one entry (default and named exports) while CommonJS can only export one entry.