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

Snippets generated even when not needed #3330

Closed
daxpedda opened this issue Feb 24, 2023 · 12 comments · Fixed by #4066
Closed

Snippets generated even when not needed #3330

daxpedda opened this issue Feb 24, 2023 · 12 comments · Fixed by #4066
Labels

Comments

@daxpedda
Copy link
Collaborator

The PR #3069 introduced linked modules, link_to!(module = "/test.js"). Currently this is meant to use snippets only if the --split-linked-modules is enabled, but not otherwise.

Currently, snippets are always generated, even in the no-modules target, they can be safely deleted and ignored, but they shouldn't be generated in the first place.

This can be easily tried by using link_to!(module = "/test.js") and trying out the following commands.

  • wasm-bindgen --target no-modules
  • wasm-bindgen --target web
  • wasm-bindgen --target no-modules --split-linked-modules

Happy to give a more comprehensive, easy to use example if desired.

Cc @lukaslihotzki.

@lukaslihotzki
Copy link
Contributor

I understand your issue.

There isn't a clean, small fix for it, because we don't know the target in the function where we could remove the files. Maybe we could disable the write-to-disk of all snippets on no-modules without --split-linked-modules, because snippets cannot be imported modules or split linked modules (as wasm-bindgen would error earlier), so they are embedded linked modules, so their write-to-disk can be skipped. I'll look if that can be a small fix. I wouldn't like to introduce new complexity to fix this.

@RReverser
Copy link
Member

link_to can actually help me remove couple of manual hacks from wasm-bindgen-rayon, but only if this behaviour is preserved. Now that it exists, I'm doing something like:

fn _ensure_worker_emitted() {
    // Just ensure that the worker is emitted into the output folder, but don't actually use the URL.
    wasm_bindgen::link_to!(module = "/src/workerHelpers.worker.js");
}

This is because I need the Worker to be emitted alongside the snippet JS so that I can use static construct new Worker(new URL('/src/workerHelpers.worker.js', import.meta.url), { type: 'module' }) that is recognised by bundlers only in this shape.

If snippet wasn't emitted and I could only get a URL value from wasm-bindgen without the statically emitted new Worker(...) wrapper, that would break serveral bundlers.

@RReverser
Copy link
Member

Another alternative would be to extend link_to! to allow custom wrappers around it so that devs could do link_to!(module = "...", wrapper = "new Worker({}, {{ type: 'module' }})") and such, but I imagine that would be a bigger change.

@daxpedda
Copy link
Collaborator Author

@RReverser I plan to address this soon and would like to understand your use case a bit more.

Unfortunately I have no clue about bundlers but I'm unsure what your exact requirements are and why you are relying on wasm-bindgen to ship JS files that you aren't even using inside of Rust.

Would you mind going into more detail explaining things from first principle so even I, without any knowledge of the JS ecosystem, can understand the issue and your goal?

@RReverser
Copy link
Member

RReverser commented Aug 12, 2024

It's used for emitting a Web Worker's entry point alongside the main JS - https://github.com/RReverser/wasm-bindgen-rayon/blob/a947bdce8ef1e4b5456b349bd5b3763fe2516e25/src/lib.rs#L55-L59 - which will be used via new Worker(...) afterwards.

So that emitted file is still used, but shouldn't be imported from the main JS file.

For bundlers, that URL must be statically known name as they will only recognise a pattern like new Worker(new URL("...", import.meta.url)) so I need to ensure that this extra JS is emitted in a statically known location, which is what snippets provide. I wrote about this in an article in the past: https://web.dev/articles/bundling-non-js-resources. Some details have changed, but this pattern is still important.

@daxpedda
Copy link
Collaborator Author

I'm still unsure how this should end up in link_to!() supporting this use case.
link_to!() specifically inlines the linked file into the JS shim without --split-linked-modules, so the generated snippet is unused.

My understanding is that you somehow need a way to for wasm-bindgen to copy your file into the output folder so it can be found by the bundler, but that seems to be a different feature then what link_to!() is intended to provide.

Am I understanding this correctly or am I missing something?

@RReverser
Copy link
Member

Yeah that's correct. I know it's a hacky behaviour, but unfortunately the entire support for threads in Wasm is a hack on top of a hack.

My job in this case was/is to maintain a library that at least hides all of that as implementation details and let's users "just use" Rayon.

If there will be a better way to emit JS files into the output directory, I'm happy to switch to a different, dedicated API.

@daxpedda
Copy link
Collaborator Author

Seeing that I'm really unqualified to address this, could you come up with a detailed feature proposal for wasm-bindgen?

@RReverser
Copy link
Member

Sorry, I don't think I'll have much time soon :( I general terms though... Any macro similar to current behaviour of link_to! should do.

@daxpedda
Copy link
Collaborator Author

Alright, please let me know if there is something else I can do here.
I will go ahead and merge the corresponding PR.

@RReverser
Copy link
Member

So the behaviour above will be broken in the next release of wasm-bindgen? Is there no way to keep it?

@daxpedda
Copy link
Collaborator Author

So the behaviour above will be broken in the next release of wasm-bindgen? Is there no way to keep it?

As I said I'm happy to discuss adding a new feature to wasm-bindgen addressing this problem, but link_to!() should definitely not do this and was creating confusion for users who thought they have to ship the snippet along with the JS shim.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants