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

Support .tsx file extensions. #56322

Open
cpojer opened this issue Dec 19, 2024 · 17 comments
Open

Support .tsx file extensions. #56322

cpojer opened this issue Dec 19, 2024 · 17 comments
Labels
feature request Issues that request new features to be added to Node.js.

Comments

@cpojer
Copy link

cpojer commented Dec 19, 2024

What is the problem this feature will solve?

Node's --experimental-strip-types and --experimental-transform-types are great improvements that allow us to drop a lot of tooling to run TypeScript in node. Right now, it only supports the .ts extension and does not work on .tsx. .tsx only really exists because of syntax ambiguity with a (somewhat legacy) way of typecasting in .ts files: microsoft/TypeScript#26489 (comment)

Why would you use .tsx for backend code?

In a monorepo, you might have many packages shared by the client and backend. For consistency, those projects may want to use only a single file extension like .tsx. If you use React, which many people do, and some files use .ts and some .tsx, it's always jarring to type JSX in a .ts file, realize it's a syntax error, and then having to rename the file. The renames also make it harder to navigate git history. Finally, if you are using only a single extension, TypeScript's behavior is always the same with regards to how angle brackets work.

I'd be excited to implement this feature and send a Pull Request if the Node.js team is in favor of supporting .tsx extensions.

What is the feature you are proposing to solve the problem?

I imagine the most workable solution is to support .tsx extensions just like .ts, but throw an error if JSX is actually used. I'm not advocating for supporting JSX, just for node to support .tsx files without compiling JSX.

What alternatives have you considered?

The alternatives are to keep using third-party tooling to strip TypeScript types, or to rename all backend files using .tsx to .ts, which may not be possible in large monorepos given the amount of files affected, and as mentioned previously, makes git history more cumbersome to work through.

@cpojer cpojer added the feature request Issues that request new features to be added to Node.js. label Dec 19, 2024
@github-project-automation github-project-automation bot moved this to Awaiting Triage in Node.js feature requests Dec 19, 2024
@aduh95
Copy link
Contributor

aduh95 commented Dec 20, 2024

Would you like to send a PR?

@cpojer
Copy link
Author

cpojer commented Dec 20, 2024

Before working on it, I would like to discuss and reach consensus that the Node.js maintainers would like to include this feature.

@aduh95
Copy link
Contributor

aduh95 commented Dec 20, 2024

I'm not sure what there is to discuss, but in any case, it won't happen until someone submits a PR.

//cc @nodejs/typescript

@cpojer
Copy link
Author

cpojer commented Dec 20, 2024

I see, so from my perspective here is what I think we need consensus on:

  • Does Node.js want to support .tsx?
  • If yes, is it acceptable (at least as a first step), to support the .tsx extension only, without actually supporting JSX? See https://www.typescriptlang.org/tsconfig/#jsx for the complexity involved with supporting JSX.

imho this would solve the outlined problem for most users, but some might have a desire to support JSX directly in the future in some form.

@JakobJingleheimer
Copy link
Member

Many of the arguments cited in favour seem illogical to me. It seems like you're suggesting supporting a mismatched file extension and then erroring when the file extension is used correctly?

Supporting actual TSX would be quite a hairy ordeal, and encouraging people to misuse the .tsx extension seems like a bad idea.

Or have I misunderstood you?

@cpojer
Copy link
Author

cpojer commented Dec 20, 2024

Yes, you misunderstood. Using the .tsx extension without using JSX is not a misuse of TypeScript. Why would it be?

@JakobJingleheimer
Copy link
Member

JakobJingleheimer commented Dec 20, 2024

It seems I did not. That is a misuse of the file extension, and it would be a landmine for users. We should absolutely not do that.

However, if we were to support jsx and thus tsx, that would be a different story. One would need to figure out how to handle configuration, because jsx has multiple transpile options. I could see value in that, but I would advise first sketching out some broad-strokes before jumping to a PR (which would almost certainly result in contradicting opinions). Far better to get those to consensus before churning on an implementation. Happy to answer questions for that 🙂 I don't know the appetite of others (I'm not sure of my own opinion on it) to support jsx though.

@ljharb
Copy link
Member

ljharb commented Dec 20, 2024

