trunk-rs / trunk

Build, bundle & ship your Rust WASM application to the web.
https://trunkrs.dev/
Apache License 2.0
3.49k stars 252 forks source link

Any plans for supporting bundling JS packages? #273

Closed jquesada2016 closed 11 months ago

jquesada2016 commented 2 years ago

Perhaps there is already a way to do this, but I was unable to figure it out, but is there any way to bundle JavaScript packages? If not, are the plans for adding this capability?

I know one can use snippets, but this is quite limiting, as one needs to reinvent the wheel for possibly very large JS packages, such as the AWS SDK, Firebase, etc. My workaround for these had been to prototype with Trunk and then shift over to Rollup once I need these packages.

Additionally, snippets, according to the wasm_bindgen docs, are limited to not importing anything, so I can't include most JS packages that are not self contained.

thedodd commented 2 years ago

@jquesada2016 I think we should support this. We have one other issue where we've discussed this. My main question is: what do you think this should look like?

The thing I would want to do is find a way to have seamless integration without adding too much baggage to Trunk. This would be especially troublesome if we added a bunch of specific JS tooling, given that the JS ecosystem is so diverse.

jquesada2016 commented 2 years ago

I think this problem is much more complex with many nuances that make it seem simple at first glance, but really isn't. Thankfully there are many battle tested tools, and I think there are many paths that can be taken. I also think it'd be wise to limit the scope of support.

For example, let's take one of my particular use cases, AWS SDK. This SDK notoriously doesn't play well with many bundlers because of it's reliance on node globals, even though it is designed to also run on the browser. These have to be polyfilled, and in my experience, the only two bundlers that can handle it gracefully are Webpack and Rollup. I do think, however, that tightly integrating with NPM is the better choice, and I only think that because it's the crates.io equivalent in the JS world.

The kind of API that I would imagine would be one where you just npm install whatever you want to use, and trunk will read the package.json and just pull those packages in. I think that's the most transparent, and would also allow to pull in packages from sources other than NPM, such as GitHub. This would also act differently if you were building for release vs debug builds as package.json supports dev dependencies.

Regarding the transformations, bundling, etc., we could either call into one of the big bundlers to bundle the final result (which would also allow advanced users to supply their own custom configs for more advanced use cases), or call into something like ESBuild, which is pretty easy to interface with.

Regarding building our own bundler, I really would shy against it, not because it couldn't be done, but rather because it's been done many times before, and it might be a better choice to ride on the shoulders of giants until a more concrete need for creating a custom bundler arises.

What do you think?

ranile commented 2 years ago

I've used rollup to bundle library and call it from wasm_bindgen (see material-yew). Rollup and webpack are the major two bundlers in JS world. Webpack doesn't work well wasm-bindgen out of the box. wasm-bindgen requires esmodules that (as of last time I looked) webpack doesn't support natively. That leaves us with Rollup being the most suitable choice.

Trunk could look for rollup.config.js and call rollup with it. The output can be consumed by the application. This has the benefit of not introducing yet another JS bundler, allowing any npm package to be used and taking advantage of the ecosystem of plugins, etc already developed for rollup.

ctron commented 2 years ago

It would be great to have an example that shows how this is intended to be used.

gilescope commented 2 years ago

Ye gods it's not easy to pull in a deno/nodejs package and try and use it from rust. An example would be amazing as for rust people it's really really difficult as we're clueless as to which of 6 bundlers are needed or what flavour of js we're using these days... most of the bundlers seem to bundle everything up and not export anything so it compiles but doesn't run in the browser. 48 hours into trying to call a hello world npm package from rust and it's still not clear at all. If anyone could point to an existing project that uses trunk and npm that would be good. At the moment it seems only an expert in Js AND rust knows how to pull this off which is a shame because if there was a working example then it might turn out to be not that difficult.

gilescope commented 2 years ago

(credit where credit's due: using rust web workers was relatively plain sailing - a great job has been done there in the examples making a complicated thing pretty easy.)

MendyBerger commented 1 year ago

I'll second what @hamza1311 said. Being able to call out to rollup probably makes the most sense. The JS ecosystem is just too large, it'll be practically impossible to build into Trunk all the compilers, minifiers, and bundlers, that the JS devs constantly pump out.

ctron commented 1 year ago

To be honest, creating -sys style crates, wrapping JS code with wasm_bindgen, is a nice pattern IMHO. Setting this up isn't a difficult task, once you figured out "how" and made your peace working with some JS tooling. Hiding that in a -sys crate helps.

As code gets committed to the repository, there is no need for the user to provide any kind of JS tooling.

Here is an example on how to use this pattern: https://github.com/ctron/asciidoctor-web … based on @siku2's approach in rust-monaco.

Ddystopia commented 1 year ago

This could help a lot, because many of the necessary packages are only in js. For example, I wanted to use codemirror, but I can't do that, so I have to use monaco (thanks to this kind person who made the bindings there), although it doesn't have some of the features I need.

ctron commented 1 year ago

although it doesn't have some of the features I need.

PR's welcome :)

github-actions[bot] commented 12 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

github-actions[bot] commented 11 months ago

This issue was closed because it has been stalled for 5 days with no activity.