Description
Background
- @guybedford's Proposal: Proposal: Support loading package by own "name" #306
- Initial Implementation: module: resolve self-references node#29327
Open Questions
Use Cases
We know of a handful of use cases:
- "Test exports": Write unit tests for the public interface of a package using
exports
. - "Copyable examples": Write example code that works both within a checkout of a library's code and while using the library.
- "Project root require": Easily reference code from other parts of a project's directory structure. Usually expected to not be affected by external visibility.
All of these can be solved today, to a certain degree, using symlinks, special scripts, or features like loaders/require extensions. But there's no first-class support for them in node.
We need to decide which use cases are in scope and which aren't. Specifically: which use cases are in scope for shipping modules themselves. A use case not being in scope doesn't mean we should prevent it.
Outcome
- Are there other use cases we should track?
- Which use cases do we need to support for unflagging modules?
- Which use cases do we want node to encourage?
- For the use cases we need to support for unflagging, are there alternate solutions?
Shorter Syntactic Sugar
Some people have called for a shorter syntax to be used either in addition or instead of the package name. Most suggestions so far have been ASCII characters but each choice has come with concerns about existing uses:
~
: Used in the ecosystem for a different feature (require internal project files from a static root, not relative to the package scope). But that feature is close enough that it could count as ecosystem precedent. May be confused with posix expansion of home directories when an unquoted~
is used in shells.@
: Used in the ecosystem for a different feature (npm scopes). But that feature is close enough that it could count as ecosystem precedent. Also used in some languages (e.g. CoffeeScript, ruby) as a reference to "this" or "self".%
: Used in (URL) specifiers already for percentage encoding. Used in Windows for variable substitutions (%HOME%
). Sometimes associated with "placeholder".^
: Used in regular expressions and other places as "start" or "beginning". Can also refer to the control key.
Beyond ASCII, we could also use other characters since JS sources are usually UTF8:
- 📦: Package. Because it's relative to the package.
- 🦄: A truly special character.
Outcome
- Do we need a shorter specifier for shipping modules or could it be added later?
- Should there be a shorter specifier?
- Which short specifier should it be?
Opting In
This applies mostly to a world with syntactic sugar.
There are two downsides of sugar that may make opt-ins for them necessary:
- Every one of those characters may have been used as directory names, especially in CJS and on *nix systems. Which means that resolving them to the active package may not be what the author intended to happen.
- Without an opt-in or parsing every file within the scope, a pre-generated resolution map (e.g. import maps) would have to duplicate every single package's resolution. Once for public use, once for internal use with the special sugar syntax. This doesn't apply to the same degree for the name itself since in many cases those entries could collapse (depending on the exact URL structure).
Outcome
- Do we need an opt-in for shipping modules or could it be added later?
- Should we require an opt-in?
- Should we offer an opt-out?
- How should the opt-in or opt-out be expressed?
Resolution Order
In short: Should it apply before or after looking at node_modules
. The safer choice is likely "after node_modules
" but with opt-in it may also be possible to do it before.
Outcome
- If there is an opt-in, should this feature apply before or after
node_modules
? - If there is no opt-in, should this feature apply before or after
node_modules
? - If there is an opt-out, should this feature apply before or after
node_modules
?