hooking 'sub-module/foo' does not work if 'sub-module' is also in the set of modules to hook
Closed this issue · 3 comments
If you add this diff to "test/sub-module.js":
diff --git a/test/sub-module.js b/test/sub-module.js
index e6f104f..bafc6fb 100644
--- a/test/sub-module.js
+++ b/test/sub-module.js
@@ -7,7 +7,7 @@ const { Hook } = require('../')
test('require(\'sub-module/foo\') => sub-module/foo.js', function (t) {
t.plan(3)
- const hook = new Hook(['sub-module/foo'], function (exports, name, basedir) {
+ const hook = new Hook(['sub-module/foo', 'sub-module'], function (exports, name, basedir) {
t.equal(name, 'sub-module/foo')
return exports
})
then the test fails:
% node test/sub-module.js
TAP version 13
# require('sub-module/foo') => sub-module/foo.js
not ok 1 should be equal
---
operator: equal
expected: |-
'sub-module/foo'
actual: |-
'sub-module'
at: <anonymous> (/Users/trentm/el/require-in-the-middle3/test/sub-module.js:11:7)
stack: |-
Error: should be equal
at Test.assert [as _assert] (/Users/trentm/el/require-in-the-middle3/node_modules/tape/lib/test.js:273:48)
at Test.bound [as _assert] (/Users/trentm/el/require-in-the-middle3/node_modules/tape/lib/test.js:85:17)
at Test.equal (/Users/trentm/el/require-in-the-middle3/node_modules/tape/lib/test.js:434:7)
at Test.bound [as equal] (/Users/trentm/el/require-in-the-middle3/node_modules/tape/lib/test.js:85:17)
at /Users/trentm/el/require-in-the-middle3/test/sub-module.js:11:7
at Module.Hook._require.Module.require (/Users/trentm/el/require-in-the-middle3/index.js:262:28)
at require (node:internal/modules/cjs/helpers:119:18)
at Test.<anonymous> (/Users/trentm/el/require-in-the-middle3/test/sub-module.js:19:11)
at Test.bound [as _cb] (/Users/trentm/el/require-in-the-middle3/node_modules/tape/lib/test.js:85:17)
at Test.run (/Users/trentm/el/require-in-the-middle3/node_modules/tape/lib/test.js:104:7)
...
ok 2 should be equal
ok 3 should be equal
# require('sub-module/bar') => sub-module/bar/index.js
ok 4 should be equal
ok 5 should be equal
ok 6 should be equal
# require('sub-module/bar/../bar') => sub-module/bar/index.js
ok 7 should be equal
ok 8 should be equal
ok 9 should be equal
# require('sub-module/conflict') => sub-module/conflict.js
ok 10 should be equal
ok 11 should be equal
ok 12 should be equal
# require('sub-module/conflict/index.js') => sub-module/conflict/index.js
ok 13 should be equal
ok 14 should be equal
ok 15 should be equal
1..15
# tests 15
# pass 14
# fail 1
The reason is that fullModulePath
is not considered here if if the moduleName
is in the set of modules to hook:
require-in-the-middle/index.js
Lines 227 to 231 in 9ddb8c7
I think it is a bug that having the top-level module in the set of modules to hook breaks getting an onRequire
callback for a sub-module.
The real world case for this is that the current elastic-apm-node is using sub-modules with its RITM usage, and in elastic/apm-agent-nodejs#3657 we wanted to hook both (a) the top-level "mongodb" module and (b) a sub-module path ("mongodb/lib/cmap/connection_pool"). For this and other reasons, elastic-apm-node is changing its usage to not use sub-modules for its built-in instrumentations -- instead we are moving to using the {internals: true}
RITM option and hooking module-relative pathes, e.g. "mongodb/lib/cmap/connection_pool.js".
This changes means that this bug isn't a high priority issue for me. Please vote/comment/propose a PR if this is an important issue for you.
Note to self, part of the Kibana usage is here: https://github.com/elastic/kibana/blob/d6550efd3cc998b23d3de80d01a574e4c9073830/src/setup_node_env/harden/lodash_template.js#L12-L30
@pgayvallet There is a require-in-the-middle@7.2.1 release out with this now.