How is it not a misuse of a file extension to do that? That's what .jsx exists for, for when you have jsx and only when you have jsx, and I'd expect ts/tsx to be the same thing. If there's no jsx in it, it's just JS or TS, and the file extension should reflect that accurately.

@cpojer
Copy link
Author

cpojer commented Dec 20, 2024

There are many projects with files that use the .tsx extension without using JSX. Tools like ts-node support it and TypeScript does not throw an error if it cannot find a JSX AST node in a .tsx file. It seems to me like .tsx is well-supported by TypeScript unlike using a random extension like .definitelynottypescript. Maybe I'm missing something, but do you have a source where the TypeScript team states it is a misuse of the extension if not JSX nodes are present?

On the topic of partial support, Node.js implemented --experimental-strip-types without support for TypeScript features like enums until --experimental-transform-types was added. Why can we not take a similar path for this?

@GeoffreyBooth
Copy link
Member

GeoffreyBooth commented Dec 20, 2024

It seems to me that supporting files with a .tsx extension but erroring on JSX syntax within would seem very broken to users. Sure it’s possible to write a .tsx file with no JSX syntax, just as it’s possible to write a .ts file with no TypeScript syntax, but I don’t think that’s what most users would consider “.tsx support.”

On the topic of partial support, Node.js implemented –experimental-strip-types without support for TypeScript features like enums until –experimental-transform-types was added. Why can we not take a similar path for this?

This proposal is more like saying “why not support the .ts extension but only if such files contain only JavaScript syntax.”

@marco-ippolito
Copy link
Member

marco-ippolito commented Dec 20, 2024

I explored this idea but I'm against it.
The main idea behind TypeScript support in Node is the type stripping. tsx cannot be run once types are stripped or syntax is transformed, it always requires an external loader.
Maybe, (maaaaaaybe) adding support in module.stripTypeScriptTypes would be "acceptable".

@cpojer
Copy link
Author

cpojer commented Dec 20, 2024

@marco-ippolito:

tsx cannot be run once types are stripped or syntax is transformed, it always requires an external loader.

Would you mind elaborating on this sentence?

@marco-ippolito
Copy link
Member

marco-ippolito commented Dec 20, 2024

@marco-ippolito:

tsx cannot be run once types are stripped or syntax is transformed, it always requires an external loader.

Would you mind elaborating on this sentence?

If types are removed, all its left is jsx that cannot be run without an external loader or a framework (that uses a loader)

@arthurfiorette
Copy link

The logical approach, considering the previously discussed --experimental-strip-types and --experimental-transform-types flags, is to introduce a new one: --experimental-jsx. This flag should include support for <jsx /> syntax and only it. Alongside it, just add .tsx as a valid ts extension and only strip types out of it,

While I agree with adding support for .tsx files without JSX, this "feature" should only be merged once Node.js can reliably execute JSX code.

Introducing a new flag might seem exhaustive, but it aligns with the established decision-making process. Moreover, the JSX implementation should remain independent of TypeScript-specific features, much like how .jsx files can be used alongside a jsconfig.json file.

This involves two distinct steps:

  1. Process .tsx files just as .ts files to strip their types.
  2. Properly handle .js and .jsx files that include <jsx /> syntax.

Providing only one of these features without the other is both counterintuitive and likely to confuse users.

@arthurfiorette
Copy link

arthurfiorette commented Dec 20, 2024

A potential first step toward this approach could be to simply ignore <jsx /> syntax entirely while adding support for the .tsx extension.

If this change is released with a clear note explaining that it currently ignores <jsx /> syntax, it could also recommend Node.js users rely on a custom loader like @educandu/node-jsx-loader for handling JSX in the interim.

This would provide a practical and usable solution much earlier, giving developers a path forward without having to wait for the complete implementation of a --experimental-jsx flag. That flag, once introduced, could be entirely independent of the Node+TypeScript-specific features. It would focus solely on transforming JSX syntax, regardless of whether TypeScript is in use.

@marco-ippolito
Copy link
Member

I'd first try to get consensus for jsx support, if that happens adding type stripping to tsx is easy.

@arthurfiorette
Copy link

The opposite would allow jsx usage via custom loaders, waiting for jsx support means no jsx at all until that + it would bring more people to use --experimental-strip-types and --experimental-transform-types which I think is better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js.
Projects
Status: Awaiting Triage
Development

No branches or pull requests

7 participants