Environment
- jimp: 1.6.0
- webpack: 5.x (web target)
- Node.js: Any — the issue is in the published artifact, not the build toolchain
- OS: Any
- Impact: Blocks webpack builds targeting browser; strict mode parsing may have been disabled as a mitigation strategy.
Summary
jimp/dist/browser/index.js is declared as an ES module (it ends with export { ... } and the package has "type": "module") but its body contains rollup-generated CommonJS interop helpers that use duplicate identifier names (e.g. function e(e) { ... }). This is invalid in strict mode, which ES modules enforce unconditionally. Webpack — and any other bundler that respects the "browser" export condition — fails to parse the file.
Expected Behavior
dist/browser/index.js should be parseable as a strict-mode ES module. The minified helper function should not shadow its own name as a parameter.
Actual Behavior
Any bundler that resolves the "browser" export condition fails with a strict-mode parse error on the duplicate identifier.
Steps to Reproduce
package.json
{
"name": "jimp-webpack-repro",
"private": true,
"scripts": { "build": "webpack --mode production" },
"dependencies": { "jimp": "1.6.0" },
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"babel-loader": "^9.1.3",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
}
}
webpack.config.js
const path = require("path");
module.exports = {
target: "web",
entry: "./src/index.js",
output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js" },
module: {
rules: [{
test: /\.m?js$/,
exclude: /node_modules\/(?!crypto-api|bootstrap)/,
loader: "babel-loader",
options: { presets: ["@babel/preset-env"], cacheDirectory: true },
type: "javascript/auto",
}],
},
};
src/index.js
import { Jimp, JimpMime } from "jimp";
async function blurImage(arrayBuffer) {
const image = await Jimp.fromBuffer(arrayBuffer);
image.blur(5);
return image.getBuffer(JimpMime.png);
}
export { blurImage };
npm install && npm run build
Failure Output
ERROR in ./node_modules/jimp/dist/browser/index.js 199:9979
Module parse failed: Identifier 'e' has already been declared (199:9979)
File was processed with these loaders:
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| return t < 0 && (t = e.length + t), e.substr(t, i);
| };
> function e(e) {
| return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
| }
Note: The column number varies across builds (line 199 in this repro vs. line 31135 in multi-line builds). This is expected — dist/browser/index.js is a single-line bundle, so all positions are on line 1 or 199 depending on how the bundler counts. More importantly, the collision is not isolated to one location — the rollup getDefaultExportFromCjs helper is emitted multiple times throughout the file, so there are multiple instances of function e(e) in the bundle.
Root Cause
dist/browser/index.js is produced by rollup as a pre-bundled file for direct browser/CDN use. Rollup inlines a getDefaultExportFromCjs helper using a minified identifier, but the minified output collides with a surrounding scope — producing function e(e) { ... } (a function named e whose parameter is also e).
This pattern is valid in sloppy mode (classic scripts) but not in strict mode. Because:
jimp/package.json declares "type": "module", and
dist/browser/index.js itself ends with export { Jimp, JimpMime, ... }
...every JavaScript engine and bundler is required to parse the file in strict mode, where the duplicate binding is a syntax error.
The @jimp/... sub-packages (e.g. @jimp/js-bmp) are unaffected — they only expose "import" and "require" export conditions with clean ESM source files.
Workaround
Alias jimp to its ESM build in your bundler config to bypass the broken browser bundle. In webpack:
resolve: {
alias: {
jimp: require("path").resolve(__dirname, "node_modules/jimp/dist/esm/index.js")
}
}
The ESM build (dist/esm/index.js) imports from the @jimp/... sub-packages, which have clean, valid ES module sources and are already installed as transitive dependencies of jimp.
Environment
Summary
jimp/dist/browser/index.jsis declared as an ES module (it ends withexport { ... }and the package has"type": "module") but its body contains rollup-generated CommonJS interop helpers that use duplicate identifier names (e.g.function e(e) { ... }). This is invalid in strict mode, which ES modules enforce unconditionally. Webpack — and any other bundler that respects the"browser"export condition — fails to parse the file.Expected Behavior
dist/browser/index.jsshould be parseable as a strict-mode ES module. The minified helper function should not shadow its own name as a parameter.Actual Behavior
Any bundler that resolves the
"browser"export condition fails with a strict-mode parse error on the duplicate identifier.Steps to Reproduce
package.json{ "name": "jimp-webpack-repro", "private": true, "scripts": { "build": "webpack --mode production" }, "dependencies": { "jimp": "1.6.0" }, "devDependencies": { "@babel/core": "^7.24.0", "@babel/preset-env": "^7.24.0", "babel-loader": "^9.1.3", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" } }webpack.config.jssrc/index.jsFailure Output
Root Cause
dist/browser/index.jsis produced by rollup as a pre-bundled file for direct browser/CDN use. Rollup inlines agetDefaultExportFromCjshelper using a minified identifier, but the minified output collides with a surrounding scope — producingfunction e(e) { ... }(a function namedewhose parameter is alsoe).This pattern is valid in sloppy mode (classic scripts) but not in strict mode. Because:
jimp/package.jsondeclares"type": "module", anddist/browser/index.jsitself ends withexport { Jimp, JimpMime, ... }...every JavaScript engine and bundler is required to parse the file in strict mode, where the duplicate binding is a syntax error.
The
@jimp/...sub-packages (e.g.@jimp/js-bmp) are unaffected — they only expose"import"and"require"export conditions with clean ESM source files.Workaround
Alias
jimpto its ESM build in your bundler config to bypass the broken browser bundle. In webpack:The ESM build (
dist/esm/index.js) imports from the@jimp/...sub-packages, which have clean, valid ES module sources and are already installed as transitive dependencies ofjimp.