Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import "yargs/yargs" in esm code brings in __dirname (when compiled using ncc) #2418

Open
chubei-urus opened this issue Jun 12, 2024 · 7 comments

Comments

@chubei-urus
Copy link

Reproduce

node --version
v20.11.1

Create package.json and index.mjs with following code:

{
  "scripts": {
    "build": "ncc build index.mjs"
  },
  "dependencies": {
    "yargs": "^17.7.2"
  },
  "devDependencies": {
    "@vercel/ncc": "^0.38.1"
  }
}
import yargs from "yargs/yargs";
console.log(yargs);

Run command:

npm install
npm run build
node dist/index.mjs

Exepcted

[Function (anonymous)] {
  applyExtends: [Function (anonymous)],
  hideBin: [Function: hideBin],
  Parser: [Function: Parser] {
    detailed: [Function (anonymous)],
    camelCase: [Function: camelCase],
    decamelize: [Function: decamelize],
    looksLikeNumber: [Function: looksLikeNumber]
  }
}

Actual

...
ReferenceError: __dirname is not defined in ES module scope
...

I think this has something to do with yargs.mjs importing build/index.cjs, but have no clue on how to solve it.

@chubei-urus chubei-urus changed the title import "yargs/yargs" in esm code brings in __dirname` import "yargs/yargs" in esm code brings in __dirname Jun 12, 2024
@shadowspawn
Copy link
Member

I was able to reproduce the failure. My guess is ncc is getting confused resolving subpath exports.

I got a working build using the main entry point:

import yargsFactory from "yargs";
console.log(yargsFactory(process.argv.slice(2)).parse());

@chubei-urus
Copy link
Author

Thank you for verifying this!

I feel ncc resolves the subpath export correctly, because the root cause seems to be that build/index.cjs uses the cjs shim, instead of the esm one. And the cjs shim uses __dirname, as it should be.

I ran into this because puppeteer imports yargs using "yargs/yargs". I see several solutions to this:

  • Ask for yargs' help to fix yarngs.mjs to be fully esm compatible.
  • Ask for puppeteer's help to change from importing "yargs/yargs" to "yargs".
  • Change the module system in my own project to use commonjs instead of esm.

What's you recommended next step for this?

@shadowspawn
Copy link
Member

shadowspawn commented Jun 14, 2024

What's you recommended next step for this?

I suggest try changing your project to use commonjs. That might avoid triggering the problem with the ncc compile.

@chubei-urus
Copy link
Author

Got it. I'll leave the issue open in case someone else ran into this.

@shadowspawn shadowspawn changed the title import "yargs/yargs" in esm code brings in __dirname import "yargs/yargs" in esm code brings in __dirname (when compiled using ncc) Jun 14, 2024
@Rouvas
Copy link

Rouvas commented Aug 20, 2024

Hello, I have the same problem when using puppeteer

My Express (Angular SSR) application compiles successfully, but an error appears on startup

ReferenceError: __dirname is not defined in ES module scope
    at node_modules/yargs/build/index.cjs (file:///Users/.../server/server.mjs:81673:264)
...
Node.js v18.6.0

@shadowspawn
Copy link
Member

To be clear, are you also compiling using ncc @Rouvas ?

@shadowspawn
Copy link
Member

shadowspawn commented Nov 2, 2024

I noticed this issue being mentioned in puppeteer/puppeteer#13249, and the fix (work-around) was to use the "old" import:

import yargs from 'yargs';

That might help track down the underlying trigger with a working case and a broken case, but even without solving it, there is hopefully a work-around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants