-
Notifications
You must be signed in to change notification settings - Fork 17
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
Roadmap for experimental TypeScript support #217
Comments
PR-URL: #53725 Refs: nodejs/loaders#217 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruy Adorno <ruy@vlt.sh>
I think this looks great; can we just replace the contents of the |
Is there a definitive list of features that are not supported here? I'm looking to adapt my eslint config to match. |
it's documented here https://github.com/nodejs/node/blob/main/doc/api/typescript.md but you should expect it to change in the future |
There's a Getting Started article on the Node.js website — Node.js with TypeScript (source) — that might benefit from an update including information about this feature (once the time is right). I suppose a linked issue should be created in that repository, but wasn't sure whether it should be included somewhere in the list here, too. |
I understand the argument against encouraging package maintainers from releasing TS only packages. However, one additional thing to consider here is how node operates with internal packages in a monorepo. I'm not familiar with how other package managers work in this regard today, but |
I would think that this detail wouldn't matter because the |
This might just work out of the box then. I haven't tested with the new experimental flag yet, but it would be awesome if it just worked without any other considerations. 👍
In my use case, I wasn't thinking of publishing because the repo in question isn't published but is our internal backend runtime. With respect to things like export maps, converting them at build-time is actually how we make these internal packages work today. The I'm unsure if this is a common use case in the rest of the world, but I'm optimistic based on the |
Is the idea to eventually support other typing systems (for example, Flow, Hegel, or whatever comes next after TypeScript) like https://github.com/tc39/proposal-type-annotations proposes, or is this feature focused solely on TypeScript? If it's only going to be for TypeScript, wouldn't it be better for the |
PR-URL: #53725 Refs: nodejs/loaders#217 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruy Adorno <ruy@vlt.sh>
PR-URL: #53725 Refs: nodejs/loaders#217 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruy Adorno <ruy@vlt.sh>
My understanding is that the inclusion of TypeScript support in Nodejs is to simplify the development cycle - where distributed code should still be transpiled to JavaScript before consumption (npm, production, etc). Nodejs-valid TypeScript requires the The official TypeScript compiler does not support transforming imports due to the difficulty of handling dynamic imports. SWC has a plugin that can rewrite import extensions, but it skips dynamic imports and is annoying to set up. Ideally, this additional tooling would be avoided as it diminishes the benefit of using built-in TS support over a loader. Can we get guidance on how to properly transpile Nodejs-valid TypeScript to valid JavaScript for distribution? |
Some discussion going on here #214. |
The extension requirement comes from ESM support in Node which has always required a extension. I think it's a good requirement because it eliminates ambiguity when multiple files exist with the same name and it makes the module resolution faster. Imho people should find some codemod tool to adds the extension to their imports. |
I'm working on creating one. I'll post once it's ready. I plan for it to correct bad file extensions (ex |
I 100% agree with this take. I think it was a good call to use explicit file paths as it avoids confusion and simplifies resolution. |
Codemod is WIP: https://github.com/JakobJingleheimer/correct-ts-specifiers currently struggling with jscodeshift, which seems to be the biggest yet is almost completely undocumented (as is codemod itself 😢). |
@JakobJingleheimer It's being worked on 😄 We (jscodeshift maintainers) launched a new docs site launched recently, but is still a work-in-progress: https://jscodeshift.com/build/api-reference/ Not sure if it's mentioned in the docs, but https://astexplorer.net/ is also a very good resource for inspecting the AST and writing codemods. https://codemod.com/ have Codemod Studio too, but I haven't tried it yet. |
@JakobJingleheimer, founder of Codemod here (also maintaining jscodeshift, thanks @Daniel15 & @karlhorky for the mention) |
Definitely and I didn't want to suggest that it should. I think the direction taken with strip-types is great, congrats on the work so far 🙌🏻 I'm really just talking about the roadmap for this feature. Currently the roadmap has the issue listed as "wontfix". I'd love for that to change. I'm also willing to help make strip-types work with js imports. My intuition is that this should be possible at no additional cost to currently supported use cases. |
Is there a specific and compelling tsconfig option that only Since everyone seems to agree TS's behaviour is wrong, I'm still inclined to say regardless that that would be TypeScript's problem, and you're asking us instead of them to change something because we actually consider feedback 🙃 (which is a little funny as I've so far basically been saying "no" 😅) Buuuut as Marco pointed out, this may be moot if
Very appreciate that you're willing to contribute—contributions generally super welcome! However, there is significant opposition to this particular item within node, not to mention it would violate spec; barring a very unexpected persuasive argument (I'm not so arrogant to say I'm right no matter what 😉), I would block this. It is already possible and very easy to do this within node with tools that already exist: a resolve hook. I even wrote such a hook that will do what you want. Should this be moved to a separate issue/discussion? I think this is getting a bit too specific for this general roadmap issue. |
I love absolutely everything that's going on here, so thank you to everyone who has been involved in it. I'm particularly impressed to see the communication and coordination going on between the node and TypeScript teams. Here's a question from the peanut gallery: |
As I understand it, everything that's on main branch until the v22 LTS is forked on 2024-10-29 will be included in a upcoming v22 release. |
Agree, answered here: #214 (comment) |
@allisonkarlitskaya yes, |
@marco-ippolito can't find proper info on the following, please let me know if I'm repeating a known issue:
I guess authors will have to compile/transpile the code because recursively stripping the imported files could result in breakage due to enums/namespace/decorators. Correct? |
please refer to the documentation https://nodejs.org/docs/latest/api/typescript.html#type-stripping
If needed there is the flag |
Just gonna drop this here, for anyone looking to run |
Will there be some discussion / meeting agenda items to come back around to TS type stripping support in The last agenda item I could find about this was these meeting notes from 2024-07-24: As a user, it would be great to also have this ability that other runtimes like Bun have, especially for monorepos. Personally, I'm looking to enable executable scripts in
#!/usr/bin/env -S node --experimental-strip-types
const a: number = 1;
console.log(a); Edit: For anyone looking for an updated discussion, a dedicated issue nodejs/typescript#14 |
There have been serious concerns raised by the TypeScript team about doing so. I 100% agree with them, and I don't expect it to ship without a contested TSC vote. |
@karlhorky There is consensus from both Node and from TypeScript that running ts in |
Could you please link to that? |
Does the lack of |
The TypeScript team is concerned about the ecosystem consequences of users publishing TypeScript source files to the npm registry, and one way to discourage such an outcome has been to prevent type stripping support for files under |
Edit: Copied to dedicated issue nodejs/typescript#14 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 A few thoughts: 1) Node.js Alone Won't Prevent TS npm PublishingThere 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:
Publishing 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 2) User ExperienceMy first experience with I immediately fell flat on my face with this, because of the banning of Even though I was already somewhat aware of the discussions and objections behind this, 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 4) Identifying and Addressing DownsidesDownsides as mentioned by Ryan and Daniel on the TypeScript team and vocal 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 ChooseEven 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
|
Edit: Copied to dedicated issue nodejs/typescript#14 6) Similarities to
|
Hello @karlhorky - thanks for the thoughtful input. @marco-ippolito mentioned in the most recent Node TS meeting that we haven't received much feedback on Whilst this restriction is trivial to lift in terms of code changes in Node, the implications and opinions on doing so are significant. I'd suggest re-posting it as a dedicated issue on the https://github.com/nodejs/typescript repo to avoid thread-explosion here. |
@robpalme thanks for the feedback! Copied to a dedicated issue here and edited my posts above: |
Sorry for bumping an old ticket, but in light of monorepo support currently only available through third party loaders (like |
Is there somewhere where feedback is being solicited? I've played around with it a bit and found it to be a great replacement for |
@allisonkarlitskaya feedback is being received through issues/discussion is the nodejs/typescript repo |
I am unsure if this comment is fitting here, but I see mentions of swc in the original post. Would it not be better to use https://oxc.rs/ and its parser as it is 3x faster than swc? |
Intro
Since the previous discussion was successful in gathering feedback from the community, and I believe there is some consensus that this feature is something that the project wants to add, I want to summarize what are going to be the next steps and some technical solutions.
To be honest I'm very glad for the amount of feedback I received, it helped me to change my view on some aspects that I previously ignored.
Before I go into technical implementation, this is what the goals of this feature should be in my opinion:
Caution
These are long term goals and next steps, they might not reflect the current status.
Step 1: Initial implementation
The initial implementation is the proof of concept that I have created to gather feedback and consensus from the project collaborators.
It's very far from being perfect but it establishes some of the points we want to move forward with.
Current limitations:
.js
extension for.ts
files.node_modules
.Important
Why no support for TypeScript features such as enums, namespaces, decorators, etc...?????
Step 2: Decoupling
There is already a precedent for something that Node.js support, that can be upgraded seperately, its NPM.
Node bundles a version of npm that can upgraded separately, we could do the same with our TypeScript transpiler.
We could create a package that we bundle but that can also be downloaded from NPM, keep a stable version in core, but if TypeScript releases new features that we don't support or breaking changes, or users want to use the new shiny experimental feature, they can upgrade it separately.
This ensures that users are not locked, but also provides support for a TypeScript version for the whole 3 years of the lifetime of Node.js release.
Getting started
Create a new package called
amaro
that wrapsswc
with the current implementation. This package, which is released on npm, offers the same api that is currently used by Node, and it can be upgraded separately. The first challenge would be setup the project, make sure it can be upgraded by runningnpm install amaro@vX.Y.Z
Increase features
Support for transformation behind a flag
Enable support for TypeScript features that require transformation (Enums, mamespaces), now that we are decoupled we can expand on the amount of feature we support.
Caution
Currently there is consensus that Node.js should NOT run TypeScript files inside `node_modules.
It is not supported to avoid package maintainers to release TS only package.
Thanks @joyeecheung and @legendecas for the idea 💡
Step 3: Make it fast
With the project up and running, we can now start thinking about performance.
We could vendor SWC in Rust, build our own wasm, or compile it to static libraries that we could use in core, c++ rust FFI, etc...
I'm not a performance expert, but I think it is possible to optimize the interaction between Node and SWC and make it performant, without impacting the Node build process.
This is the phase where we measure the performance and make it usable in production without performance penalties.
Step 4: Add more features
Wont Fix
.js
extension for.ts
files.The reason is that the compiler/bundler should be responsible to resolve the correct extension at compile time.
At runtime, the extension must be correct, it doesn't make sense to add overhead in production when it can be solved during development. Discussion happening here: Import specifiers in
--experimental-strip-types
#214.This is also supported by TypeScript from 5.7 Rewrite relative import extensions with flag microsoft/TypeScript#59767
tsconfig
directlyThis would mean to run with typescript to support the latest flavors etc... Compilation and type checking should be done by user land tools during development.
The text was updated successfully, but these errors were encountered: