-
Notifications
You must be signed in to change notification settings - Fork 44
import(cjs) messes with module.parent #469
Comments
Thanks for bringing this up, I don't think we were tracking this yet! Your options sound spot-on.
Making
Yeah, I think to me
I think it'll depend on how widespread this issue is. Can you share which package (or packages) this happened with? Capturing a list here may make it easier for us to determine the impact. |
One use case for |
@SimenB not all ESM have a valid file path associated with them ( |
For reference, I have seen is-port-available and pdf-parse use a similar pattern. Not highly used modules either, but there are certainly others. |
I think we should deprecate |
Folks, I'm In fact, I'm in need of this feature to be functional for ES modules too. The intended use-case is to be able to visualize module graphs. To be able to traverse these graphs, I'd need this parent-children relationship metadata. This also relates to APMs. Additionally, I do not think something so important should be deprecated merely to discourage a pattern. |
@DerekNonGeneric parent does not give an accurate traversal of a graph anyway, because modules can actually have multiple parents. you should start at the entrypoint and traverse down. |
I'm sorry, can you clarify? I'm aware CJS and ES modules use different algorithms, but |
@DerekNonGeneric like |
That's perfectly fine! I'm interested in visualizing the graph as it exists during execution (not conceptually). |
@DerekNonGeneric ... during execution both a.js and b.js required x.js. a cjs module graph would show a directed edge from a.js to x.js and a directed edge from b.js to x.js. |
I'm unclear why this information would be useful to a stack trace, but unavailable to userland. I'd have to do more research, but this seems like valuable information is being lost. |
@DerekNonGeneric the graph structure is preserved (in a more accurate manner) via |
@devsnek, thank you. I don't feel the ends justify the means here. It seems like the correct way to go about this would be to deprecate the module that's using the discouraged pattern, not deprecate a runtime feature because people are using it incorrectly. |
@DerekNonGeneric my point is that there is no "correct" way to use |
This would also prevent building stack trace libraries too, though wouldn't it? Perhaps a good compromise would be to rename it to something else as opposed to deprecation? |
@DerekNonGeneric what does |
I was under the impression that one would be able to use a cache (that hasn't been tampered with) to determine the execution order. From my perspective, what would justify deprecation would be if the contents of (It's not just a type, it's actually a fully-populated and observable module record-like object.) |
@DerekNonGeneric it tells you what the first module to require a module is, but that doesn't allow you to discern the execution order of the graph as a whole. |
Reading the use case, we can make that an issue rather than a side effect from the existence of |
@bmeck, good plan, will do. |
I happened to stumble upon a published tip (post) with a legitimate use of
if (!module.parent) {
// ran with `node something.js`
app.listen(8088, function() {
console.log('app listening on port 8088');
})
} else {
// used with `require('/.something.js')`
module.exports = app;
} I'm unsure we have a viable replacement for this in ES module context. I would hope this wouldn't involve |
That's part of a separate discussion about how and if entries should be classified: nodejs/node#49440 |
@devsnek, they're certainly very similar, but according to Guy in nodejs/node#49440:
That issue seems to be about CLI vs package entry points (main). I would be interested in knowing the module graph entry point (no ancestors / root node). |
that's somewhat purposely not a thing in esm. in any case this issue is about module.parent which is being deprecated so i'm going to close it out. |
@aduh95, your PR is recommending to use … if (require.main === module) {
} … as opposed to … if (!module.parent) {
} These may appear to achieve the same desired effect, but that's not the case in
Therefore, if I'm not mistaken, Ultimately, I'm not attached to the outcome of the deprecation PR since it's |
It's not any more or less credible than every other option. There's no reliability difference (afaik) between $ cat /tmp/my.cjs
console.log(module.parent ? "has parent" : "no parent")
$ node /tmp/my.cjs
no parent
$ node -e "require('/tmp/my.cjs')"
has parent
$ node -e "require('module')._load('/tmp/my.cjs', null, true)"
no parent You can even modify
I don't agree since |
I believe
That doesn't seem like a problem we would want to fix, I guess people that do "hijack" Anyway, |
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469 PR-URL: nodejs#32217 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469 PR-URL: nodejs#32217 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469 Backport-PR-URL: #33533 PR-URL: #32217 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469 Backport-PR-URL: #33533 PR-URL: #32217 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469 PR-URL: nodejs#32217 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469 PR-URL: #32217 Backport-PR-URL: #34592 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Some packages use a check on
module.parent
to know if they are launched from CLI or required by another module:This works fine if you use
require
(I tried from both CJS and ES modules):However, when importing from ESM, that doesn't work:
Same for dynamic imports:
I can see three ways to tackle this issue, but none is very satisfying to me:
module.parent
truthy when a CJS is imported (although I have no idea what it could look like).module.parent
? Packages usingrequire.main===module
are fine, so that's what library authors should be using to test this, right?module.createRequire
to workaround the issue.The text was updated successfully, but these errors were encountered: