Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/DrSensor/rs-jest

Jest preprocessor/transformer for Rust
https://github.com/DrSensor/rs-jest

jest jest-transform my-experiment rust webassembly

Last synced: 2 months ago
JSON representation

Jest preprocessor/transformer for Rust

Lists

README

        



binaryen logo


webpack logo

[![npm][npm]][npm-url]
[![size][size]][size-url]
[![npm][npm-download]][npm-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]

# rs-jest

tl;dr -- see [examples](#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

    ```console
    rustup default 1.28.0
    rustup target add wasm32-unknown-unknown
    ```


## Getting Started

To begin, you'll need to install `rs-jest`:

```console
npm install rs-jest --save-dev
```

Then configure Jest to make `rs-jest` to transform the Rust (`*.rs`) file. For example:

jest.config.js

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

or if you prefer to put the config in
package.json

```json
"jest": {
"transform": {
"^.+\\.rs$": "rs-jest"
}
}
```

quick usage

lib.rs

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

index.js

```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][webassembly-loader]. (see [examples](#examples))

```json
{
"globals": {
"rs-jest": {
"export": "instance"
}
},
"transform": {
"^.+\\.rs$": "rs-jest"
}
}
```

target

- Type: `String`
- Default: `wasm32-unknown-unknown`
- Expected value: see [supported platform](https://forge.rust-lang.org/platform-support.html)

The Rust target to use. Currently it **only support [wasm related target](https://kripken.github.io/blog/binaryen/2018/04/18/rust-emscripten.html)**

```json
{
"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.

```json
{
"globals": {
"rs-jest": {
"release": false
}
},
"transform": {
"^.+\\.rs$": "rs-jest"
}
}
```

## Examples

See the test cases and example projects in [fixtures](./test/fixtures) and [examples](./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

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

Cargo.toml

```toml
[package]
name = "adder"
version = "0.1.0"
authors = ["Full Name "]

[lib]
crate-type = ["cdylib"]
path = "lib.rs"
```

### With options

#### `{export: 'buffer'}`

```js
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'}`

```js
import wasmModule from "./lib.rs";

const instance = new WebAssembly.Instance(wasmModule);
console(instance.exports.add(1, 2)); // 3
```

---

#### `{export: 'instance'}`

```js
import wasm from "./lib.rs";

console(wasm.exports.add(1, 2)); // 3
```

---

#### `{export: 'async'}`

```rust
extern {
fn hook(c: i32);
}

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

```js
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'}`

```js
import wasmInstantiate from "./lib.rs";

wasmInstantiate(importObject | undefined).then(instance => {
console(instance.exports.add(1, 2)); // 3
});
```

---

#### `{export: 'async-module'}`

```js
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

- [rollup-plugin-rust](https://github.com/DrSensor/rollup-plugin-rust)
- [webassembly-loader](https://github.com/DrSensor/webassembly-loader) + [rust-native-wasm-loader](https://github.com/dflemstr/rust-native-wasm-loader)

## Who use this?

- [example-stencil-rust](https://github.com/DrSensor/example-stencil-rust)
- [add yours 😉]

## Contributing

- [CONTRIBUTING.md](./.github/CONTRIBUTING.md) for how you can make contribution
- [HACKING.md](./.github/HACKING.md) for technical details

## Credits

- [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter)
- [webpack-defaults](https://github.com/webpack-contrib/webpack-defaults)

---

## License

[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FDrSensor%2Frs-jest.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FDrSensor%2Frs-jest?ref=badge_large)

[ts-jest]: https://github.com/kulshekhar/ts-jest/
[webassembly-loader]: https://github.com/DrSensor/webassembly-loader#export
[npm]: https://img.shields.io/npm/v/rs-jest.svg
[npm-url]: https://npmjs.com/package/rs-jest
[npm-download]: https://img.shields.io/npm/dm/rs-jest.svg
[deps]: https://david-dm.org/DrSensor/rs-jest.svg
[deps-url]: https://david-dm.org/DrSensor/rs-jest
[tests]: https://img.shields.io/circleci/project/github/DrSensor/rs-jest.svg
[tests-url]: https://circleci.com/gh/DrSensor/rs-jest
[cover]: https://codecov.io/gh/DrSensor/rs-jest/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/DrSensor/rs-jest
[size]: https://packagephobia.now.sh/badge?p=rs-jest
[size-url]: https://packagephobia.now.sh/result?p=rs-jest