ncc icon indicating copy to clipboard operation
ncc copied to clipboard

ESM mode still uses "require" within an ESM module

Open onigoetz opened this issue 1 year ago • 6 comments

Hi,

I'm trying to bundle my dependencies within an ESM package I get mixed results depending if the module I compile is using ESM or CJS.

Here is an example of three packages I'm trying to bundle, each in their separate file;

  • is-fullwidth-code-point, CJS module
  • slice-ansi, ESM module, depends on is-fullwidth-code-point
  • string-width, CJS module, depends on is-fullwidth-code-point

When compiling these three modules they all compile fine, and create a package.json containing { "type": "module" }.

However, within string-width, NCC (I guess because of the asset relocator) require calls are transformed to the following:

/***/ 695:
/***/ ((module) => {

module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("../is-fullwidth-code-point/index.mjs");

/***/ }),

Which fails when we try to run it since the result is a require of an ESM module:

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/is-fullwidth-code-point/index.mjs not supported.
Instead change the require of /Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/is-fullwidth-code-point/index.mjs to a dynamic import() which is available in all CommonJS modules.
    at 695 (file:///Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/string-width/index.mjs:74:67)
    at __nccwpck_require__ (file:///Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/string-width/index.mjs:107:41)
    at 871 (file:///Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/string-width/index.mjs:22:30)
    at __nccwpck_require__ (file:///Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/string-width/index.mjs:107:41)
    at file:///Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/string-width/index.mjs:146:70
    at file:///Users/onigoetz/Sites/Libs/crafty/packages/crafty-preset-stylelint/dist/string-width/index.mjs:148:3

is there a way to tell the asset relocator that the destination is an ESM module and it should let webpack hoist the dependency ?

onigoetz avatar Feb 08 '24 22:02 onigoetz

I am also running into this issue. Running with sourcemaps also gives ReferenceError: __dirname is not defined in ES module scope. It seems it is still using the global __dirname which you cannot in ESM.

mr-short avatar Feb 10 '24 14:02 mr-short

This sounds like a duplicate of https://github.com/vercel/ncc/issues/749

styfle avatar Feb 12 '24 13:02 styfle

It is not, #749 mentions wanting to output CJS within an ESM module, and it can't access __dirname / __filename

This is issue is about outputing ESM in an ESM module, and importing other ESM modules. But NCC's transformations tries to require an ESM module

onigoetz avatar Feb 12 '24 14:02 onigoetz

Oops, I meant duplicate of #791

styfle avatar Feb 12 '24 15:02 styfle

It is similar to #791 but not really

All cases in #791 point on a missing createRequire (which BTW seems to work fine now)

My case is that I have require / createRequire but wish to have import (because what I'm importing is an ESM module)

onigoetz avatar Feb 13 '24 08:02 onigoetz

I think I have the same error. I upgraded a package that required me to update my script to be a module so I could use import. Now I can run the script manually just fine, but once I compile it with ncc and try to run it, it fails

file:///home/chris/workspace/chocrates/actions-governance/dist/exec-child.js:1
if (require.main !== module) {
^

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and '/home/chris/workspace/chocrates/actions-governance/dist/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at file:///home/chris/workspace/chocrates/actions-governance/dist/exec-child.js:1:1
    at ModuleJob.run (node:internal/modules/esm/module_job:192:25)
    at async DefaultModuleLoader.import (node:internal/modules/esm/loader:228:24)
    at async loadESM (node:internal/process/esm_loader:40:7)
    at async handleMainPromise (node:internal/modules/run_main:66:12)

There are no require's in my codebase anymore and it looks like the generated exec-child.js is the culprit.

Chocrates avatar Feb 28 '24 21:02 Chocrates