-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 init function without parameters #1559
Comments
Do you have an idea of how to implement this? While we know that the wasm is next to the JS glue by default, and we know how to go from the JS glue to the wasm with a relative URL path, we don't know where the whole |
@fitzgen what about import.meta? function init(module) {
let result;
const imports = { './webgl_engine': __exports };
if (typeof module === "undefined") {
module = import.meta.url.replace(/\.js$/, '_bg.wasm');
}
if (module instanceof URL || typeof module === 'string' || module instanceof Request) { |
I think that's just a node-ism and wouldn't work in other locations? (and it's also only an es6 node-ism I think which is still somewhat experimental) |
What is node-ism? It's a part of es-modules, browser support according to MDN is Chrome 64, Firefox 62, Opera 51, Safari 11.1 (no information about Edge, but it will be based on Chromium anyway soon). It's possible to use |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import.meta Looks like it is stage 3 right now. Yeah, with |
Oh nice! I didn't realize that and that sounds reasonable to me! |
I'm running into problems parsing the module with import.meta. If you are using target |
I was able to get around this by adding @babel/plugin-syntax-import-meta and babel-plugin-bundled-import-meta (with the importStyle set to cjs) |
@jljorgenson18 The |
@Pauan The bundler option doesn't work at the moment because it relies on Webpack's internal Wasm parsing (which is extremely buggy and I have yet to see it work). Nearly all of the workarounds I've seen for Webpack failing to parse the wasm file end up using file-loader and then they pass the url to WebAssembly.instantiate themselves. If you opt for a solution that loads in a wasm distribution via url, then the web target is the best bet since you can just pass in the url string. I think ideally, there would be a middle ground target that is more agnostic to pure web modules and pure bundler options. |
I haven't had any issues with Webpack + Wasm. There used to be some bugs in the past, but they've been fixed. Make sure everything is up to date (Webpack, wasm-bindgen, wasm-pack, etc.) If you're still running into issues, then you should file a bug report. |
The initial issues I ran into on the wasm-bindgen side had to do with #1246 and #1564 which seemed to be fixed by webpack/webpack#8786. However, with using tools like Emscripten, Webpack cannot handle the wasm files webpack/webpack#7352. So the solution is just to instantiate the module yourself with a bit of glue code and to use file-loader. If you are using wasm files generated from various tools, chances are at this stage that Webpack won't work well with all of them. You could dynamically change the loader using inline loader syntax or a combination of oneOf + resourceQueries, but at that point, what is the point of using Webpack to instantiate the wasm modules? If you want to have greater control over how the wasm bytes are imported while still using some of the nice javascript bindings, then the web option actually works really well other than the import.meta condition. |
Ah, right, Rust + emscripten has a lot of issues (in general, not just with Webpack). Well, I'm glad you were able to find a workaround at least. |
Well emscripten was compiling a C module, it was just that the general wasm + emscripten compiliation does not get along well with Webpack (I'm guessing it's because of the extra env options needed). Because of that, you have to add a rule to overwrite the webassembly/experimental type with file-loader and then potentially create your own instantiate functionality. |
Hello, I run into one issue after the other trying to use wasm together with Angular.
Please, consider adding an option to omit |
FWIW, I was using |
@suyoshi If you are using babel, you can add |
Hi @suyoshi , thanks for your report! I'm sorry for breaking things. Can you tell more details about your case so we could probably find a good solution? In particular, why the |
Sorry for the late reply, I didn't get any notifications! @ibaryshnikov It would be really great if |
@ibaryshnikov Yeah, I know that. But even if webpack resolves it properly, I noticed that there's an even worse issue plaguing the Leaving alone the I know how to work around it, but it prevents you from importing any types from the generated package. The |
what makes it useless for your case? I mean, |
Sorry, I should have explained it better. The problem is not that it's asynchronous. This is possible with
But it's not possible with
I hope that explanation makes more sense! |
@suyoshi You should be able to do something like this: private someClass: import("path/to/module").SomeClass;
private someObject: import("path/to/module").SomeInterface;
...
import("path/to/module").then(module => {
...
}); Ugly, but it will work. You could also tidy it up a bit like this: type Foo = typeof import("path/to/module");
...
private someClass: Foo["SomeClass"];
private someObject: Foo["SomeInterface"];
...
import("path/to/module").then(module => {
...
}); |
There's also another solution, which I think is much better. You can import the import { SomeClass, SomeInterface } from "path/to/module";
private someClass: SomeClass;
private someObject: SomeInterface;
...
this.someClass = new SomeClass();
this.someObject = this.someClass.someFunction();
... (Note that there's no dynamic ...and then you can asynchronously import the main module in your import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
import('./app/app.module')
.then(AppModule => platformBrowserDynamic().bootstrapModule(AppModule))
.catch(err => console.error(err)); This should make Webpack happy (because there is a dynamic I recommend doing this rather than using |
Hello @Pauan, I tried the
It happens because of this line ( What is About the first example, it kinda works, but is really ugly as you said. As long as the |
@suyoshi In your code example you used Did you change
Because 1) it doesn't work, as you have noticed, and 2) there's no guarantee it will work in the future, because it wasn't designed for this use case. In addition, my suggestion of importing the |
@Pauan Yes, And I also changed the |
@suyoshi Ah, there was a small error in my code. Here is the correct code: import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
import('./app/app.module')
.then(x => platformBrowserDynamic().bootstrapModule(x.AppModule))
.catch(err => console.error(err)); I created a new Angular project and verified that the above does indeed work perfectly: I can load the wasm-bindgen files synchronously and everything works great: import { Component } from '@angular/core';
import { add } from "./wasm/index";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = '' + add(1, 5);
} |
@Pauan @ibaryshnikov You guys rock! The last approach seems to work fairly well. Many thanks. 👍 Just one minor thing (I hope). It results in two warnings:
But those are negligible for now I guess, since everything seems to work as it should. Sorry for all the noise! |
Hi guys, I'm wondering In Angular when we are importing wasm package, can we get rid of these warnings WARNING in Circular dependency detected: WARNING in Circular dependency detected: Thanks |
And btw I received another error on prod building, od develop building everything is working fine ERROR Error: Uncaught (in promise): TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'. |
@tonimitrevski it's a false positive about circular dependencies since it's not possible to import javascript from wasm atm, it just happened that imports object used during As a workaround, is it possible to skip certain imports in circular dependency detector? I had the same warning while building my app with webpack, but I simply ignored it. Incorrect mime type is a common error. As error says, the file server should use a correct mime type for |
@ibaryshnikov Thank you for the answer. |
@tonimitrevski to continue about circular dependencies, if you use something like this plugin https://github.com/aackerman/circular-dependency-plugin there's an option to exclude certain files, for example // webpack.config.js
const CircularDependencyPlugin = require('circular-dependency-plugin')
module.exports = {
entry: "./src/index",
plugins: [
new CircularDependencyPlugin({
exclude: /\.wasm/, Angular doesn't expose webpack config, but maybe there's an equivalent option |
It's possible to create a custom Webpack config for Angular: https://netbasal.com/customize-webpack-configuration-in-your-angular-application-d09683f6bd22 |
Guys thank you very much I fixed the problem, appreciate your help 💪 💪 💪 |
I ran into the same issue and followed the instructions of @Pauan. This does allow me to compile the app, but the app won't start, because of the following error: My main.ts looks like this:
|
@arjanvaneersel could you also attach the version of import wasm from './my_module_bg.wasm'; there is no need in workarounds, it should work out of the box with |
@ibaryshnikov The version of bindgen was 0.2.34. I now updated it to 0.2.58 to see if that has any effect. I didn't specify any target, so it should use bundler as that's the default if I'm not mistaking. The new version indeed takes care of the import problem, but I do still get this error:
Hence my impression that I still need to change main.ts. For that I used the above mentioned instructions of @Pauan. However, that way doesn't seem to work anymore. I'm using Angular 8 BTW. |
@ibaryshnikov The problem is somewhere else. I created a fresh Angular project and imported the wasm module created via the latest bindgen and followed the instructions to change main.ts as described above. And it works like a charm. Hence something else in my code is causing this error. |
@arjanvaneersel Sounds like you (or one of your dependencies) is incorrectly assuming that it's running in Node, so it's trying to look up |
Although it is absolutely irrelevant to the thread for I use
I have a working example, and it uses |
Motivation
When used without a bundler, there is a need to call init with a
.wasm
file name:and again
Proposed Solution
Make it possible to use
which will default to path with generated
.wasm
fileThe text was updated successfully, but these errors were encountered: