You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
node - a version of Node 11 and earlier resolution
node16 - a version of resolutiont that captures all the new Node 16 features for ESM.
What's the problem?
Bundlers support lots of useful things. TypeScript doesn't really capture their behavior.
Example scenario:
Your project starts off using the node resolution strategy.
You add a dependency which specifies an exports field - but the node strategy doesn't understand that.
So TypeScript errors, but your bundler (e.g. Webpack) is fine.
You swap to the node16 or nodenext module resolution options to fix it.
TypeScript starts erroring on another dependency because it has "type": "module" but your project doesn't.
So TypeScript errors, but your bundler (e.g. Webpack) is fine.
You switch your file to a module - either by renaming it to .mts or adding "type": "module" to your package.json.
TypeScript starts erroring on a relative import because you didn't specify the extension.
So TypeScript errors, but your bundler (e.g. Webpack) is fine.
You specify the .js extension as TypeScript suggests.
Your bundler can no longer resolve the relative import because it doesn't know that a file ending in .js is supposed to map to .ts.
So your bundler (e.g. Webpack) errors, but TypeScript is fine.
You have to now configure your bundler further.
Friction!
Many behaviors of Node16 have been brought into bundlers, and bundlers can continue to provide many features that provide a nice UX (e.g. extensionless resolution).
Maybe a new hybrid mode?
Name is bikesheddable.
A basis for bundlers and maybe more.
node_modules lookups
Index files (e.g. ./folder -> ./folder/index.ts)
Extensionless (e.g. ./foo/bar -> ./foo/bar.ts)
Resolution of the exports field of package.json
.mts, .cts, "type" don't matter. Everything is
minimal
A basis for browsers and maybe more.
No node_modules etc.
Just relative URL paths with required extensions.
URLs?
Yes, %20 is a space.
So ./our%20assets/file.js is our assets/file.js.
Does import "bar.js" resolve to relative in browser contexts?
Have to check - believe WHATWG reserved this?
We probably don't want to resolve relative even if that's the case.
Maybe node becomes node-legacy
Feedback from the TC39 tools group was node -> node-legacy might not be a good call. Maybe call it node11
Does it make sense to call this node-cjs?
But it's the oldnode-cjs.
So it sounds like this new hybrid/conventional mode really thinks of everything as possibly synchronous ES modules.
Way to work around some of the shortcomings from package manager installation and package resolution.
Instead extracting all packages fully into node_modules and having your code resolve from the disk at runtime, Yarn calculates all the information ahead of time for packages.
Yarn creates a .pnp.cjs file that intercepts require (and sometimes file system APIs)
What's the advantage?
It's faster because it doesn't have to shuffle directory trees around.
Just plop a cached zip
"just check in your node_modules"
Gotcha?
Non-standard-ish
Nothing in Node that emulates it.
Have discussed it a few times. Why revisiting?
Resolution steps have been published.
Where do these zip files come from?
There's a cache, but it gets created from the npm registry.
You can navigate it with the right VS Code extension!
It causes crashes because we don't think files can exist in zip files.
Importing a resolver JS file is no longer a hard requirement.
Statically resolvable and specified.
Need to be able to read from a .zip file
PnP + "check in your dependencies" is one of the few things that mitigates supply chain attacks.
But npm ci etc?
Not really the reason for this. It is a nice bonus maybe. But the convenience is just fast workflows.
Okay, it's not in an executable file. Where is it?
.pnp.data.json
Great, we have the JSON, so how do we do the zip file support?
Have to roll our own or add a dependency.
Old .cjs file did all this for us. It was nice!
But did it? We still need to support path completion, virtualizing files, etc. Things work now, but the demo keeps crashing on the mounted files.
zip support is technically optional
But not really?
What about the old competing crux? Other possible strategies here?
Versioning concerns of specification?
Wrong abstraction? Shouldn't this be in Node.js anyway?
That's what's Yarn is trying to do out of band anyway - provide a way to leverage the right hooks.
Doesn't matter, TypeScript and friends need to reimplement their own custom resolution rules anyway.
Can we make it easier for Yarn to patch these?
Unclear - seems very hard.
Has to patch the System host, the ModuleResolutionHost, and more.
How does this compose between all the upcoming module work?
Substantial cost - short-term and long-term.
Last time the executable JS was the biggest concern. Are we changing our view?
Took time to address the original concerns.
Not seeing community convergence between different package managers and runtimes - though is this a blocker?
Hard to promise that we can keep up with updates.
What are the concerns?
Can't add every custom resolution algorithm - adding this means it'll be there forever.
Not clear on what the spec will add over time.
What can we do to alleviate here? Work with the existing process?
Is there a way to make patching easier?
The text was updated successfully, but these errors were encountered:
Module Resolution Proposals
#50152
classic
- node-like extensionless resolution implemented wrongnode
- a version of Node 11 and earlier resolutionnode16
- a version of resolutiont that captures all the new Node 16 features for ESM.node
resolution strategy.exports
field - but thenode
strategy doesn't understand that.node16
ornodenext
module resolution options to fix it."type": "module"
but your project doesn't..mts
or adding"type": "module"
to yourpackage.json
..js
extension as TypeScript suggests..js
is supposed to map to.ts
.hybrid
mode?node_modules
lookups./folder
->./folder/index.ts
)./foo/bar
->./foo/bar.ts
)exports
field ofpackage.json
.mts
,.cts
,"type"
don't matter. Everything isminimal
node_modules
etc.%20
is a space../our%20assets/file.js
isour assets/file.js
.import "bar.js"
resolve to relative in browser contexts?node
becomesnode-legacy
node
->node-legacy
might not be a good call. Maybe call itnode11
node-cjs
?node-cjs
.hybrid
/conventional
mode really thinks of everything as possibly synchronous ES modules.await
?hybrid
mode--moduleResolution bundler
?Yarn Plug'n'Play
#28289
#35206
node_modules
and having your code resolve from the disk at runtime, Yarn calculates all the information ahead of time for packages..pnp.cjs
file that interceptsrequire
(and sometimes file system APIs)zip
node_modules
"zip
files come from?.zip
filenpm ci
etc?.pnp.data.json
.cjs
file did all this for us. It was nice!System
host, theModuleResolutionHost
, and more.The text was updated successfully, but these errors were encountered: