Repository navigation
Migrate the TypeScript Project to Use Modules #35210
Description
Activity
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptCommittedThe team has roadmapped this issueThe team has roadmapped this issueInfrastructureIssue relates to TypeScript team infrastructureIssue relates to TypeScript team infrastructure
on Nov 19, 2019 sandersn commented
on Nov 19, 2019 MemberMore actionsReminder: 1000 is 1/36 of the total lines of checker.ts. That's fewer imports per source line than most Javascript I've written.
Reacted by AnyhowStep, Andrew Branch, Wenlu Wang, ExE Boss, Paul Draper, Thomas Mclennan, Brian, Dmytro Tiapukhin and 王一赫Reacted by Ryan Cavanaugh, Wenlu Wang, Josh Ghoulberg 👻, ExE Boss, Igor Oleinikov, Oliver Bell, Jesper Engberg, Amit Beckenstein, Brian, strager and 1 moreI don’t care so much about the tree-shaking, I just want to be able to consume TS using
importinstead ofrequire(). You can’t userequire()at all in Node in ESM files to my knowledge; I allow this in miniSphere but you then have to use an absolute path:
https://github.com/fatcerberus/spectacles-i/blob/master/buildtime/ts-tool.js#L35I want the above to be an relative path but I can’t because in my engine, using
importwould try to load it as ESM—and fail.This would resolve #32949 as well so 👍 🎉
Also,
.d.tsgeneration would be a good dog-fooding exercise of some of what we have to deal with in creating libraries based on TypeScript, so what you likely solve there would benefit all of us.Reminder: 1000 is 1/36 of the total lines of checker.ts.
To be fair, though,
checker.tsis absolutely massive. It's the only time I've ever encountered a source file in a project so large that GitHub totally refuses to display it. 😆(To be clear: I don't really buy the death-by-1000-imports argument. As long as a program is well-structured, this doesn't become an issue in my experience.)
(To be clear: I don't really buy the death-by-1000-imports argument. As long as a program is well-structured, this doesn't become an issue in my experience.)
And if you use a type self development language and environment, management of the imports is pretty easy... 😆
Daniel Rosenwasser (@DanielRosenwasser) You've missed out the biggest con: Moving from organising code in virtual hierarchies (ie namespaces) to a system based on the physical file system.
How is that a con?
Reacted by Daniel Rosenwasser, Stephen Wade and NDHReacted by Daniel Rosenwasser and kollsterHow is that a con?
I assume because the organization of the API has to conform the organization of development (source files).
But this is the reason barrel modules exist.
- addedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Nov 2, 2022 For those following this issue, the module conversion PR has been posted: #51387
Reacted by Evan Wallace, Max, lin72h, Paul Draper and AlejandroReacted by Yves M.- added a commit that references this issue
on Nov 7, 2022
Follow-up from #34899
Today, TypeScript is authored in a relatively outdated style that uses what are called "namespaces" (formerly "internal modules"). This used to have some advantages in being able to globally access the compiler in the browser, but nowadays bundlers make this possible without exposing internal authoring details.
Benefits of Modules
Authoring with namespaces has several disadvantages today, and moving to using ES module syntax per file would likely solve those issues. Here are some of the advantages to moving to modules.
Dog-fooding
Using namespaces separates our team from the way that the community authors code. We have to learn about bugs related to module resolution from external bug reports rather than hitting them ourselves on the team. That means we can't dog-food our product the same as most modern users.
We would also hit some of the challenges module users hit with external tooling (more on this later) but this is a good thing! It will help us build the appropriate empathy to improve the situation for users.
Leaner package size with share-able bundles
TypeScript ships at least 5 different JavaScript files that are meant for different purposes - but because of the nature of namespaces, the contents of every core file is duplicated in each output file - basically, think of this as us shipping 5 virtually identical
.exes because of their dependencies statically linked rather than being split into.dlls. So as a result, you end up withchecker.ts's contents included 5 times in every install oftypescript.Ideally,
tsc.jsandtypescript.jscould share a majority of the code generated fromsrc/compiler.As an end result, we would fix #27891
Faster builds and editing
Every keystroke involves re-checking the entire program, which involves merging every global namespace's symbol tables. Not clear how long this takes in practice, but you wouldn't need to wait for that per-keystroke when editing
checker.ts.Slightly more tree-shakeable
If you're only using TypeScript's parser, you shouldn't have to pay for the checker too. Would be nice to enable API consumers like this.
Challenges
Not stopping the world
We cannot stop the team from authoring code - ideally, nobody is touching the tops of most files, so this shouldn't be a huge problem.
Have break off part of
utilities.tsintoprivateUtilities.tsBecause
stripInternaldoes't work on an entire file level. On the other hand, that's really handy because you don't need to usestripInternal, you just never export from that module.d.tsbundlingWe'd presumably leverage something like API Extractor. This would be new infrastructure work, and it would have to integrate into our test suite (since we already do
.d.tsbaselining for our API.Death by 1000 imports
Not clear whether this is really a problem or just annoying, but people keep bringing it up.