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

🚀 Feature: Explicit --import support for Node ESM #5002

Closed
4 tasks done
GianlucaGuarini opened this issue Jul 21, 2023 · 3 comments
Closed
4 tasks done

🚀 Feature: Explicit --import support for Node ESM #5002

GianlucaGuarini opened this issue Jul 21, 2023 · 3 comments
Assignees
Labels
status: in discussion Let's talk about it! type: feature enhancement proposal

Comments

@GianlucaGuarini
Copy link

Prerequisites

  • Checked that your issue hasn't already been filed by cross-referencing issues with the faq label
  • Checked next-gen ES issues and syntax problems by using the same environment and/or transpiler configuration without Mocha to ensure it isn't just a feature that actually isn't supported in the environment in question or a bug in your code.
  • 'Smoke tested' the code to be tested by running it outside the real test suite to get a better sense of whether the problem is in the code under test, your usage of Mocha, or Mocha itself
  • Ensured that there is no discrepancy between the locally and globally installed versions of Mocha. You can find them with: node_modules/.bin/mocha --version(Local) and mocha --version(Global). We recommend that you not install Mocha globally.

Description

Node versions >=16 allow the use of the --loader flag. Custom Loaders should be supported by mocha since the flag is a Node native option.

Steps to Reproduce

  1. Clone this repo https://github.com/riot/ssr
  2. Pass the loader option directly to mocha here (avoid the use of the NODE_OPTIONS workaround)

Expected behavior: [What you expect to happen]
Mocha should work without the use of NODE_OPTIONS workaround

Actual behavior: [What actually happens]

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/riot/ssr/@riotjs/register' imported from /riot/ssr/
    at new NodeError (node:internal/errors:399:5)
    at finalizeResolution (node:internal/modules/esm/resolve:326:11)
    at moduleResolve (node:internal/modules/esm/resolve:945:10)
    at defaultResolve (node:internal/modules/esm/resolve:1153:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ESMLoader.import (node:internal/modules/esm/loader:525:22)
    at node:internal/modules/run_main:58:28
    at loadESM (node:internal/process/esm_loader:91:11) {
  code: 'ERR_MODULE_NOT_FOUND'

Reproduces how often: [What percentage of the time does it reproduce?]

Always

Versions

  • The output of mocha --version and node_modules/.bin/mocha --version: 10.2.0
  • The output of node --version: v18.14.0
  • Your operating system
    • name and version: macOS 12.6.7
    • architecture (32 or 64-bit): 64bit
  • Your shell (e.g., bash, zsh, PowerShell, cmd): zsh
  • Your browser and version (if running browser tests):
  • Any third-party Mocha-related modules (and their versions):
  • Any code transpiler (e.g., TypeScript, CoffeeScript, Babel) being used (and its version):

Additional Information

Thank you for your hard work ❤️

@drernie
Copy link

drernie commented Oct 9, 2023

Not sure if this is related, but I am able to use "--loader" with node v18 and v20. Specifically:

$ mocha "test/ops/*" --loader=ts-node/esm

However, mocha appears to be calling node with the "experimental-loader" flag, resulting in a warning:

(node:56122) ExperimentalWarning: `--experimental-loader` may be removed in the future; instead use `register()`:
--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("ts-node/esm", pathToFileURL("./"));'
    at createModuleLoader (node:internal/modules/esm/loader:534:17)
    at loadESM (node:internal/process/esm_loader:21:19)
    at runMainESM (node:internal/modules/run_main:53:21)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:5)
    at node:internal/main/run_main_module:23:47

Is "--loader" supported or not?

@JoshuaKGoldberg JoshuaKGoldberg changed the title Node ESM Custom Loaders should be loaded using the --loader flag 🐛 Bug: Node ESM Custom Loaders should be loaded using the --loader flag Dec 28, 2023
@JoshuaKGoldberg JoshuaKGoldberg self-assigned this Jan 21, 2024
@JoshuaKGoldberg
Copy link
Member

JoshuaKGoldberg commented Jan 21, 2024

👋 thanks for the great details! Although this was filed as a bug, it seems like more of a docs/feature request to me. As in, you're asking for support of ESM loaders in Node, right @GianlucaGuarini?

@drernie is right: Mocha actually does "support" ESM loaders! It's just coincidental and not documented (🙃). You can see ESM support in action in the ts-node/esm and tsx/esm examples I sent just now in mochajs/mocha-examples#76.

Which leads me to think that this is issue is really two requests:

...and any --experimental-loader console complaints won't be relevant in projects using --import.


In more detail: Mocha forwards unrecognized args to its child node process. You can see the args being passed by running with a debug package DEBUG environment variable set to mocha:cli:mocha. It's logged in a message with final node argv.

$ DEBUG=mocha:cli:mocha
  ...
  mocha:cli:mocha final node argv [ '--loader=ts-node/esm' ] +2ms
  mocha:cli:mocha forking child process via command: /path/to/node --loader=ts-node/esm /path/to/node_modules/mocha/lib/cli/cli.js ...
  ...
--loader=ts-node/esm works, albeit with the aforementioned --experimental-loader complaint. See that mocha-examples PR's packages/typescript-ts-node-esm-loader:
~/repos/mocha-examples/packages/typescript-ts-node-esm-loader $ npm run test

> typescript-esm-loader@1.0.0 test
> mocha --loader=ts-node/esm

(node:50478) ExperimentalWarning: `--experimental-loader` may be removed in the future; instead use `register()`:
--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("ts-node/esm", pathToFileURL("./"));'
(Use `node --trace-warnings ...` to show where the warning was created)


  TypeScript usage suite
    ✔ should be able to execute a test
    ✔ should return expected string


  2 passing (1ms)

Note that the Node.js --loader flag was deprecated in Node.js v18.19.0/v20.6.0. It's --import now.

Which is what the mocha-examples PR's packages/typescript-tsx-esm-import uses, without any log complaints.
~/repos/mocha-examples/packages/typescript-tsx-esm-import $ npm run test

> typescript-esm-loader@1.0.0 test
> mocha --import=tsx/esm



  TypeScript usage suite
    ✔ should be able to execute a test
    ✔ should return expected string


  2 passing (2ms)

Does that sound right to everyone?

@JoshuaKGoldberg JoshuaKGoldberg added status: in discussion Let's talk about it! and removed unconfirmed-bug labels Jan 21, 2024
@JoshuaKGoldberg JoshuaKGoldberg changed the title 🐛 Bug: Node ESM Custom Loaders should be loaded using the --loader flag 🚀 Feature: Explicit --import support for Node ESM Jan 21, 2024
@JoshuaKGoldberg JoshuaKGoldberg added the type: feature enhancement proposal label Jan 21, 2024
@GianlucaGuarini
Copy link
Author

Since --loader flag was deprecated in node it doesn't make sense to further discuss about this issue.
Thank you @JoshuaKGoldberg for your answer!

For all the others having a similar issue I recommend to register the loaders using explicitly the register hook https://nodejs.org/api/module.html#customization-hooks

FoxxMD added a commit to FoxxMD/multi-scrobbler that referenced this issue Feb 15, 2024
So that we can use tsx with official --import rather than requiring (old-style) which doesn't work with string-sameness esm for some reason

mochajs/mocha#5002
mochajs/mocha-examples#76
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: in discussion Let's talk about it! type: feature enhancement proposal
Projects
None yet
Development

No branches or pull requests

3 participants