Skip to content

fix: support --print with --input-type=module #59068

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Momena-akhtar
Copy link

Description

This PR resolves an inconsistency in the Node.js CLI where the --print (-p) flag did not work properly with ES modules using --input-type=module, making it impossible to use top-level await in quick one-liner scripts.


Before this change

node -p "await Promise.resolve(123)" --input-type=module

Output

SyntaxError: await is only valid in async functions and the top level bodies of modules
# OR
Error [ERR_EVAL_ESM_CANNOT_PRINT]: Cannot print result of an ES module evaluation

After this change

node -p "await Promise.resolve(123)" --input-type=module

Output

123

What this PR does

  • Enables top-level await to work with --print when --input-type=module is used
  • Wraps the expression in an async () => (...) IIFE
  • Uses a dynamic ES module evaluation via runEntryPointWithESMLoader
  • Prints the resolved value to stdout
  • Handles execution errors gracefully
  • Adds test coverage in test/parallel/test-cli-print-esm.js

Test Added

// test/parallel/test-cli-print-esm.js

'use strict';

const { execSync } = require('child_process');
const assert = require('assert');

const output = execSync(
  `${process.execPath} -p "await Promise.resolve(123)" --input-type=module`
).toString().trim();

assert.strictEqual(output, '123');

Related

Notes

This is a minimal and safe change that improves consistency and scriptability for developers using ES modules interactively or in pipelines.
Let me know if you'd like to see support extended to TypeScript --input-type=module-typescript as well.

Previously, `node -p` did not support top-level await in ES modules when used with `--input-type=module`, throwing ERR_EVAL_ESM_CANNOT_PRINT.

This change wraps the evaluated source in an async IIFE and dynamically imports it, allowing top-level await and printing the result in ESM mode.
Adds a regression test to ensure that `node -p` works with top-level await when used with `--input-type=module`.

Validates output from: node -p "await Promise.resolve(123)" --input-type=module
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/loaders

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. process Issues and PRs related to the process subsystem. labels Jul 14, 2025
throw new ERR_EVAL_ESM_CANNOT_PRINT();
}
RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs.
RegExpPrototypeExec(/^/, '');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has lost a rather important comment.

@GeoffreyBooth
Copy link
Member

See also: #52105

That earlier PR might have some tests that you could port over into this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-ci PRs that need a full CI run. process Issues and PRs related to the process subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make --print respect --input-type=module
4 participants