nodejs / nodejs/import-in-the-middle

IITM does not hook an indirect import of the "main" file, differing from RITM

Open
#239 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
170
Forks
58
Avg merge
3d 19h
Merged PRs (30d)
7

Description

The problem

This works:

Hook(['ioredis'], (exports, name, baseDir) => {
  console.log('HIT: name=%s', name)  // matched, name=="ioredis"
})
await import('ioredis')

but IITM does not match when the module "main" file is deep-imported:

Hook(['ioredis'], (exports, name, baseDir) => {
  console.log('HIT: name=%s', name)  // Note: IITM does not match here
})
await import('ioredis/built/index.js')  // deep import of the module "main" file

This does work with RITM.

RITM does extra work (using require.resolve(moduleName)) to realize that the loaded filename/URL (e.g. "/Users/trentm/my-app/node_modules/ioredis/built/index.js" in this case) file is the package "main" file, and then returns the module name rather than the internal file path.

Fixing it?

I don't know how IITM could fix this.

RITM is using require.resolve(modName).
For IITM to do the equivalent, it would have to use import.meta.resolve(modName). However, IIUC, that can only be used in an ESM module and all the IITM code here is CommonJS at this point.

There is an argument to be made that perhaps this need not be changed to match RITM, because:

  • It is nice that IITM isn't doing this extra require.resolve(...)-type work for many loads (RITM could likely cache better).
  • This should be rare, right? Not sure. Brian's early commit changing the API to match RITM included an assertion that Hook(['c8']) does not match import 'c8/index.js', which is interesting.
  • As mentioned in "Option 2" of https://github.com/nodejs/import-in-the-middle/issues/238 I think observability tools moving to specifying the exact implementation files to monkey-patch, rather than entry-points (including the module name) would be more robust. I.e. prefer hooking ioredis/built/index.js over hooking ioredis.

Granted that means changing instrumentations... and coping with the IITM/RITM difference, or perhaps getting RITM to add that 4th modPath arg I mentioned in https://github.com/nodejs/import-in-the-middle/issues/238

Thoughts?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the difference between IITM and RITM for the direct and deep imports shown in the issue. Read RITM's require.resolve logic in index.js and review IITM's CommonJS implementation alongside the import.meta.resolve constraint. Done means the project has a decided behavior for matching a package's main file, with the corresponding compatibility or documentation change identified.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.