[Idea] Generate TS code then compile to JS
Currently when generating js code, there is an additional .d.ts file generated. Furthermore, the JS that is generated requires ESM support.
Instead could there just be TS generated that then is compiled to generate the js and .d.ts. This would allow for targeting any JS and reduce the complexity of the code generation. This does, however, introduce an additional dependency but projects SWC could be added as part of the workflow.
If this sounds like a good idea, I'd love to give it a try.
Thanks for the report! This was actually originally done, generating TypeScript instead of JS, but more given that JS was "lower level" (didn't require preprocessing) it forced the need for JS. Supporting both JS and TS output is not trivial and required a good deal of duplication (especially if the JS is accompanied with *.d.ts) so I at some point removed the TS generation and instead focused solely on JS and *.d.ts.
AFAIK it would still be pretty nontrivial to support both languages so I think I'd prefer to not add a mode that emits *.ts files.
Do you have an example of this? Since TS is a superset of JS, I'm confused how providing support for TS doesn't translate to JS support.
Since TS is a superset of JS, I'm confused how providing support for TS doesn't translate to JS support.
It does, but only for people using the TypeScript compiler, so we'd add that as a hard dependency to their workflow, when otherwise it might not be. OTOH, for TypeScript users the type definitions are what's important, not necessarily the implementation of the bindings (which they really should treat as an implementation detail), and we provide those with the .d.ts file.
Adding TS to your tooling can be tricky given how many options there are, however, by leaving it in TS the output can be any flavor of JS, whereas writing directly to JS forces you to pick one.
Furthermore, adding say SWC to the current tooling here means you get JS at the end and can provide arguments for which JS if the default ESM is not preferable.
Ah it appears I got my repositories mixed up, I thought this was an issue on the wasm-bindgen repository originally when I wrote my response. In any case though the conclusion I personally feel is the same where a TS-generation mode ends up duplicating too much with JS output. In any case though I don't have examples in this repository for the examples of complexity, it's all from my experience with the history of the wasm-bindgen repository.
Some users won't want extra tooling to consume the output, e.g. anyone putting the code directly into a browser or something like that. While TS tooling is commonplace it's not 100% ubiquitous, which is why the JS is the "least common denominator" for now.
by leaving it in TS the output can be any flavor of JS, whereas writing directly to JS forces you to pick one.
I'm not sure I fully understand this point. You're of course right that we have to choose a specific flavor, but one can always convert it to an older JS version. There are also tools to convert ESM to CJS, but I think that's less relevant these days, as all runtimes have native ESM support.
Given this situation, I think it's much better to emit something that for a large number of use cases can be used as-is, without any further tooling, and without the need for us to add significant dependencies such as SWC.
Fair enough I had only played around with the output from this repo and had issues since I haven't figured out how best to play with TS + ESM. I ended up having to fix the import names since node wanted .js endings on imports: https://github.com/AhaLabs/wit-bindgen/blob/feat/simple_example/crates/examples/wit-bindgen-example/buildtools/fix-imports.js
There is probably a better way to get TS generated files to play well with these, but I wouldn't have had this issue if I could chose to generate the the output. Though I would love a pointer on how to deal with this is the general case.
In my use case I am generating TS (though it falls into what I call a remote Wasm adapter, so doesn't apply here) and will be adding SWC support to my pipeline. After I set it up and see how well it works I'll report back.
After I set it up and see how well it works I'll report back.
Great, thank you.
And to be clear, I could well imagine that there's room for improvement in both the JS code and the d.ts files we generate :)
Going through some old JS issues, I'm going to close this since I don't think this will be implemented (implying a second output mode), but any options necessary to tweak the output of the original JS I think is fine to implement, so if something is needed feel free to open an issue or make a PR about changing the output.