Skip to content

--preserve-symlinks-main doesn't work #41000

Description

@pauldraper

Version

v17.0.1

Platform

Linux paul 5.4.0-90-generic #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

Create a package with a file and a symlink to a file in a different directory.

echo 'require("./lib.js")' > file.js
mkdir package
> package/lib.js
ln -rs file.js package/index.js

Run Node.js with the package as the entrypoint.

node --preserve-symlinks --preserve-symlinks-main ./package

How often does it reproduce? Is there a required condition?

The feature --preserve-symlinks-main works with some file structures and doesn't work with others (like the example). I haven't yet figured out the general rule.

What is the expected behavior?

Node.js runs without error.

Namely, the entry point /home/paul/example/package/index.js resolves ./lib.js to /home/paul/example/package/lib.js

What do you see instead?

Node.js errs:

node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module './lib.js'
Require stack:
- /home/paul/example/file.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/home/paul/dev/example/file.js:1:1)
    at Module._compile (node:internal/modules/cjs/loader:1095:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1147:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/home/paul/example/file.js' ]
}

Notice that Node.js has resolved /home/paul/example/package/index.js to its realpath (/home/paul/example/file.js), causing module resolution to fail.

Additional information

The validity of the example can be confirmed by replacing the symlink with a hardlink (ln file.js package/index.js), after which module resolution works.

Activity

  1. added
    confirmed-bugIssues and PRs for confirmed bugs.
    docIssues and PRs related to Node.js documentation.
    good first issueIssues that are suitable for first-time contributors.
    and removed
    confirmed-bugIssues and PRs for confirmed bugs.
    docIssues and PRs related to Node.js documentation.
    on Dec 16, 2023
  2. dgoldstein0 commented on Dec 16, 2023

    @dgoldstein0

    hm, the one thing that comes to mind is that I've only ever used --preserve-symlinks-main with full file paths. Does it repro with

    node --preserve-symlinks --preserve-symlinks-main ./package/index.js
    

    Also it was implemented before ESM was supported by default in node, so could be a commonjs vs ESM module loading issue.

  3. added a commit that references this issue on Dec 29, 2023
  4. mrgrain commented on Jan 3, 2024

    @mrgrain

    I can easily reproduce this with npm:

    $ node --preserve-symlinks --preserve-symlinks-main ./path/to/global/installs/node_modules/bin/npm --version
    
    node:internal/modules/cjs/loader:1078
      throw err;
      ^
    
    Error: Cannot find module '../lib/cli.js'
    
  5. dgoldstein0 commented on Jan 3, 2024

    @dgoldstein0

    not sure I entirely understand your npm example but in general I would not expect --preserve-symlinks-main to be usable with a node_modules/.bin/thing main argument - thing there would be a symlink into an entirely different folder, probably node_modules/thing/cli.js or similar, and then require()s or imports in cli.js should be resolved relative to node_modules/thing/cli.js, not the node_modules/.bin/thing. So I don't think your npm example is a valid reproduction.

  6. added a commit that references this issue on Jan 10, 2024
  7. added a commit that references this issue on Feb 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueIssues that are suitable for first-time contributors.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions