Skip to content

JavaScript: require('..') of a directory with package.json "main" isn't followed; the call links to the local const #2964

Open

Description

@inth3shadows

A relative require() of a directory whose entry file is named by that directory's package.json "main" isn't followed. This includes require('..') and require('../') from a test folder up to the package root. The call then links to the local const holding the require result, a calls edge to a variable in the same file, and the real entry function gets no callers.

// package.json
{ "name": "srv", "main": "srv.js" }

// srv.js
'use strict'
function srv (opts) { return build(opts) }
function build (o) { return o }
module.exports = srv

// lib/index.js
function helper () { return 1 }
module.exports = helper

// lib/inner/package.json
{ "main": "entry.js" }
// lib/inner/entry.js
function inner () { return 2 }
module.exports = inner

// test/a.test.js
'use strict'
const Srv = require('..')
const Srv2 = require('../')
const Srv3 = require('../srv')
function t () { Srv(); Srv2(); Srv3() }

// b.js
const helper = require('./lib')
const inner = require('./lib/inner')
function u () { helper(); inner() }
call edge on main expected
Srv() (require('..')) Srv, the local const at test/a.test.js:2 (exact-match) ✗ srv in srv.js
Srv2() (require('../')) Srv2, the local const ✗ srv in srv.js
Srv3() (require('../srv')) srv in srv.js (import) ✓ same
helper() (require('./lib'), index.js) helper in lib/index.js (import) ✓ same
inner() (require('./lib/inner'), package.json main) inner, the local const in b.js ✗ inner in lib/inner/entry.js

A directory with an index.js resolves; only the "main" lookup is missing for relative directory paths.

Reproduced on main at 72f398a with CODEGRAPH_KERNEL=0. Linux/WSL2, Node 22.23.2.

Where it shows up. Every fastify (5df959f) test starts with const Fastify = require('..') (root package.json has "main": "fastify.js") and calls Fastify(). Checking every calls edge against the TypeScript checker (allowJs), 1,191 edges in fastify are these calls linking to each test file's own Fastify constant, and fastify() in fastify.js gets none of them as callers. require('..') / require('../..') from test/ is the usual way a package's tests load the package.

Expected. Resolve a relative directory specifier the way Node does: <dir>/package.json "main" (then <dir>/index.js). Also, a call through a binding that holds a require() result shouldn't become a calls edge to the binding's own const node.

Related: #2799 / #2502 (the same package.json entry lookup for a workspace package's name), #2263, #2189.

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions