evanw/esbuild

When bundle is a CommonJS library, parent directory name is used.

Closed this issue · 1 comments

When bundling a CommonJS library that exports variables, the directory name of the project's root is used, rather than the package name or some other generic name. This doesn't happen with ESM modules. In the following example, note that require_temp is the name of a variable, because the folder name of the project happened to be temp.

This is problematic because it makes it impossible to create deterministic reproducible builds since there can be no guarantee about the directory structure above the project on a given machine. Even automated build environments may have something like a hash or ID in the directory name.

package.json

{
  "name": "some-lib",
  "main": "index.js",
  "dependencies": {
    "esbuild": "0.24.0"
  }
}

index.js

module.exports.eat = function eat() {
	console.log('apple eaten')
}

Bundle Command:

npx --no esbuild index.js --bundle --platform=browser --format=esm --outfile=bundle.mjs

Bundle Output:

var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};

// index.js
var require_temp = __commonJS({
  "index.js"(exports, module) {
    module.exports.eat = function eat() {
      console.log("nom nom");
    };
  }
});
export default require_temp();

It is worth noting, I am very intentionally not minifying/obfuscating anything. The bundle should be as human readable as possible and I explicitly do not wish to just mangle all of the names away. I also am fine with directory structure/filenames within the project to have an impact on the names that are chosen, as those are part of version control. I merely want the build output to not include the parent directory name.

Thank you!