Home

Awesome

<div align="center"> <a href="https://github.com/rust-lang/rust"> <img height="200" alt="binaryen logo" src="https://www.rust-lang.org/logos/rust-logo-blk.svg"> </a> <a href="https://github.com/rollup/rollup"> <img height="200" alt="webpack logo" src="https://jestjs.io/img/jest.svg"> </a> </div>

npm size npm deps tests

<!-- [![cover][cover]][cover-url] -->

rs-jest

<sup><sup>tl;dr -- see examples</sup></sup>

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:

Requirements

<ul> <li>Node v8 or later</li> <li>Jest v23 or later</li> <li><details> <summary>Rust v1.28.0 with wasm32-uknown-unknown installed</summary>
rustup default 1.28.0
rustup target add wasm32-unknown-unknown
</details></li> </ul>

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:

<b>jest.config.js</b>

module.exports = {
  transform: {
    "^.+\\.rs$": "rs-jest"
  }
};

or if you prefer to put the config in <b>package.json</b>

  "jest": {
    "transform": {
      "^.+\\.rs$": "rs-jest"
    }
  }
<details> <summary>quick usage</summary>

<b>lib.rs</b>

#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

<b>index.js</b>

import wasm from "lib.rs";

export async function increment(a) {
  const { instance } = await wasm;
  return instance.exports.add(1, a);
}
</details>

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:

<details> <summary><b><code>export</code></b></summary>

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"
  }
}
</details> <details> <summary><b><code>target</code></b></summary>

The Rust target to use. Currently it only support wasm related target

{
  "globals": {
    "rs-jest": {
      "target": "wasm32-unknown-emscripten"
    }
  },
  "transform": {
    "^.+\\.rs$": "rs-jest"
  }
}
</details> <details> <summary><b><code>release</code></b></summary>

Whether to compile the Rust code in debug or release mode.

{
  "globals": {
    "rs-jest": {
      "release": false
    }
  },
  "transform": {
    "^.+\\.rs$": "rs-jest"
  }
}
</details>

Examples

See the test cases and example projects in fixtures and examples for more insight.

<details> <summary>The exported module are pretty much like <a href="https://github.com/DrSensor/rollup-plugin-rust">rollup-plugin-rust</a> so it can be used alongside with it</summary>

Given this Rust code

<b>lib.rs</b>

#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

<b>Cargo.toml</b>

[package]
name = "adder"
version = "0.1.0"
authors = ["Full Name <email@site.domain>"]

[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
});

</details>

You may also want to look at

Who use this?

Contributing

Credits


License

FOSSA Status