@ljharb brought up in the exports patterns PR that it would be worthwhile to ensure the * matching in exports patterns permits empty matches to ensure consistency with all other wildcard schemes.
I agree this conceptual integrity could make sense, and in addition such a feature could be added as a fully backwards compatible change to exports patterns so I would be glad to see this land either way.
One benefit I really liked of not matching the null match is that currently:
{
"exports": {
"./": "./sub/"
}
}
will cause import.meta.resolve('pkg/') to resolve into the sub/ folder. As a result this means import.meta.resolve('pkg/') is not a reliable way to get a package root (and also relates to the package.json resolution discussion previously).
If we now use patterns here:
{
"exports": {
"./*": "./sub/*"
}
}
then as currently written, import.meta.resolve('pkg/') will throw a PACKAGE_PATH_NOT_EXPORTED error because the empty string match is not permitted and thus this "reserves" this space for us to treat it as a special package base resolution case which seems a really useful property for a resolver to have to me in being able to resolve the base of any package this way.
On the other hand I do not have any conceptual arguments against matching the empty string pattern other than that I simply can't think of a single use case in which it is useful. If the argument is purely one of conceptual consistency being important I'm all for that though, but would be concerned about invalidating a perfectly good use case in the name of that.
@ljharb brought up in the exports patterns PR that it would be worthwhile to ensure the
*matching in exports patterns permits empty matches to ensure consistency with all other wildcard schemes.I agree this conceptual integrity could make sense, and in addition such a feature could be added as a fully backwards compatible change to exports patterns so I would be glad to see this land either way.
One benefit I really liked of not matching the null match is that currently:
will cause
import.meta.resolve('pkg/')to resolve into thesub/folder. As a result this meansimport.meta.resolve('pkg/')is not a reliable way to get a package root (and also relates to the package.json resolution discussion previously).If we now use patterns here:
then as currently written,
import.meta.resolve('pkg/')will throw aPACKAGE_PATH_NOT_EXPORTEDerror because the empty string match is not permitted and thus this "reserves" this space for us to treat it as a special package base resolution case which seems a really useful property for a resolver to have to me in being able to resolve the base of any package this way.On the other hand I do not have any conceptual arguments against matching the empty string pattern other than that I simply can't think of a single use case in which it is useful. If the argument is purely one of conceptual consistency being important I'm all for that though, but would be concerned about invalidating a perfectly good use case in the name of that.