Skip to content

Circular dependencies don't always work #32

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

Closed
gentoo90 opened this issue Feb 18, 2018 · 6 comments
Closed

Circular dependencies don't always work #32

gentoo90 opened this issue Feb 18, 2018 · 6 comments

Comments

@gentoo90
Copy link

I stepped on this while trying to add some webassembly to a Visual Studio Code extension.
Right now output.js and output_wasm.js both import each other and this doesn't work in VS Code because import_b is empty when WebAssembly.instantiate is called:
wasm-bindgen-missing-exports

While the same file imported in the main module has everything in place:
wasm-bindgen-exports-in-place

Everything started working like a charm after I manually moved stuff required by wasm into a separate file and imported it from both files.

You can see the example extension in https://github.com/gentoo90/vs-wasm
Uncomment line 24 in tasks.json and relaunch to see the error.

@alexcrichton
Copy link
Contributor

Aha thanks for the info! This actually sounds like a great idea to me, I was a little wary as well about the circular imports.

I think we can totally change codegen to emit three files, one JS module for the "real interface", one for the wasm, and one for internal support. That I think should allow us to break cycles as the internal support doesnt import anything and the wasm only imports that

@alexcrichton
Copy link
Contributor

So I've actually found out that this very easy to do and may actually not be possible (oh dear!)

In #48 though I've tweaked the codegen as it looks like webpack was also not happy with our circular imports. I've tweaked it though such that webpack now works, mind giving VSCode a spin to see if it now works as well?

@alexcrichton
Copy link
Contributor

Oh right I meant to expand on why this may be hard.

In general wasm-bindgen stuff falls in two categories, imports and exports. We're generating a JS module where the exports must be present, but the imports can go anywhere. Both the imports and the exports reference the wasm module itself (to do things like read memory, deal with strings, etc). The wasm module also references imports.

Finally, we've got a category of "shims" which is various runtime support in JS for wasm-bindgen, and both exports/imports need this functionality.

Or otherwise, in a pretty graphviz diagram:

image

So clearly there's a cycle here but it's purely an internal cycle, doesn't have to be user facing. In that sense I don't think it's possible to actually break all cycles but I'm also curious if the construction in #48 helps! I personally know very little about cyclic imports in ES6 modules and how they're supposed to work, but I'm hoping we can squeak by...

@gentoo90
Copy link
Author

gentoo90 commented Mar 4, 2018

Ok, so I updated wasm-bindgen and gave it one more try, and it failed again with the same error. But then I thought that maybe import order matters. Aaaand it does. After I put import { booted } before import ffi from 'wasm.js' it started working properly. But I'm not sure if that trick is reliable cause it may depend on JS engine.

@alexcrichton
Copy link
Contributor

Interesting! I'm unfortunately pretty unfamiliar with how circular imports are supposed to work but it's good to know that it at least works somewhat!

@alexcrichton
Copy link
Contributor

I'm going to close this for now as I think it's very non-trivial to get away from this, but it seems to be working in most packaging systems.

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

No branches or pull requests

2 participants