-
Notifications
You must be signed in to change notification settings - Fork 256
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 for including Web Workers #46
Comments
@siku2 this is really excellent. Thanks for opening the issue. Everything you've proposed above makes sense, and seems quite doable. I would like to propose a slight modification. One thing that I've been trying to stick to with the overall design of Trunk is to keep the required amount of config as minimal as possible, and wherever we can, keep assets & build instructions in the source HTML. I will admit that this pattern is obviously not best for everything, but it may actually work quite nicely with this web workers system. drive from
|
@MartinKavik any thoughts on the above items as well? |
@siku2 this also makes me realize that we should be leveraging the info from |
I love the idea of using There still needs to be an attribute to specify the output path to satisfy the second requirement. The only nitpick I have is that "href" should be optional and if specified, may point to the parent directory of |
Do you mind expounding a bit more on what our requirements are for this? Mainly:
As far as the optional href bits, I can agree. I am tempted to say that the entire
Agreed on supporting the pattern of pointing to the dir of the
Agreed that it would remove the need for the |
The worker binary is generated using: wasm-bindgen --target no-modules --out-name worker path/to/wasm The output is then included in the server directory.
Yes, but the app already handles this internally. This isn't something I think Trunk should do because Web Workers are often created dynamically and different apps have different requirements.
No, we're talking about the worker itself here. The worker script needs to set up everything by itself, we don't have the ability to call the "init" function.
It should definitely be optional! No need to introduce the complexity for simple apps.
The issue there is that you might want to support something like this in the future:
where index.html contains: <link rel="trunk-app" href="my_app" />
<link rel="trunk-worker" href="my_worker" /> Where do you place the I realize my suggestion of placing it relative to the index file isn't ideal for a setup like this:
which would result in |
So according to the points above I would suggest for setup like:
<script type="wasm" src="my_app" data-trunk-main>
<script type="wasm" src="my_worker"> Notes:
|
@siku2 your example of having two different crates — one for the app and another for the worker — is definitely a good one, and I had considered that, and I drew the same conclusion you did, so sounds like that may indeed be best.
@siku2 thanks for all of the info on the worker setup and all. That makes sense. I'll do some experimentation to see if there may be a simple way to solve these issues. Hopefully we can cross this bridge without a JS bundler ... we'll see. @MartinKavik great feedback. I agree on most points.
The main reason I chose to use
|
Ok, one more item of discussion here. Related to some general ideas in #3, some from #28, I'm thinking that what we might want to do for the HTML portion of these updates is to stick with Right now, Trunk only uses the special
With the above proposal, the HTML links would now look like this: <html>
<head>
<link rel="rust" data-bin="app" href="path/to/Cargo.toml"/>
<link rel="rust" data-bin="worker" data-worker href="path/to/Cargo.toml"/>
</head>
</html> I know that specifying an This pattern will then set the precedent for future link types. Potentially including WASM modules from other languages. Transpiled JS/TS ... whatever. Simple Thoughts? |
A fucking killer combo on the above for JS/TS would be: <link rel="js" data-build-command="build" data-watch="js/src,ts/src" href="path/to/package.json"/> With this, Trunk would be able to build JS & TS apps (or any other JS offshoot language), and include their artifacts in the
This is the first JS/TS integration option which I've felt ok about. Hype! |
I think using
I really like this approach and the possibilities it entails! Perhaps, to avoid confusion, we could use a custom element like It's not necessary to use the custom element for everything. For instance, it makes sense for trunk to handle Sass in
I don't see how there's a chance for misconfiguration by making If we look at the example I used before:
Thanks to the workspace, running So the following index.html should work: <html>
<head>
<!-- Using the custom element proposal from above to get a feel for how it looks -->
<trunk-link type="rust" bin="my_app" />
<trunk-link type="rust" bin="my_worker" data-worker />
</head>
</html> I think this is much cleaner than this: <html>
<head>
<link rel="rust" bin="my_app" href="./my_app/Cargo.toml" />
<link rel="rust" bin="my_worker" data-worker href="./my_worker/Cargo.toml" />
</head>
</html> It's even worse when we're dealing with a single crate with multiple binary targets because then I feel like we haven't really tackled the second issue yet.
The way I see it, until we have the trunk library which can take care of this, using a pre-determined output name is the best solution. And finally:
@MartinKavik makes a good point here. The reason I singled out Web Workers for this issue is because of their special requirements. Other types of binaries don't necessarily have to:
Having a "preset" for workers seems very reasonable because of this. This isn't to say that we shouldn't support other types, but depending on what they do they have entirely different requirements. With the current design it should be fairly easy to add such functionality in the future, so I don't think we need to focus on this too much yet. |
Syntax highlighting is being done on main thread. This is kinda slow operation and blocks the main thread. It should be done in a web worker but that is unsupported by trunk and is a hassle to get working. See: trunk-rs/trunk#46
Just to mention that an implementation which is compatible with audio worklets (which are somewhat similar to web workers but may have some specific scope restrictions) would be very cool. |
@rfwatson do you mind sharing some info on what you would expect Trunk to need to do in order to support audio worklets? If you want to open a new issue for it as well, that would be fine. Once I have some additional cycles I'll of course do some research on this |
Is there any ongoing work on this? If not, could I give it a shot? |
My reference for this issue is Yew's
multi_thread
example which requires two WASM binaries. One for the actual application and one for the Web Worker.Up until now building applications with web workers has been a real pain but with trunk we have the chance to turn this around.
Requirements
The following is an objective list of problems that need to be solved to support Web Workers.
1. Multiple binary targets
Trunk should handle crates with multiple binary targets gracefully.
Currently, invoking
trunk serve
on the aforementioned example results in this error:The
multi_thread.wasm
could not be found because there are two WASM binaries calledapp.wasm
andworker.wasm
.While it isn't strictly related to this issue, I think this behaviour could be improved.
2. Letting the app know where to find the Web Worker
Because of how Web Worker are created[link] we need to know the URL of the worker's Javascript file while compiling the app.
3. Building Web Workers with the required Javascript code to start them
Trunk currently runs
wasm-bindgen
with--target=web
. The generated js code exports an initializer function which needs to be called to start the program. This doesn't work for Web Workers as they need to be self-executing.Proposal
This is just one potential way of solving the issues mentioned above to get the discussion started.
Since Trunk already has a config file, I think it makes perfect sense to use it for this.
We add a new section to
[build]
, let's call it "targets", which is used to configure binary targets.To take care of 3., we can simply build the WASM with
--target=no-modules
.Since we still want to have normal binaries, let's give each target a
type
key with the following two values:Builds the binary with
--target=web
and includes it inindex.html
.--target=no-modules
.The output is moved to
dist/
but not added toindex.html
For 2. we need to allow targets to side-step hashing so we can assign static URLs to them.
In the future this could use a similar approach to #9 so we don't miss out on caching, but for now we can just add a key "output" to the target which manually sets the output path.
This is what it would look like when applied to the
multi_thread
example:Trunk should reject projects with multiple binaries (without appropriate configuration) outright and point the user to documentation on the subject.
It might be tempting to guess which binary is which based on certain keywords (like "app" and "worker") but this probably does more harm than good in the long run.
This satisfies 1..
This is quite a high priority feature for Yew and I would love to help out with this.
The text was updated successfully, but these errors were encountered: