-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type Stripping in node_modules/*/*.ts
#14
Comments
Adding a flag to allow type stripping in node_modules is trivial. |
Isn't there? The namespace I'm in favour of allowing publication of ts in general (as I'm also in favour of publishing jsx) because it allows the consumer to decide the output and avoids make-work steps and a game of telephone. |
I think that's possible, with loader hooks, Marco have been working on exposing the type stripping utilities for this exact use-case IIRC. |
@marco-ippolito I think maybe first needs to be identified:
It seems like trying to ban users from publishing Maybe better would be 4) Identifying and Addressing Downsides, listing out the real downsides which occur as a result of publishing |
It is possible with a loader hook: https://github.com/jakobjingleheimer/nodejs-loaders#jsx--tsx (This is about to be split into a monorepo and published separately as |
Btw as @aduh95 mentioned, if |
I agree that we should document the downsides of not supporting Summing them up are:
|
|
Theoretically, this shouldn't happen for plain monorepo use; the determination of "is in
The reduction in complexity here is from the tooling, though; something like
These kinds of restrictions do not help published TS source; TypeScript will load all of the source code given to it, including function/class bodies, expressions, etc. Publishing and loading "Slow types" is a bit of a misnomer becuase it's talking about "slow" in terms of generating declaration files from the perspective that the "slow types" require running There are other concerns here as well:
All of these problems are handled by transforming your code before publishing it. (My list is not exhaustive either; a proper combined list would of course be good.) |
What if we supported running in |
Downsides of Publishing
|
With clear metrics, it will be more clear what the tradeoffs are and what could be solved, optimized or worked around to minimize those downsides. Some projects may decide that the tradeoff is worth it:
|
I personally have, and I've seen many other projects have, mono-repos with npm workspaces (packages) that are not private, they are published as individual packages. The mono-repo's top-level |
Its a trade-off. If you want to run |
There's another problem with publishing |
@targos yeah, that was mentioned above a couple of times, including my list above:
I'll reword to be more clear |
On the list of reasons @jakebailey stated for why redistributable TS on npm is a cause for concern, I will add my agreement (and expand) on a couple of specific points raised regarding future compatibility of TS syntax.
These are just possibilities. It's hard to say whether they will play out. Regardless, it's very cheap for Node to be conservative and avoid complicating future evolution. We just need to avoid third-party redistributable code (i.e. npm deps) depending on Node supporting that syntax. Happily |
I don't understand why this helps; if the package is |
@andrewbranch did the analysis and shared his results here about a year ago: https://x.com/atcb/status/1705675335814271157 |
@jakebailey thanks! Updated my post above with those numbers. |
With numbers, I'm -1 on transpiling/stripping in |
To be clear, Andrew's numbers are comparing the cost of checking TS vs DTS. It seems fair to conclude we should continue encouraging distribution of DTS files in packages for faster checking of dependencies. That will help keep tsc and IDE usage fast. This could be considered somewhat independent of whether the executable code in the package is TS or JS. |
(@karlhorky messaged me wondering if I had an opinion so just going to jot it down here.) TL;DR: I pretty much agree with what TS core team is saying above. The way I'm building monorepos today, I wouldn't need this flag. My high-level thought these days on internal packaging for monorepos is: Compile like you're shipping to npm*, even though you're not. I find this simplifies the mental model. Your package consumers are going to look into As far as what's proposed in this issue goes, I admittedly don't have much of an opinion. There are a lot of different ways to build a monorepo today, many of which I'm not fond of. I try to teach folks my little happy path that I've carved out, but there are still plenty of valid, wonky things you can do, in the true spirit of JavaScript. If one were to follow the way that I happen to teach Workspace-building, this flag would be unnecessary, because there would be *: There are exceptions to this idea, like dual-publishing. In your monorepo, you're in control, so you don't necessarily have to cater to the unknown matrix of consumers of a public npm package. Example: you know your monorepo is committed to using ESM, so you don't have to dual-publish. **: I'm working from the assumption that you're not using |
Id add a flag to enable typescript in node_modules after the feature gets unflagged. Id also want to check if we can make it compatible with jsr 🌝 |
This is on the agenda for tomorrow's meeting, so I'll try to summarize the official TypeScript stance on why we are currently against running TypeScript source files within The TL;DR is:
AdvantagesThere are a few main advantages we see in running TypeScript within First, such a feature can simplify the publishing process for library authors because they will not need a build step before publishing to the registry. These developers can ship their code "as-is". The other advantage is that it can make it easier for users to debug library code, since sourcemaps would not be necessary (and sourcemaps are often either incorrect or tools may have issues in their sourcemap support). There is also another possible advantage, which is that it can make it easier for users to explore the implementations of their dependencies. Whereas today TypeScript will prefer jumping to DisadvantagesUnfortunately, we believe the disadvantages outweigh the advantages. The biggest disadvantage we see is that this feature would cause versioning headaches around TypeScript feature usage. If a library author decides to ship TypeScript syntax that is not understood by a specific version of Node.js or TypeScript, this makes the situation more complicated for library consumers. While TypeScript declaration files occasionally still have this issue, it does not affect Node.js users directly, it is much rarer, and users can apply a post-processing step to "downlevel" the A similar, but not entirely related issue, is that there is not a consistent strategy for how to handle any arbitrary TypeScript files in the absence of a Finally, there is the issue of more code to analyze, along with the need to check the implementation of source code. We've seen a few people look into the size delta between source files and declaration files (here and here). Furthermore, as mentioned above, source files typically would need to have their implementations type-checked. So shipping TypeScript source files would probably require one of two strategies for the TypeScript type-checker: either increase the size of all code analyzed by TypeScript all at once, or perform an up-front analysis of all dependencies ahead of time and cache the results as ConclusionWhile it is possible that some of these disadvantages could be mitigated, we believe that the disadvantages are significant enough that we would discourage this feature. We are open to hearing more feedback on this topic and revisiting, but we believe that the current strategy of shipping JavaScript and declaration files is the best strategy for the ecosystem as a whole. |
I think it's fair to say that nobody expects any type checking in the If this feature proposal is ever implemented, I’d expect only one functionality from it: I’m not sure if it’s too much to ask for TypeScript to read the After all, your target users are nodejs backend developers, who would never need any special browser bundling in the first place. If a library is expected to run in the browser, then it should absolutely be shipping |
I don't think that's entirely fair to say (many projects do not enable skipLibCheck), and even without checking enabled, performance is negatively hit as all of the internals will still be parsed, bound, and potentially still incur type checking for inference or other checks the compiler still does even if no errors are shown.
I believe it is unrealistic to attempt to read any tsconfigs but your own; tsconfigs can extend configs from devDeps (e.g. the |
Has anyone considered usage of fields like I'm not sure this would completely mitigate many of the concerns with TS features compatibility, but maybe it could be one piece of a starting point for published TypeScript source files. |
I was just thinking this 🙂 |
We had consensus in this meeting #19, that for now there is no good reason to implement support in node_modules, since most of the monorepo that have been tested should be working fine. |
Just my small 2¢:
There is already a similar problem with Node version mismatch that package installers must keep track of. Most of the popular npm packages support an old enough Node version that it's not a problem, but taking advantage of any new features will still break packages. (Personally I run into this frequently as I'm usually eager to start using experimental Node features.) |
Copied from original discussion in nodejs/loaders#217 (comment)
I know that as a user I won't have much sway here, but I think I'm not alone in thinking that files in
node_modules/*/*.ts
should also be allowed--experimental-strip-types
type stripping.A few thoughts:
1) Node.js Alone Won't Prevent TS npm Publishing
There is a lot of movement in the "execute TypeScript, don't build it" ecosystem already, for example with the advent of many ecosystem projects such as:
ts-node
,tsm
,tsx
Publishing
.ts
files to npm and other registries is already a growing pattern, which drastically reduces the effort and complexity of publishing a TypeScript package.I think as these projects evolve and more people get to know about this possibility, there will be a greatly increased interest in this possibility.
It's my opinion that this banning of
node_modules/*/*.ts
in Node.js alone won't be able to hold back the energy in the ecosystem, especially with working alternatives. (not to mention users circumventing this by using any of the other projects, which do not have this limitation)2) User Experience
My first experience with
node --experimental-strip-types
was creating an internal checking tool which was its own package, without a build step.I immediately fell flat on my face with this, because of the banning of
node_modules/*/*.ts
files.Even though I was already somewhat aware of the discussions and objections behind this (eg. the
nodejs/TSC
meeting notes from 2024-07-24), for my use case it felt like an arbitrary limitation imposed on my project.I imagine that as type stripping becomes more widespread, this will be a common complaint from users.
3) Node.js Features Available Everywhere
@GeoffreyBooth wrote about supporting a Node.js feature everywhere:
This resonates with me - it seems like supporting a Node.js feature in as many places as possible will be the best for users and cause the least amount of support complaints.
Banning
node_modules/*/*.ts
to try to avoid a pattern which the ecosystem may adopt seems like a weak reason. (not to mention that the ecosystem may end up adopting this pattern anyway by finding cowpaths around this)4) Identifying and Addressing Downsides
Downsides as mentioned by Ryan and Daniel on the TypeScript team and vocal
node_modules/*/*.ts
opponents such as Matteo are important and should be considered.But it feels like also:
This being done with a dispassionate, neutral stance, not trying to prove any one viewpoint.
In reading through the publicly-available documents, I don't think this has been done yet.
5) At Least Allow Users to Choose
Even if careful enumeration of problems and solutions leads to the final conclusion that the tradeoff is not worth it for Node.js, I think it would be good to allow users to choose for themselves and disable this
node_modules/*/*.ts
banning with a flag, eg:6) Similarities to
.ts
Rewriting LimitationOh one more thing, more related of a feeling than fact-based:
This
node_modules/*/*.ts
banning feels like it has a similar vibe to the.ts
->.js
rewriting decision in TypeScript, which was overturned after years of doubling-down on.js
imports (ironically heavily inspired by Node.js type stripping).The text was updated successfully, but these errors were encountered: