rs-jest
                                
                                 rs-jest copied to clipboard
                                
                                    rs-jest copied to clipboard
                            
                            
                            
                        Jest preprocessor/transformer for Rust
rs-jest
tl;dr -- see examples
This is a jest transformer that loads Rust code so it can be interop with Javascript base project. Currently, the Rust code will be compiled as:
- [x] WebAssembly module/instance
- [ ] Node.js addon/ffi
Requirements
- Node v8 or later
- Jest v23 or later
- Rust v1.28.0 with wasm32-uknown-unknown installed- rustup default 1.28.0 rustup target add wasm32-unknown-unknown
Getting Started
To begin, you'll need to install rs-jest:
npm install rs-jest --save-dev
Then configure Jest to make rs-jest to transform the Rust (*.rs) file. For example:
jest.config.js
module.exports = {
  transform: {
    "^.+\\.rs$": "rs-jest"
  }
};
or if you prefer to put the config in package.json
  "jest": {
    "transform": {
      "^.+\\.rs$": "rs-jest"
    }
  }
quick usage
lib.rs
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
index.js
import wasm from "lib.rs";
export async function increment(a) {
  const { instance } = await wasm;
  return instance.exports.add(1, a);
}
And run jest via your preferred method.
Options
Pretty much like ts-jest, you can configure rs-jest by using global variables under the "rs-jest" key:
export
How wasm code would be exported. This options is identical with option export in webassembly-loader. (see examples)
{
  "globals": {
    "rs-jest": {
      "export": "instance"
    }
  },
  "transform": {
    "^.+\\.rs$": "rs-jest"
  }
}
target
- Type: String
- Default: wasm32-unknown-unknown
- Expected value: see supported platform
The Rust target to use. Currently it only support wasm related target
{
  "globals": {
    "rs-jest": {
      "target": "wasm32-unknown-emscripten"
    }
  },
  "transform": {
    "^.+\\.rs$": "rs-jest"
  }
}
release
- Type: Boolean
- Default: true
Whether to compile the Rust code in debug or release mode.
{
  "globals": {
    "rs-jest": {
      "release": false
    }
  },
  "transform": {
    "^.+\\.rs$": "rs-jest"
  }
}
Examples
See the test cases and example projects in fixtures and examples for more insight.
The exported module are pretty much like rollup-plugin-rust so it can be used alongside with it
Given this Rust code
lib.rs
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
Cargo.toml
[package]
name = "adder"
version = "0.1.0"
authors = ["Full Name <[email protected]>"]
[lib]
crate-type = ["cdylib"]
path = "lib.rs"
With options
{export: 'buffer'}
import wasmCode from "./lib.rs";
WebAssembly.compile(wasmCode).then(module => {
  const instance = new WebAssembly.Instance(module);
  console(instance.exports.add(1, 2)); // 3
});
{export: 'module'}
import wasmModule from "./lib.rs";
const instance = new WebAssembly.Instance(wasmModule);
console(instance.exports.add(1, 2)); // 3
{export: 'instance'}
import wasm from "./lib.rs";
console(wasm.exports.add(1, 2)); // 3
{export: 'async'}
extern {
    fn hook(c: i32);
}
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
    hook(a + b)
}
import wasmInstantiate from "./lib.rs";
wasmInstantiate(importObject | undefined).then(({ instance, module }) => {
  console(instance.exports.add(1, 2)); // 3
  // create different instance, extra will be called in different environment
  const differentInstance = new WebAssembly.Instance(module, {
    env: {
      hook: result => result * 2
    }
  });
  console(differentInstance.exports.add(1, 2)); // 6
});
{export: 'async-instance'}
import wasmInstantiate from "./lib.rs";
wasmInstantiate(importObject | undefined).then(instance => {
  console(instance.exports.add(1, 2)); // 3
});
{export: 'async-module'}
import wasmInstantiate from "./lib.rs";
wasmCompile(importObject | undefined).then(module => {
  const differentInstance = new WebAssembly.Instance(module);
  console(differentInstance.exports.add(1, 2)); // 3
});
You may also want to look at
Who use this?
- example-stencil-rust
- [add yours 😉]
Contributing
- CONTRIBUTING.md for how you can make contribution
- HACKING.md for technical details