diff --git a/Cargo.toml b/Cargo.toml index 3bae5e9e..dd9ae64e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ members = [ "examples/add", "examples/asm.js", "examples/char", + "examples/import_js", ] [profile.release] diff --git a/examples/README.md b/examples/README.md index f62f9f2e..617f6f44 100644 --- a/examples/README.md +++ b/examples/README.md @@ -34,5 +34,6 @@ The examples here are: * `asm.js` - an example of using the `wasm2asm` tool from [binaryen] to convert the generated WebAssembly to normal JS * `char` - an example of passing the rust `char` type to and from the js `string` type +* `import_js` - an example of importing local JS functionality into a crate [binaryen]: https://github.com/WebAssembly/binaryen diff --git a/examples/import_js/.gitignore b/examples/import_js/.gitignore new file mode 100644 index 00000000..bd9c9eb3 --- /dev/null +++ b/examples/import_js/.gitignore @@ -0,0 +1,4 @@ +package-lock.json +import_js.js +import_js_bg.js +import_js_bg.wasm diff --git a/examples/import_js/Cargo.toml b/examples/import_js/Cargo.toml new file mode 100644 index 00000000..bf2fdf7a --- /dev/null +++ b/examples/import_js/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "import_js" +version = "0.1.0" +authors = ["Alex Crichton "] + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wasm-bindgen = { path = "../.." } diff --git a/examples/import_js/README.md b/examples/import_js/README.md new file mode 100644 index 00000000..9a8b542f --- /dev/null +++ b/examples/import_js/README.md @@ -0,0 +1,20 @@ +# Importing non-browser JS + +This directory is an example of using the `#[wasm_bindgen]` macro to import the +JS defined by you rather than the browser. + +You can build the example with: + +``` +$ ./build.sh +``` + +(or running the commands on Windows manually) + +and then opening up `index.html` in a web browser and see some messages in the +console. + +For more information about this example be sure to check out +[`hello_world`][hello] which also has more comments about caveats and such. + +[hello]: https://github.com/alexcrichton/wasm-bindgen/tree/master/examples/hello_world diff --git a/examples/import_js/build.sh b/examples/import_js/build.sh new file mode 100755 index 00000000..4446e5c2 --- /dev/null +++ b/examples/import_js/build.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# For more coments about what's going on here, see the `hello_world` example + +set -ex + +cargo +nightly build --target wasm32-unknown-unknown +cargo +nightly run --manifest-path ../../crates/cli/Cargo.toml \ + --bin wasm-bindgen -- \ + ../../target/wasm32-unknown-unknown/debug/import_js.wasm --out-dir . +npm install +npm run serve diff --git a/examples/import_js/defined-in-js.js b/examples/import_js/defined-in-js.js new file mode 100644 index 00000000..24854507 --- /dev/null +++ b/examples/import_js/defined-in-js.js @@ -0,0 +1,21 @@ +export function name() { + return 'World'; +} + +export class MyClass { + constructor() { + this._number = 42; + } + + get number() { + return this._number; + } + + set number(n) { + return this._number = n; + } + + render() { + return `My number is: ${this.number}`; + } +} diff --git a/examples/import_js/index.html b/examples/import_js/index.html new file mode 100644 index 00000000..14e4ff72 --- /dev/null +++ b/examples/import_js/index.html @@ -0,0 +1,9 @@ + + + + + + +

Open up the developer console and you should see "Hello from Rust!"

+ + diff --git a/examples/import_js/index.js b/examples/import_js/index.js new file mode 100644 index 00000000..791d8267 --- /dev/null +++ b/examples/import_js/index.js @@ -0,0 +1,5 @@ +// For more comments about what's going on here, check out the `hello_world` +// example +const rust = import("./import_js"); + +rust.then(m => m.run()); diff --git a/examples/import_js/package.json b/examples/import_js/package.json new file mode 100644 index 00000000..c9666e67 --- /dev/null +++ b/examples/import_js/package.json @@ -0,0 +1,10 @@ +{ + "scripts": { + "serve": "webpack-dev-server" + }, + "devDependencies": { + "webpack": "^4.8.1", + "webpack-cli": "^2.0.10", + "webpack-dev-server": "^3.1.0" + } +} diff --git a/examples/import_js/src/lib.rs b/examples/import_js/src/lib.rs new file mode 100644 index 00000000..43697899 --- /dev/null +++ b/examples/import_js/src/lib.rs @@ -0,0 +1,39 @@ +#![feature(proc_macro, wasm_custom_section, wasm_import_module)] + +extern crate wasm_bindgen; + +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(module = "./defined-in-js")] +extern { + fn name() -> String; + + type MyClass; + + #[wasm_bindgen(constructor)] + fn new() -> MyClass; + + #[wasm_bindgen(method, getter)] + fn number(this: &MyClass) -> u32; + #[wasm_bindgen(method, setter)] + fn set_number(this: &MyClass, number: u32) -> MyClass; + #[wasm_bindgen(method)] + fn render(this: &MyClass) -> String; +} + +// Import `console.log` so we can log something to the console +#[wasm_bindgen] +extern { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + +#[wasm_bindgen] +pub fn run() { + log(&format!("Hello, {}!", name())); + + let x = MyClass::new(); + assert_eq!(x.number(), 42); + x.set_number(10); + log(&x.render()); +} diff --git a/examples/import_js/webpack.config.js b/examples/import_js/webpack.config.js new file mode 100644 index 00000000..5910e2ae --- /dev/null +++ b/examples/import_js/webpack.config.js @@ -0,0 +1,10 @@ +const path = require('path'); + +module.exports = { + entry: "./index.js", + output: { + path: path.resolve(__dirname, "dist"), + filename: "index.js", + }, + mode: "development" +};