rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript
https://rustwasm.github.io/docs/wasm-bindgen/
Apache License 2.0
7.81k stars 1.08k forks source link

Example to call JS with imports? #2375

Open ivnsch opened 3 years ago

ivnsch commented 3 years ago

Trying to call a JS file that uses (JS) imports from Rust. Getting errors:

#[wasm_bindgen(module = "/www/foo.js")]
extern "C" {
    fn myjsfunc(address: &str);
}

foo.js

import { mod } from "./module"
// or
const mod = require("./module")
// also not imports from external modules
import { mod } from "module"
ERROR in ../......-8baa1b60db89072f/www/foo.js
Module not found: Error: Can't resolve './module' in '/......./pkg/snippets/foo-8baa1b60db89072f/www'
 @ ../....../foo-8baa1b60db89072f/www/foo.js 27:19-36
 @ ../pkg/foo_bg.js
 @ ../pkg/foo.js
 @ ./index.js
 @ ./bootstrap.js

The JS works if I start the project from JS. It doesn't work only when called from Rust.

I overflew the examples in this project and couldn't find anything similar. The char example uses JS imports, but there JS calls Rust.

My project is configured like this one: https://github.com/i-schuetz/wasm-error (the sources are different, can upload these if needed).

alexcrichton commented 3 years ago

Hm is this different from https://github.com/rustwasm/wasm-bindgen/issues/2368? I'm not sure that repository is still in a state to reproduce this error?

ivnsch commented 3 years ago

This may be the more general problem. Imports in JS don't work.

It's the same project as the other one, but importing a regular "hello world" JS file instead of the wasm interface.

alexcrichton commented 3 years ago

Sorry but this is probably out of my wheelhouse. I suspect the issue is with webpack configuration or related, but I don't know for sure and don't know well how to diagnose.

ivnsch commented 3 years ago

I forked master and updated the import-js example to reproduce the error: https://github.com/i-schuetz/wasm-bindgen/commit/bd00737c7d20e396012d3cd3390f91f04849da67

Steps to reproduce

cd examples/import_js
npm run serve

Error:

ERROR in ./crate/pkg/snippets/import_js-614d6b8c410ac4f9/defined-in-js.js
Module not found: Error: Can't resolve './myimport' in '/xxxx/wasm-bindgen/examples/import_js/crate/pkg/snippets/import_js-614d6b8c410ac4f9'
 @ ./crate/pkg/snippets/import_js-614d6b8c410ac4f9/defined-in-js.js 1:0-33
 @ ./crate/pkg/index_bg.js
 @ ./crate/pkg/index.js
 @ ./index.js

npm version 6.14.8 wasm-pack version 0.9.1 MacOS 11.0.1

ivnsch commented 3 years ago

In this commit I modified the above example to do imports only in JS (no calls from Rust), which works: https://github.com/i-schuetz/wasm-bindgen/commit/f68cb2f2acbfc872b04693bcd8784004d15022e2

ivnsch commented 3 years ago

@alexcrichton what's the way forward to solve this? Can it be confirmed whether it's a webpack configuration or a wasm-bindgen problem?

alexcrichton commented 3 years ago

I think someone with more webpack knowledge would need to weigh in here probably?

9SMTM6 commented 3 years ago

Not exactly an expert on webpack, but I just dont use the tooling from the rust-wasm ecosystem. I dont want it top build my Rust projekt on every npm run start anyways.

So I just use a generic wasm-loader, with my package.json referring to the pkg-folder of my Rust-Projekt.

Unfortunately I cant give you a full webpack-config, as I use react-scripts-rewired to modify the config of react-scripts (a react-project bootstrap), and as I said, no expert, I just tacked together some stuff until I got it working. But heres what I got:

// config-overrides.js

const path = require('path');

const wasmExtensionRegExp = /\.wasm$/;

module.exports = function override(config, env) {
    // config.resolve.extensions.push(".wasm");

    config.module.rules.forEach(rule => {
        (rule.oneOf || []).forEach(oneOf => {
            if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
                // Make file-loader ignore WASM files
                oneOf.exclude.push(wasmExtensionRegExp);
            }
        });
    });

    // Add a dedicated loader for WASM
    config.module.rules.push({
        test: wasmExtensionRegExp,
        include: path.resolve(__dirname, 'src'),
        use: [{ loader: require.resolve('wasm-loader'), options: {} }]
    });

    return config;
}
// package.json
{
    "dependencies": {
        "generic-rust-wasm-proj": "file:path/to/rust/proj/pkg/",
        "react-app-rewired": "^2.1.7",
        "wasm-loader": "^1.3.0"
    }
}

even the hot-reloading from react-scripts works just fine if I rebuild my Rust-Project. Good enough for me, that integrated approach is just asking for bugs.