Skip to content
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

Native Node.js Integration/Support #56838

Open
6 tasks done
shinebayar-g opened this issue Dec 21, 2023 · 6 comments
Open
6 tasks done

Native Node.js Integration/Support #56838

shinebayar-g opened this issue Dec 21, 2023 · 6 comments
Assignees
Labels
Discussion Issues which may not have code impact

Comments

@shinebayar-g
Copy link

🔍 Search Terms

native nodejs integration
nodejs support
nodejs integration
run nodejs

✅ Viability Checklist

⭐ Suggestion

I would like Node.js and Typescript to support the following user experience.

$ node script.ts
"Hello World"

This setup requires a seamless integration between Node.js and the TypeScript language. The @nodejs community has a longstanding issue documented here regarding this specific use case. While the majority of the work is anticipated to take place within the Node.js runtime, establishing an effective communication channel between the Node.js and TypeScript communities is crucial for tracking and progressing this feature request. It appears that the Node.js community could benefit from collaboration and support from the TypeScript community, as mentioned in this comment.

📃 Motivating Example

The TypeScript ecosystem is closely integrated with Node.js. It would be fantastic if Node.js could effortlessly consume TypeScript code without the need for additional third-party tools. Both Deno and Bun runtimes have independently implemented this feature. However, Node.js currently lags behind in providing native support for this capability.

💻 Use Cases

  1. What do you want to use this for?
  • Run TypeScript code directly without an additional bundler/compiler step.
  • Enable developers to distribute TypeScript-only npm packages, eliminating the need to manage both .d.ts and .js files in non-browser environments.
  1. What shortcomings exist with current approaches?
    Additional tooling is required, and there are no defined heuristics.

  2. What workarounds are you using in the meantime?
    Currently, tools such as ts-node or tsx are employed to execute TypeScript code directly in the Node.js ecosystem. Alternatively, developers may opt for alternative runtimes like Deno and Bun.

@RyanCavanaugh RyanCavanaugh added the Discussion Issues which may not have code impact label Dec 21, 2023
@RyanCavanaugh
Copy link
Member

You might want to open an issue with the TypeScript team, if there isn’t one there already. They’re the ones who have the power to add official support for runtime transpilation

I'm not sure what else @GeoffreyBooth is referring to here that doesn't already exist. ts.transpileModule is the exposed endpoint for this.

@GeoffreyBooth
Copy link

I’m not sure what else @GeoffreyBooth is referring to here that doesn’t already exist. ts.transpileModule is the exposed endpoint for this.

That’s an exposed endpoint for other tools to consume. To actually run a TypeScript file, such as the example’s node script.ts, a wrapper tool such as ts-node or tsx needs to be used. I think the user request is to make such wrapper tools unnecessary.

Or to put it another way, look at the functionality added by ts-node or tsx and add most of it into the core typescript package or an official sibling package. In particular, TypeScript could ship official Node module customization hooks to enable runtime transpilation. If there was something official, Node could automate its installation and usage when TypeScript files are encountered, rather than “picking a winner” among the various third-party tools out there.

Another thing that would be very helpful coming from the TypeScript team is a strong recommendation for tsconfig.json settings for Node projects, especially modern ones that run as ESM with ESM-only dependencies. It’s an excruciating pain point for users trying to figure out how to get tsc to generate ESM JavaScript that can be run by Node (as opposed to consumed by a bundler, or transpiled into CommonJS) so that ESM dependencies work. I think it would help if the TypeScript documentation had clear recommendations or examples, or if tsconfig.json had straightforward “use this” simplified settings, along the lines of "moduleResolution": "bundler" but targeting the “run as ESM” case.

@RyanCavanaugh
Copy link
Member

to generate ESM JavaScript that can be run by Node (as opposed to consumed by a bundler, or transpiled into CommonJS) so that ESM dependencies work ... if tsconfig.json had straightforward “use this” simplified settings, along the lines of "moduleResolution": "bundler" but targeting the “run as ESM” case.

