fix: ensure the callback 'name' arg is the module name when matching the module main file, even when 'internals: true' option is used#241
Conversation
…ies and specifier (submodule) matching
…mproved import(cjs) export sniffing
…ine, but CI currently tests v21 which did NOT get sufficient backports to work for these test files
…to module main file, even when 'internals: true' option is used This implements "option 1" of nodejs#238 Using the `got` module as an example, the issue was that the following two hooks would have a different `name` value when calling back when the `got` main file (".../node_modules/got/dist/source/index.js") was loaded: Hook(['got'], (exports, name) => { ... }) Hook(['got'], {internals: true}, (exports, name) => { ... }) In the first case `name === 'got'`, in the second case `name === 'got/dist/source/index.js`. This differed from RITM behaviour where `name === 'got'` in both cases. This *also* fixes an issue with IITM not properly hooking an absolute path: when the absolute path being imported happened to be in a "node_modules" subdir. Closes: nodejs#238
trentm
left a comment
There was a problem hiding this comment.
Add some notes for reviewers.
| const isBuiltin = name.startsWith('node:') | ||
| let baseDir | ||
| const loadUrl = name | ||
| const isNodeUrl = loadUrl.startsWith('node:') |
There was a problem hiding this comment.
Reviewer note: The name change to isNodeUrl is to avoid the name isBuiltin for the actual isBuiltin function from the node:module module in a separate PR (https://github.com/nodejs/import-in-the-middle/pull/240/files).
| Error.stackTraceLimit = stackTraceLimit | ||
|
|
||
| if (filePath) { | ||
| const details = moduleDetailsFromPath(filePath) |
There was a problem hiding this comment.
Reviewer note: This section changes to only do the moduleDetailsFromPath() parsing if we have a file:// URL that was successfully converted to a path.
| callHookFn(hookFn, namespace, name, baseDir) | ||
| } else if (internals) { | ||
| const internalPath = name + path.sep + path.relative(baseDir, filePath) | ||
| callHookFn(hookFn, namespace, internalPath, baseDir) |
There was a problem hiding this comment.
Reviewer note: This part of the change (that moves the } else if (internals) {-block to be after the else if (baseDir.endsWith(specifier..-block) is for the first/primary fix in this PR: the fix the name in the callback to match what RITM does.
The rest of the changes in "index.js" are for the absolute-paths fix.
|
|
||
| const path = require('path') | ||
| const parse = require('module-details-from-path') | ||
| const moduleDetailsFromPath = require('module-details-from-path') |
|
PTAL, merging from main with a merge conflict dismissed reviews. Thanks. |
|
I did not get the chance to fully review this before it landed and I believe this change is actually not what we want, no matter that it deviates from ritm. The reason is: if we declare @trentm instead of aligning with ritm, I think we should consider changing ritm to also load the internal file when being loaded with the module name. |
This implements "option 1" of #238
Using the
gotmodule as an example, the issue was that the followingtwo hooks would have a different
namevalue in the callback when thegotmain file (".../node_modules/got/dist/source/index.js") wasloaded:
In the first case
name === 'got',in the second case
name === 'got/dist/source/index.js.This differed from RITM behaviour where
name === 'got'in both cases.This also fixes an issue with IITM not properly hooking an absolute
path: when the absolute path being imported happened to be in a
"node_modules" subdir.
Closes: #238
Checklist
Details on the absolute-path import fixes
Consider this can-iitm-match-abs-paths.mjs which attempts to hook four absolute paths, with slightly different cases:
With current IITM:
baseDirin the callback.The reason for both issues is that the absolute files happen to be under a
.../node_modules/...tree. Case 3 accidentally matches using thematchArg === specifierbranch, rather than the intended match branch for absolute paths.With the changes in this PR:
Comparing to RITM
Using the equivalent test script for RITM:
can-ritm-match-abs-paths.cjs
the result is:
All four match.
(Aside: the
nameandbaseDirvalues are different between IITM and RITM, but that is a topic for a separate PR.)