Skip to content

module,cli: fix module loading for paths ending with /. or /.. #52532

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

Closed
wants to merge 5 commits into from

Conversation

avivkeller
Copy link
Member

Related to #24256
Fixes #32008
Fixes #24210

This PR appends a trailing slash to certain paths to ensure they resolve correctly. Before this page, the module loader would prefer (cwd).js instead of (cwd)/index.js when running node ..

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/loaders

Sorry, something went wrong.

@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label Apr 14, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Copy link
Member

@GeoffreyBooth GeoffreyBooth left a comment

Choose a reason for hiding this comment

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

Please always include tests in a PR. The test should fail on current main and pass in your branch.

This change seems like it would be a semver major breaking change. It's not clear to me that the current behavior is buggy; is there documentation that describes the intended behavior, where a test can confirm that Node behaves not in accordance with that?

@avivkeller
Copy link
Member Author

avivkeller commented Apr 14, 2024

Please always include tests in a PR. The test should fail on current main and pass in your branch.

Hi! I'm about to push tests that will fail in the current version of node, but not in my patch.

This change seems like it would be a semver major breaking change. It's not clear to me that the current behavior is buggy; is there documentation that describes the intended behavior, where a test can confirm that Node behaves not in accordance with that?

Consider the directory setup below (assuming your current working directory is ./app):

.
├── app.js
└── app
    └── index.js

In the latest version of NodeJS, executing node . will launch app.js. However, in the REPL, calling require('.') will execute ./app/index.js.

@LiviaMedeiros LiviaMedeiros added module Issues and PRs related to the module subsystem. semver-major PRs that contain breaking changes and should be released in the next major version. cli Issues and PRs related to the Node.js command line interface. labels Apr 14, 2024
@LiviaMedeiros LiviaMedeiros changed the title lib, fix: fix module loading module,cli: fix module loading for paths ending with '/.' or '/..' Apr 14, 2024
@LiviaMedeiros LiviaMedeiros changed the title module,cli: fix module loading for paths ending with '/.' or '/..' module,cli: fix module loading for paths ending with /. or /.. Apr 14, 2024
@JakobJingleheimer
Copy link
Member

JakobJingleheimer commented Apr 14, 2024

In the latest version of NodeJS, executing node . will launch app.js.

I believe this is the correct behaviour.

@avivkeller
Copy link
Member Author

In the latest version of NodeJS, executing node . will launch app.js.

I believe this is the correct behaviour.

IMO it's not, as one would assume:
node . -> node ./index.js
instead of
node . -> node ../(cwd).js

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
@GeoffreyBooth
Copy link
Member

IMO it’s not, as one would assume

The relevant documentation is at https://nodejs.org/api/cli.html#program-entry-point:

The program entry point is a specifier-like string. If the string is not an absolute path, it’s resolved as a relative path from the current working directory. That path is then resolved by CommonJS module loader, or by the ES module loader if --experimental-default-type=module is passed. If no corresponding file is found, an error is thrown.

So reading this literally, an entry point string of . is not an absolute path, so it’s resolved as a relative path from the current working directory. Resolving /path/to/app/. from a relative path to an absolute path gets you /path/to/app; resolving that as a CommonJS specifier gets you /path/to/app.js (assuming ../app.js exists). Nonintuitive, but correct, per the documentation.

You might argue that this is nonsensical, that no one would want this behavior, and I would agree with that. In which case it’s not a bugfix but just a change, and the documentation needs to be updated along with the behavior. I would argue, though, that if we’re going to make a semver-major change to how the resolution of the entry point happens, we might want to go a bit bigger and eliminate the CommonJS resolution from this entirely: if you want to run ./index.js, then you need to run node ./index.js or node index.js and not rely on . getting resolved to index.js. But that’s a much larger breaking change and should probably be proposed in its own issue to gauge how people feel about it.

@avivkeller
Copy link
Member Author

True, with all of the changes that could be made around this functionality, you'd probably right that a discussion with @nodejs/loaders (or the relevant team).

@avivkeller avivkeller closed this Aug 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cli Issues and PRs related to the Node.js command line interface. module Issues and PRs related to the module subsystem. needs-ci PRs that need a full CI run. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Strange resolving order using "node ." to start an app node . runs a different file on node 10 than 8
6 participants