What you're describing is verbatimModuleSyntax paired with "module": "nodenext". We're recommending verbatimModuleSyntax (which greatly simplifies possible consequences of on-the-fly transpilation) in nearly every configuration. "module": "nodenext" picks the target runtime environment. I'm not sure if we can pare it down any further than that, but I'm open to ideas + more discussion.

If there was something official ...

As for writing the official hooks ourselves, that's a scoping decision for us, not a technical blocker (as evidenced by other runtimes which are supporting TS out of the box - it's clearly possible without TS shipping components it doesn't already). Daniel and I will discuss more when we're both back from the holidays, but it's obviously not an easy thing to just commit to.

Another thing that would be very helpful coming from the TypeScript team is a strong recommendation for tsconfig.json settings for Node projects

We have some new docs on this (link to a section of a much larger guide to modules in general) https://www.typescriptlang.org/docs/handbook/modules/guides/choosing-compiler-options.html#im-compiling-and-running-the-outputs-in-nodejs . I'd like to figure out more ways to get this set of docs in particular in front of people's faces -- they're very comprehensive and answer virtually every question people have come to us with, but the area is famously hard to understand and I'm not sure how to get more people to see this content.

@GeoffreyBooth
Copy link

In April 2023 Node did some user research, available at https://github.com/nodejs/next-10/blob/main/surveys/2023-04/Node.js%20Survey%20open%20ended%20answers.pdf. The last question was “Do you have any recurring issues when using Node.js?” and was free response. Of the 325 responses we received, 27% referred to ESM or modules (details). Half of those, or 13% of all responses, mentioned types or TypeScript.

  • A lot of time spent configuring Typescript with Node.js for full custom projects
  • Basic typescript types, cold start times
  • Debugging, better typescript support.
  • Direct typescript execution
  • error handling is terrible & no built in typescript support
  • errors wont appear untill runtime (in JS) other than in TS
  • Honestly, eslint and typescript should be basic features at this point. I can’t imagine building things without them.
  • I would like to have native support of typescript in Node.js
  • If node could strip type annotations and run TS directly that would be slay
  • Im a purist, I want JS, some people around me push for TS… they can all move to zimbabwe and have a nice life away from me
  • issues with typescript support issues with ESM modules still hard to work with unexpected exceptions in runtime still hard to detect which user blocked the execution and close it (fail fast)
  • It’s hard to use it with Typescript
  • Lack of out-of-the-box support for TypeScript
  • Lack of types
  • Lack of TypeScript and enterprise language features
  • Memory leaks are hard to track down in production - First-class typescript support would be huge
  • Native Typescript support should be enabled out of the box. - Nodejs should improve the way external packages are imported and the scope those have in the ecosystem. Even if you import one package you end up with 50 and it’s hard to keep track of how legit those in-depth packages are.
  • Needs typescript support out of the box
  • No native TypeScript support
  • No other than ESM (import syntax) configuration and using typescript. E.g I’d like to be able to just run a .ts file like node index.ts ts-node is supposed to help this but maybe I’m just dumb because I often run into issues with that and module syntax. (Even when using —esm flag)
  • People often use global node packages in npm scripts, which means you have to install them before installing project dependencies. I have seen people use typescript’s ‘tsc’ as a global module, when it should really be used as a dev dependency.
  • Please help push to integrate the Types as Comments, so we can finally be rid of Typescript and the horrible build step and non-standard feature implementations.
  • Problem with incorrect module versions, and not being able to run Typescript directly.
  • Regular npm install / update / ci confusion by junior developers. Typescript boilerplate compiling/ts-node’ing/etc because of lack of support in node
  • security, design patterns/structure of the project node_modules wtf?(a lot dependencies) education for high-quality code TYPES
  • Startup time, no built-in TypeScript support, mediocre docs
  • The thing that missing is full integration with typescript. Or a guidance of how no JS runs with typescript. Maybe this is more applicable for typescript side
  • TS support
  • types
  • Types
  • Types
  • Types should have first class support.
  • Types, I need at least basic typing support because it’s hard to maintain large applications.
  • Typescript + ESM situation is a hell
  • Typescript and performances
  • Typescript compilation
  • typescript getting in the way.
  • Typescript should be embedded or at least be enabled as first class citizen.
  • TypeScript support still seems patchy. Error messages can be archaic. ●U
  • updating Node.js version while keeping all global deps (via NVM) slow startup time for CLI commands (esp. if they are written in TS and need –loader ts-node/esm/transpile-only
  • wishing to have typescript “out of the box”
  • Would really appreciate native typescript support and easier project setup
  • Yep, especially when figuring out how to work with dozens of module import/export approaches. Mixing them together when migrating to TypeScript or just to a new module system. I wish there were an ultimate consolidated solution to all these problems.

So we know that this is a major challenge for a large portion of Node users. It’s so difficult that Deno and Bun advertise “out-of-the-box TypeScript” as a major selling point. We get very strongly worded feedback like this:

the intersection of typescript, nodejs, and ES modules is consistently the most frustrating experience I ever have. Trying to figure out which magic incantation of tsconfig/esbuild/tsc/node options will let me just write code and run it is a fools errand. You might figure something out, and then you try to use Jest and then you descend into madness again.

So clearly there is a lot of room for improvement around the UX of this. Education is a part of it, and a reasonable place to start, but I think this is far too difficult for far too many people to just write better docs and consider that good enough.

A particularly difficult use case that comes up often is one where an existing app that is compiled into CommonJS needs to switch to compile into ESM because the developer wants to add an ESM-only dependency. This seems to often set off a game of whack-a-mole, where changing one setting makes Node work but the bundler fail, or the bundler work but the test runner fail, and so on. There are just too many tsconfig options and too many permutations, and too many tools, to know how to get it right.

@GeoffreyBooth
Copy link

We’re recommending verbatimModuleSyntax (which greatly simplifies possible consequences of on-the-fly transpilation) in nearly every configuration.

If verbatimModuleSyntax is nearly always recommended, what would be lost by making it the only option? As in, don’t just make it enabled by default, but get rid of the ability to disable it. (Maybe after a few releases where it’s enabled by default but disabling it triggers a deprecation warning.)

When I read https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax, there’s a lot of text written about how this simplifies TypeScript knowing when to skip emitting imports for types, but then in the last paragraph it mentions almost as an aside:

That does have some implications when it comes to module interop though. Under this flag, ECMAScript imports and exports won’t be rewritten to require calls when your settings or file extension implied a different module system.

This “what you write is what you get” feels like it would solve a lot of problems? A big frustration that people have is trying to figure out how to get TypeScript to output real ESM syntax. If TypeScript’s default behavior was to output code as written and never convert module formats (import to require or vice versa) unless specifically requested, that would probably alleviate many of these issues. I would even go further and suggest that tsc get out of the business of converting module formats entirely; if the user wants their ESM syntax converted into CommonJS, there are many wonderful build tools they can use to achieve that, and it’s not part of the core mission of tsc.

@vorant94
Copy link

vorant94 commented Apr 17, 2024

I'm surprised I can't use tsc as a node loader and actually need to go for third-party solutions like ts-node or tsx. those third-party tools always have only 80-90% features support, which allows them to be called production ready, but they always catch devs with small things. like good luck with the following

  • setting up ESM support for both development runtime and build process
  • spinning up monorepo with tsconfig.references support
  • the huge point for node built-in test runner is that you have one less dependency to support, but since tests are just as code written with TS, you need to either compile tests alongside with code or use third-party loader mentioned above (e.g. just changing one dep for another)

I ended up with tsc --watch mode and just node --watch. it is two processes running, but at least I get at devtime the same code that I get in buildtime. it would be really helpful to see node --loader tsc index.ts as a first-party support from typescript team

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion Issues which may not have code impact
Projects
None yet
Development

No branches or pull requests

5 participants