-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hashbang not resolving --loader
relative to entry
#23868
Comments
this isn't a bug. most OSes only use the first argument of a shebang. we can't put flags in it. also your example code won't really work because the file with the loader isn't used to resolve itself because it doesn't exist yet at that point. |
It actually works for me fine, except if cwd is not the same. In the folder, node works and the loader kicks in. Outside the folder (anywhere else) calling Edit: My use case is not most OSes. |
I don't think we should try to encourage using a shebang like this because it won't work in most places, even in the same cwd. https://linux.die.net/man/2/execve |
Can we consider this not less lowest-common-denominator shebangs, but more from the general case of a shebang that supports this (my case and maybe more): Command line [cwd]» node --experimental-modules --loader ./index.mjs index.mjs Shebang #!/usr/bin/env node --experimental-modules --loader ./index.mjs Can we agree that in the cases where they work (and the do for me) between those two, Contrast this How can we rationalize Any thoughts? Note: there is only one index.mjs |
@SMotaal i'm not sure what you're trying to say, but I think that the current behaviour is how it should be. |
Any other Collaborators want to chime in on this one? Seems like the flags-in-shebang issue/question/request could conceivably be especially relevant to @nodejs/tooling folks? |
this isn't a bug, nor is it a "feature". hashbangs are an os level construct, not something node provides. |
If this is a problem specific to shebangs, I don’t understand why. I do understand the lowest-common-denominator shebang behavior, but not how this relates to Node’s handling of relative paths. If the desired behavior is limited to certain OSes and would break in others, it may be difficult to rally much support. |
my understanding of this issue was that @SMotaal wanted to use hashbangs for esm and something about it wasn't working. if the issue isn't specific to hashbangs can it be rephrased? |
@boneskull I think it depends on how you look at it and I am finding it tricky to rephrase/reframe this as @devsnek pointed out but I will try. One way to look at it is to look at it relative to the current implementation. Essentially, the fact that it is a hashbang does not factor into the behaviour. There is no distinction between running Another way to look at it is to consider the practical uses of the different aspects. A hashbang is a static header of the main entry point of the node process. A custom I am not ignoring the technical considerations that this would require. At the same time I am considering the current limitations on the future usability of this flag. |
@SMotaal you're saying that paths in the hashbang should be resolved from the file location, not the cwd? |
I am not sure I am prepared to make this generalization on all paths, but for loader specifically and cases where the path points to a resource that bootstraps the runtime needed for the entry point to actually function.
This part is really where I see a divergence where I imagine that node will need a mechanism to distinguish when it is executing from a hashbang. If not offered by platforms, then a very raw idea to do this is to ensure that the stringified arguments (spaces notwithstanding) occurs at index 0 of the main entry before it even tries to locate the loader — obviously this needs work and just intended to inspire a better and cleaner solution. |
For reference,
What could be done is add a new I don't know if this works for $ NODE_PATH=..:${NODE_PATH} ../bar.js
foo |
@SMotaal ok thanks for rephrasing. i would still say that the current behaviour is "working as intended": 1st, hashbangs are "above" node, we don't define their behavior or interpret them. 2nd, node exec flags (such as |
I absolutely agree, but I also think that now that Hashbangs are part of the spec, and they are specifically relevant for node modules because they are executables, I am inclined to see them more within the domain of node moving forward. Not to imply that we define their behaviour, just to say that we define our behaviour in response to their intent which we interpret to maximize their utility and minimize their semantic dissonance. The 2nd point is not an exclusive thing, just consider my own module as an example, it is the entry and loader in a single file, and once the loader loads itself, it will use the loader to resolve files otherwise not resolved. And while this loader is application bound, it can never be used except when it is the entry point (crazy 👿 right?) |
@Trott Can we please hold off on unlabeling until we had a chance to hash out the different point of views. I honestly see this as a feature worth discussing. |
@SMotaal I don't see how hashbangs could be in the domain of Node.js. What are you proposing specifically? Also cc @nodejs/modules |
Let me try to phrase this through the example in this issue:
Please appreciate however that I am at a disadvantage on implementation specifics. My argument comes from a user-centric consideration. So even if technically we need to work on a solution, it is fair to also try to appreciate the user's side, one does not negate the other. |
@mcollina So in terms of the subset of hashbangs that fall inside the domain of node, my position is that when node can determine that it is running via a shebang, it can decide how it chooses to handle it's own behaviour to deal with the arguments. There is work to actually do the first part, I merely speak in an abstract sense. But suppose that we are able to determine that we're bootstrapping in shebang mode, don't you think that some behaviours can be better handled to yield a more pragmatic experience from the end user's perspective? |
Can you please articulate how Node.js can determine if it is running via an hashbang? Could you maybe send a PR to add this capability to Node.js itself? |
I agree with @mcollina. We first need confirmation that Node can know it is running via a hashbang, then only it makes sense to use our time to discuss how we want to handle this case. |
First, and not to sound discouraging, but I must restate that I have limited experience on that front. So let's try to paraphrase the idea I had in mind as a first step to allow us and specifically the more experienced on that front to see if it may have merit or is worth exploring. During bootstrap, generally, node synthesizes the But it is not without complexities, specifically if the OS does not pass arguments of the shebang. In this case, node will not be able to use this approach to detect that it was shebang. Finding a graceful way to handle this divide is best left to the creative problem solving efforts of those with more experience on the topic. |
@SMotaal I've tagged this feature request. I'll be happy to review a contribution that add some capability to detect if Node.js is running with an hashbang. I don't think this is doable or easy to maintain, so I'll keep being very skeptical on the topic (I'm happy to be proven wrong). |
@targos I think what is missing is input from those with experience to weigh in on my very raw suggestion first. While I normally didn't mind taking a few days or weeks to catch up when problem solving, I think that this one is one too deep in my 1.5 yr distraction which initial was just to be able to use modules back in 2017 😄. Then, if we see that there is a possible solution that has due confidence, I am happy to do my part. |
@boneskull I absolutely agree on the meaning of I wanted to explore ideas like dropping the |
@SMotaal Sure. I didn't want to say that you must be the one who does the investigation, sorry if I wasn't clear on that point. I just want to make sure we answer the questions in the right order :) |
Interpreter directives (Hashbangs / Shebangs) do not parse consistently across shells. I do not believe we should attempt to specify behavior within node itself due to this as node's behavior could differ from shell behavior. |
I'm a bit confused by this, there seem to be a mix of issues discussed, but note that most scripting languages use posix option syntax, and have short-option versions of any long options, particularly any long options that are credible candidates for use in #! lines, so while
would not work, traditional scripting languages would allow something like
which fits within the "only one optional arg" limitation of exec. Node doesn't use standard option syntax, so this doesn't work for it. Perhaps it should. |
This is something I've really been wanting, my current solution is to use the This doesn't tie to to shebangs in anyway as it would just work as a command e.g.: # This resolves the path given relative to ./path/to/my/module.js rather than the cwd
# (e.g. path.resolve("./path./to/my/module.js", "./my-loader.js")
node --relative-loader ./my-loader.js ./path/to/my/module.js # This would resolve ts-node/esm relative to ./path/to/my/node_modules/ rather than the cwd
# (e.g. like import.meta.resolve("ts-node/esm") from within "./path/to/my/module.js")
node --relative-loader ts-node/esm ./path/to/my/module.js This would make shebangs be as simple as: #!/usr/bin/env -S node --relative-loader ts-node/esm
console.log("Hello"); |
I have an alternate proposal that could resolve this a little more properly: #40594 Worth noting that multiple arguments in a shebang is non-portable anyways: https://stackoverflow.com/questions/4303128/how-to-use-multiple-arguments-for-awk-with-a-shebang-i-e - that's one of the motivating factors of that feature request. |
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document. |
There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment. For more information on how the project manages feature requests, please consult the feature request management document. |
--experimental-modules
(only)When using shebangs to specify
--loader
specifically for--experimental-modules
a file could want to use a relative path to it's own loader file.In this specific case, the module file is it's own loader, as if things are not already complicated enough.
The issue is not related to modules down the road, it is strictly related to the current way relative
--loader
paths are resolved.Executing this file from other paths other than it's own directory looks for
./index.mjs
in the cwd and not the file's own directory.I believe that Loader being a variable aspect of a shebang is at least problematic, more so risky, and simply not practical (I could be wrong).
Can we fix (or justify) this bug (or feature) please?
The text was updated successfully, but these errors were encountered: