Cannot find modules
njtrettel opened this issue · comments
Bug Report
Overview
I get the error, TypeError: WebAssembly Instantiation: Import #0 module="utils" error: module is not an object or function
. I assume there is something I need to do to make these available, but I could not find anything in the docs.
Expected
Should import modules like log
from the env
module, as shown in the simple Walt Explorer examples and quick start guide.
Actual
TypeError - can't resolve modules.
Example
Versions
Node.js: v8.10
Webpack: 4.15.1
walt-loader: 1.0.21
import { log: LogType } from 'env'; // also tried 'console' here
type LogType = (i32) => void;
Webpack config:
const path = require('path')
module.exports = {
resolve: {
extensions: [".walt", ".js", ".css"]
},
module: {
rules: [
{ test: /\.walt$/, use: 'walt-loader' },
{
test: /\.js$/,
exclude: /node_modules/,
use: "babel-loader"
},
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
]
},
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
Hey, if you have a snippet of the source JS file using the import I might be able to help.
The loaded file resolves to a factory function returning the module. The factory takes an import object which is where you would provide the env
object which would have your log method. It's a bit nicer wrapper around WebAssembly.instantiate
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate
There is an example here https://github.com/ballercat/walt/blob/master/packages/webpack-walt-examples/src/CounterExample.js#L8
That make*
method takes an object as the importObj, the example should maybe reflect that API though heh.
The loader has not had an update in a while, but the APIs should still work.
I don't fully understand what you mean. It sounds like I am missing some init parameters?
I have a very similar setup to the CounterExample (although I didn't notice that example initially). Here is my JS snippet:
import React from 'react';
import makeSorter from '../walt/sort.walt';
class Tester extends React.Component {
constructor() {
super();
this.state = {
sorter: null
};
}
componentDidMount() {
makeSorter().then(wasmModule => (
this.setState({ sorter: wasmModule.instance.exports.sortItems })
));
}
render() {
if (!this.state.sorter) {
return <div>Loading...</div>;
}
const result = this.state.sorter([]);
return (
<div>
{result}
</div>
);
}
};
export default Tester;
@ballercat AH! sorry, I just noticed the JS
tab on the Walt Explorer 😄
I see the env
variable you are passing into instantiate
now. Where does that JS piece (you have it titled compile()
) fit in to the big picture then? Should I just compile
my WALT stuff on initial page load?
The Explorer uses a deconstructed compile process to expose the underlying ASTs and other metadata but the idea is still the same.
For your code snippet to pass a log
method nested inside an env
namespace you should do the following
componentDidMount() {
makeSorter({
env: {
log: console.log
}
}).then(wasmModule => (
this.setState({ sorter: wasmModule.instance.exports.sortItems })
));
}
Yes, you could compile it manually and instantiate it since the compiler runs in the browser, but it's usually not what you want to deal with.
Fixed 👍, thanks for the help!
NP! Thanks for pointing out that the docs are out of date
@ballercat didn't want to open a new issue for this, because it's just a random question. a response is not urgent.
if i were to import a javascript library to use in walt (such as importing console.log
in your example), would the performance be the same as if i ran it in JS? i.e, these imported JS library are still run in a JS environment right? I would assume so.
thinking wishfully - It would be super cool if I could import something like lodash
and have it perform like WASM.
It still runs int the JavaScript sandbox, think of it as if you linked a .dll into your executable. You can call the methods imported but you don't change how they are written/executed.
There is even a slight penalty for crossing that wasm <> js boundary (in either direction) as the engine has to perform validation and security(?) checks. I think Firefox at least has worked around some of these speed bumps though.