caoccao / swc4j

swc4j (SWC for Java) is an ultra-fast JavaScript and TypeScript compilation and bundling tool on JVM.
Apache License 2.0
39 stars 1 forks source link

TSX to JSX, Vue support #6

Closed WarningImHack3r closed 1 week ago

WarningImHack3r commented 1 month ago

Hello there, I've been looking for a TS to JS transpiler and found this one that looks fast, well-made, and feature-full.

I want to transpile files from TSX to JSX, as well as from TypeScript Vue files into JavaScript Vue files. Vue seems too specific for this project, I might try to hack around with it with SWC4J anyway, but my main concern is for JSX.

Would you be interested in an option for the transpiler to choose the target language? I'd love to de-type my files without modifying them all the way down to JS.

On a side note, is there a way to get the file extension from a Swc4jMediaType? Can setSpecifier automatically compute the file name if not provided?

caoccao commented 1 month ago

Hi @WarningImHack3r ,

I think it's possible to write a plugin for Vue 3. I don't think hacking swc4j will help because the transpile() comes directly from swc. The recommended approach is to write swc4j plugins in Java. There are tutorials about how to write plugins.

Regarding the target language, if you call transpile(), you will always get JS code. But, if you call transform(), you will be able to decide which target language you want in your plugins. Swc4j doesn't set restrictions at all. It's up to the applications to make the decision. Of course, it would be great if you could create a generic plugin that transforms TSX to JSX. I would suggest you submit pull requests so that the community could benefit from the work. Or, if you want me to do so, please ping me at discord.

Regarding the file type detection, I think it's quite easy and highly customizable so that the freedom should be given to the applications.

Hope these make sense. Please let me know if you have any questions.

WarningImHack3r commented 1 month ago

First off, thanks for your quick and comprehensive response!

I think it's possible to write a plugin for Vue 3. [...] There are tutorials about how to write plugins.

Oh yes indeed, I didn't see that in the documentation. I went straight to Transpile without looking at the other options. I'll take a look now.

Regarding the target language, if you call transpile(), you will always get JS code. But, if you call transform(), you will be able to decide which target language you want in your plugins. Swc4j doesn't set restrictions at all. It's up to the applications to make the decision.

Can you point me to an example of this? The transform() docs only mention ECMAScript targets, not language targets

Of course, it would be great if you could create a generic plugin that transforms TSX to JSX. I would suggest you submit pull requests so that the community could benefit from the work.

Yes of course. For both Vue and JSX, if I come to make a plugin for it, it will be open source and available on GitHub.

Or, if you want me to do so, please ping me at discord.

I can't bother you with that unless you know it will take you 5 minutes :D

Regarding the file type detection, I think it's quite easy and highly customizable so that the freedom should be given to the applications.

Yeah that's what I currently did, just wondering if it could be built-in as the table describing the bindings is in the docs

Hope these make sense. Please let me know if you have any questions.

Thanks for that!

caoccao commented 1 month ago

Can you point me to an example of this? The transform() docs only mention ECMAScript targets, not language targets

There are tutorials for transform() as well. Regarding plugins, they apply to parse(), transform(), transpile() the same way so that any tutorials are worth reading. transform() just directly converts the transformed AST (by plugins) to code. If the AST has TypeScript annotation, the code is TypeScript. If the AST has JSX Elements, the code is JSX. It's plugins' decisions at all. The ES target is just a hint for swc on how to convert the AST to code for backward compatibility.

Yes of course. For both Vue and JSX, if I come to make a plugin for it, it will be open source and available on GitHub.

Thank you in advance. I look forward to the pull requests.

I can't bother you with that unless you know it will take you 5 minutes :D

I think that (code + test + doc) would take at least a week to reach production quality.

Yeah that's what I currently did, just wondering if it could be built-in as the table describing the bindings is in the docs

If it's generic enough, why not also contribute it to the community?

WarningImHack3r commented 1 month ago

There are tutorials for transform() as well. Regarding plugins, they apply to parse(), transform(), transpile() the same way so that any tutorials are worth reading. transform() just directly converts the transformed AST (by plugins) to code. If the AST has TypeScript annotation, the code is TypeScript. If the AST has JSX Elements, the code is JSX. It's plugins' decisions at all. The ES target is just a hint for swc on how to convert the AST to code for backward compatibility.

So that means that if I change the AST's language through PluginHost.process() it will change the target language? If so, how can I change the AST language?

I think that (code + test + doc) would take at least a week to reach production quality.

Fair enough, I can't ask you to do it then :D

If it's generic enough, why not also contribute it to the community?

It's in Kotlin (not Java) and I don't know if you want it in your codebase, that's why I quickly did it myself. If you want it I can make these toString()s for all enums no problem

caoccao commented 1 month ago

So that means that if I change the AST's language through PluginHost.process() it will change the target language? If so, how can I change the AST language?

In transform(), there is no concept called target language. It just directly casts AST to code. You put a TsTypeAnn number after an Ident a, you get let a: number. That's TS. If you remove that TsTypeAnn, you get let a. That's JS.

It's in Kotlin

That's fine. swc4j is written in Java 8 for maximum compatibility so that it cannot take any Kotlin code. I wonder if you could post the Kotlin code here later, and I would rewrite it in Java. Thank you.

WarningImHack3r commented 1 month ago

In transform(), there is no concept called target language. It just directly casts AST to code. You put a TsTypeAnn number after an Ident a, you get let a: number. That's TS. If you remove that TsTypeAnn, you get let a. That's JS.

I see, that's clever!! I'm going to try this out (and probably make a PR to clarify the docs on that point)

I wonder if you could post the Kotlin code here later, and I would rewrite it in Java.

Don't worry, I'm going to do it myself and push a PR for that

Thanks for your help overall!