-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
Relax package.json#imports prefix #49182
Comments
As a maintainer of Rspack, I find our users(webpack | rspack users) choose tsconfig paths over subpaths imports for the following reasons:
|
I think the main goal of removing the prefix would be to reduce the migration costs here. You could still use whatever prefix you desire such as An additional desire might be to move a single source of truth since TS and bundlers also support tsconfig in various plugin/etc scenarios but the runtime does not. Making runtime and bundler behave the same is a big maintenance burden quite often. I'm open to alternative that solve this but it seems removing the prefix would solve this use case including monorepos at the cost of a tooling update. |
TBH tsconfig paths is not an ideal way to treat as single source of truth because it's super complex and the parsing work is very high(json comment support, extends support, project reference support), but since it's the only alias configuration typescript recognize, I can't think of a better alternative, maybe @andrewbranch have better suggestions? |
Personally, I very much like that there is an enforced prefix there. It makes it obvious what this import specifier is about and it also clearly defines where I should look for the "manifest" of how this specifier might be resolved. To address some of the @hardfist's points:
|
I think the enforced prefix is critically important for clarity. Aesthetics aren't what's important here, and eventually the long tail of tools that have done things their own way for a decade will catch up to doing what node does, as they've always done, and people will migrate to the built-in approach. |
@ljharb this isn't purely aesthetics, these are being used to alias bare specifiers like package names which is a different capability than what we currently allow. |
If I had to guess, I would say that the I think things would be marginally better if modern tools didn’t adopt tsconfig I personally like the |
@bmeck npm already has overrides for that. |
from new tool point of view,migration cost is the key point of new tools adoption,if users can migrate to subpath import without changing code,we can sugget users do that,but if they need to modify tons of code,new tool has to find new way to meet users needs to reduce migration cost other than ask users to change their code to meet standard |
Unless I’m misremembering, the There’s also self-referencing a package by its name, which is a different, even less well-known feature. You can do something similar to what you’re discussing above, relative to the root of the project. For example, with a {
"name": "~",
"type": "module",
"exports": {
"./*": "./*"
}
} and a import { num } from '~/foo.js' And the You could also use the {
"name": "~",
"type": "module",
"exports": {
"./*": "./src/*"
}
} Then if you move It doesn’t need to be |
@ljharb overrides are quite different, they affect siblings and propagate through the module graph in various ways such as fallthrough. Additionally they are an affect at installation time rather than runtime so things that do work using @GeoffreyBooth to some extent that can solve it but using self referential import w/o a valid registry name means it cannot be used for dependencies/monorepo scenarios. It also lacks one of the key reasons that people are using |
It sounds like, rather than removing the prefix, what node may want is application-level import map support? |
When you say “redirect bare imports” are you saying like “I want to redirect Regardless, I think this is getting too abstract. If |
@ljharb no, these are being locally aliased inside a package scope. We can already do global aliasing with policies for administration anyway so that is less needed. This is for package authors. |
@GeoffreyBooth the ask is pretty small already I am not willing to split it up. Likewise not up for long months of discussion so not eager to go down that route I've done before |
Not really. The proposed solution about
Which is essentially, “cover all use cases that You can close it if you’d like, or reopen with a focused use case. |
Definitely not the ask. The ask is to relax the rule to cover more use cases |
As a quick note, Yarn supports this pattern natively via the {
"dependencies": {
"app": "link:./src"
}
} Since those protocols aren't fully supported by other package managers they aren't suitable for published libraries, but they work as you would expect for regular applications. |
What use cases? |
From the general support of other tools the field in question is used for:
These actually very closely match how Importantly:
Similarly, other tooling like @arcanis is pointing out does provide local aliasing options for similar purposes. I do not think the solution needs to match tsconfig less we just want to implement that but a variety of tooling is covering things that |
What’s an example of this? |
@bmeck why do they need to be mapped in situ? meaning, if a package author wants a path to be mappable, why not add it to I guess what I'm asking for is, why is avoiding that diff churn worth giving up the amount of resolution information you can reliably infer from a file? |
I suppose the argument here is that there is currently less awareness of So we have to weigh if we think there is a very real risk of fragmentation / lack of adoption, versus making the feature more useful but potentially making it harder to trace mapping rules without context. I don't know the answer to the above, but we should try to listen to users here? |
Sure, but like I wrote earlier, let’s first dig up the reason for the current design. Why the restriction that imports need to start with |
The reasoning was that it creates a strong distinction between normal package dependencies and imports field mappings so there is no conflating of the lookup rules. Allowing imports to shadow normal package dependency lookups introduces ambiguity in the module system where the reason why a |
What are the exact needs of users here? Like, I get that it's something about wanting to blindly remap any specifiers inside their package to whatever they want, but why do they want that? TS paths, in my experience, are mostly used to get a root-relative bare specifier so they don't have to have variable numbers of |
I'll weigh in with my own use case: Transparently supporting a JavaScript runtime that doesn't provide any builtins. Without the {
"imports": {
"events": {
"<runtime>": "<runtime>-events",
"default": "events"
}
}
} Alas, due to the
Edit: I just realised I can't even do that with a |
All the arguments have already been said, but I would like to emphasize, that in my opinion current behavior of Node.js is correct and useful, nothing need to change, Node.js side. Using
However, I wish TypeScript, could support it better, but seems like microsoft/TypeScript#55015 already doing it (hope it will be merged soon). |
Reported an issue related to subpath imports and |
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the
never-stale
|
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. |
What is the problem this feature will solve?
Tools such as rspack, bun, typescript, remix, and turbo are all looking at using tsconfig.json#compilerOptions.paths . This is in part due to constraints on package.json#imports and it lacking the ability to fully alias the entire import space. These also seem to have differing constraints and some are doing something outside the standard TS behavior on purpose.
What is the feature you are proposing to solve the problem?
The
package.json#imports
field seems sufficient from reading some twitter threads involving a few maintainers from remix or rspack except for the prefix#
constraint. I propose getting feedback from these tools on removing the constraint if that would be sufficient for their users’ general needs. If it is sufficient we could encourage people to use a single way of doing this allowing tooling to avoid divergence and interop woes.This would not cover global aliasing which already can be covered with policy redirects but likely is not desirable/sufficient for some subset of users. My hope is that subset is small enough to avoid the issue blocking this entirely.
What alternatives have you considered?
Supporting tsconfig.json in a limited subset to alleviate the user needs.
cc @nodejs/loaders @nodejs/modules
The text was updated successfully, but these errors were encountered: