In the Node runtime, as a CommonJS consumer, you can't interact with ESM at all.
require always does a CJS resolution
In a module, you can only import other modules, and they need to have extensions.
Idea: if what Node has today is the best that it will ever deliver...
We'd have to redo basically everything in the CJS resolution scheme we do.
We'd need to add .mjs resolution, but error on that.
There will need to be a module format output.
Also, import(...) would...need to not be imported.
Wait, why would you want any of this?
You want to migrate consuming code (?)
Should we emit .mjs files?
Shouldn't emit .ts files to .mjs files because that'd be a massive breaking change.
Need a new module field?
Need .mts and .cts? * .mtsx and .ctsx? * .d.mts and .d.cts?
This is absolutely unreasonable. * Need to be able to disambiguate format of the original inputs. * Could it be in-band? * File extensions mean you don't need to read the file contents.
As long as we don't rewrite imports (and we won't because it's error prone and requires whole-program knowledge), then we need the disambiguators.
Take the following example
foo/package.json
foo/index.js (this is ESM)
foo/index.cjs (this is CJS)
require("foo") breaks because it'll resolve to foo/index.js
import "foo" doesn't work because it won't resolve to /index.js because Node thinks it's too magical for ESM.
This logic is extremely complex.
"The combinatorics of this are extremely absurd."
Can we come up with a smaller set of what is supported? * By doing that, it provides a prescriptive direction for users who ask "how do I write ES modules in Node and TypeScript?"
But have to be smart about what we "leave on the table" and what that breaks. * Also want to leave things open for later additions.
Conclusion:
.mjs in an import path is doable long-term, but not
Node ESM support as a whole will need to be scoped out. * .mjs output is troublesome.
The defaults make little sense in the editor - means that users need to configure their editors to load tsserver with yarn. Very opt-in.
Also, while guidance is to stick to one version of package manager, users sometimes mix/match package managers and different versions.
Kind of hard to be sure what doing the right thing means here that doesn't require the same level of configuration as an LS plugin that overrides resolution