Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# @prettier
version: 2

rustup_nightly: &rustup_nightly
run:
name: Install Cargo and Rust compiler
command: |
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> $BASH_ENV
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.28.0
source $BASH_ENV
rustup target add wasm32-unknown-unknown

unit_tests: &unit_tests
steps:
- checkout
Expand All @@ -16,6 +25,29 @@ unit_tests: &unit_tests
name: Run unit tests.
command: npm run ci:test

smoke_tests: &smoke_tests
steps:
- checkout
- restore_cache:
key: dependency-cache-{{ checksum "package-lock.json" }}
- <<: *rustup_nightly #TODO: replace this when CircleCI can make steps reusable in multiple jobs
- run:
name: NPM Rebuild
command: npm install --quiet
- run:
name: Build & Bundle project
command: npm run build
- run:
name: NPM install dependencies for smoke-test
command: |
cd examples/${EXAMPLE_PROJECT}
npm install
- run:
name: Run smoke tests
command: |
cd examples/${EXAMPLE_PROJECT}
npm run build

jobs:
#region PREPARATION
dependency_cache:
Expand Down Expand Up @@ -87,6 +119,15 @@ jobs:
<<: *unit_tests
#endregion

#region TEST BY EXAMPLES
smoke-rust-vue:
docker:
- image: circleci/node:latest
environment:
- EXAMPLE_PROJECT: rust/vue
<<: *smoke_tests
#endregion

#region RELEASE VERSION
draft:
docker:
Expand Down Expand Up @@ -162,6 +203,15 @@ workflows:
only: /.*/
#endregion

#region TEST BY EXAMPLES
- smoke-rust-vue:
requires:
- node8-latest
filters:
tags:
only: /.*/
#endregion

#region RELEASE VERSION
- draft:
requires:
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# ( ͡° ͜ʖ ͡°)
.utopian/
.NOTE.md

# Generated folder
types/
dist/
.rpt2_cache/

# Rust
*.lock
**/target/
Expand Down
120 changes: 120 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
## Options

### `export`
How wasm code would be exported. (see [examples](#examples))
- Type: `string`
- Default: `async`
- Expected value:
- `buffer` will export wasm code as [Buffer][]
- `module` will export wasm code as [WebAssembly.Module][]
- `instance` will export wasm code as [WebAssembly.Instance][]
- `async` will [instantiate][webassembly.instantiate] wasm code asynchronously, return promise of both [WebAssembly.Module][] and [WebAssembly.Instance][]
- `async-module` will [compile][webassembly.compile] wasm code asynchronously, return promise of [WebAssembly.Module][]
- `async-instance` will [instantiate][webassembly.instantiate] wasm code asynchronously, return promise of [WebAssembly.Instance][]

<details><summary><i>webpack.config.js</i></summary>

```js
module.exports = {
rules: [{
test: /\.wasm$/,
type: "javascript/auto",
use: [{
loader: "webassembly-loader",
options: {
export: "async"
}
}]
}]
}
```
</details>

> tips: you can use [query parameter][inline] to change export mode on demand

[inline]: https://webpack.js.org/concepts/loaders/#inline
[buffer]: https://nodejs.org/api/buffer.html
[webassembly.module]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module
[webassembly.instance]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance
[webassembly.instantiate]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate
[webassembly.compile]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile

## Examples

See the test cases and example projects in [*.test.ts](./test) and [examples](./examples/) for more insight.

### With options

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

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

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.wasm";

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

---

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

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

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

---

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

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

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);
console(differentInstance.exports.add(1, 2)); // 6
});
```

---

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

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

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

---

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

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

wasmCompile(importObject | undefined).then(module => {
const differentInstance = new WebAssembly.Instance(module);
console(differentInstance.exports.add(1, 2)); // 3
});
```
---
25 changes: 25 additions & 0 deletions examples/rust/vue/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package-lock.json
*.lock

.DS_Store
node_modules
/dist
/target

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
12 changes: 12 additions & 0 deletions examples/rust/vue/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "vue"
version = "0.1.0"
authors = ["Fahmi Akbar Wildana <fahmi.a.w@gmail.com>"]

[lib]
crate-type = ["cdylib"]

[profile.release]
lto = true

[dependencies]
16 changes: 16 additions & 0 deletions examples/rust/vue/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# vue

## Project setup
```
npm install
```

### Compiles and hot-reloads for development
```
npm run serve
```

### Compiles and minifies for production
```
npm run build
```
24 changes: 24 additions & 0 deletions examples/rust/vue/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "vue",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"vue": "^2.5.17"
},
"devDependencies": {
"@vue/cli-service": "^3.0.1",
"rust-native-wasm-loader": "^0.8.1",
"vue-template-compiler": "^2.5.17",
"webassembly-loader": "file:../../.."
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": ["> 1%", "last 2 versions", "not ie <= 8"]
}
13 changes: 13 additions & 0 deletions examples/rust/vue/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vue</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
24 changes: 24 additions & 0 deletions examples/rust/vue/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<div id="app">
{{add(1,2)}}
</div>
</template>

<script>
import wasmInstance from "./lib.rs";

export default {
name: "app",
methods: {
//#region TODO: use 👇 to create svelte-preprocessor for rustwasm (hint: register that as a {helpers})
...Object.keys(wasmInstance.exports).reduce((r, e) => {
if (typeof wasmInstance.exports[e] === "function")
r[e] = wasmInstance.exports[e];
return r;
}, {})
//#endregion

// add: wasmInstance.exports.add /*👈🙅 because it's to mainstream 😆*/
}
};
</script>
4 changes: 4 additions & 0 deletions examples/rust/vue/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
8 changes: 8 additions & 0 deletions examples/rust/vue/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Vue from 'vue';
import App from './App.vue';

Vue.config.productionTip = false;

new Vue({
render: h => h(App)
}).$mount('#app');
25 changes: 25 additions & 0 deletions examples/rust/vue/vue.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
configureWebpack: {
module: {
rules: [
{
test: /\.rs$/,
use: [
{
loader: "webassembly-loader",
options: {
export: "instance"
}
},
{
loader: "rust-native-wasm-loader",
options: {
release: true
}
}
]
}
]
}
}
}
23 changes: 2 additions & 21 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
module.exports = {
testEnvironment: "node",
globals: {
"ts-jest": {
babelConfig: true
}
},
transform: {
"^.+\\.tsx?$": "ts-jest"
},
testPathIgnorePatterns: [
"<rootDir>/test/fixtures",
"<rootDir>/node_modules/",
"<rootDir>/packages/"
],
coveragePathIgnorePatterns: [
".*\\.d\\.ts",
"<rootDir>/node_modules/",
"<rootDir>/packages/"
],
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
preset: "ts-jest",
testMatch: null
preset: "ts-jest/presets/js-with-ts",
globalSetup: "./jest.setup.js"
}
Loading