Skip to content

Commit ee3a73f

Browse files
committedSep 17, 2018
Add WebAssembly example
1 parent 200ba0d commit ee3a73f

File tree

9 files changed

+127
-0
lines changed

9 files changed

+127
-0
lines changed
 

‎examples/with-webassembly/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.next

‎examples/with-webassembly/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "next-rust"
3+
version = "0.1.0"
4+
authors = ["Tim Neutkens <timneutkens@me.com>"]
5+
6+
[dependencies]

‎examples/with-webassembly/add.wasm

126 Bytes
Binary file not shown.
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
webpack (config) {
3+
config.output.webassemblyModuleFilename = 'static/wasm/[modulehash].wasm'
4+
return config
5+
}
6+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"dependencies": {
3+
"next": "canary",
4+
"react": "^16.4.2",
5+
"react-dom": "^16.4.2"
6+
},
7+
"scripts": {
8+
"dev": "node server.js",
9+
"build": "next build",
10+
"build-rust": "rustc +nightly --target wasm32-unknown-unknown -O --crate-type=cdylib src/add.rs -o add.wasm",
11+
"start": "NODE_ENV=production node server.js"
12+
}
13+
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {withRouter} from 'next/router'
2+
import dynamic from 'next/dynamic'
3+
import Link from 'next/link'
4+
5+
const RustComponent = dynamic({
6+
loader: async () => {
7+
// Import the wasm module
8+
const rustModule = await import('../add.wasm')
9+
// Return a React component that calls the add_one method on the wasm module
10+
return (props) => <div>
11+
{rustModule.add_one(props.number)}
12+
</div>
13+
}
14+
})
15+
16+
const Page = ({router: {query}}) => {
17+
const number = parseInt(query.number || 30)
18+
return <div>
19+
<RustComponent number={number} />
20+
<Link href={`/?number=${number + 1}`}><a>+</a></Link>
21+
</div>
22+
}
23+
24+
export default withRouter(Page)

‎examples/with-webassembly/readme.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/hello-world)
2+
3+
# WebAssembly example
4+
5+
## How to use
6+
7+
### Using `create-next-app`
8+
9+
Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
10+
11+
```bash
12+
npx create-next-app --example with-webassembly with-webassembly-app
13+
# or
14+
yarn create next-app --example with-webassembly with-webassembly-app
15+
```
16+
17+
### Download manually
18+
19+
Download the example:
20+
21+
```bash
22+
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-webassembly
23+
cd with-webassembly
24+
```
25+
26+
Install it and run:
27+
28+
This example uses Rust compiled to wasm, the wasm file is included in the example, but to compile your own Rust code you'll have to [install](https://www.rust-lang.org/en-US/) Rust.
29+
30+
```bash
31+
npm install
32+
npm run dev
33+
# or
34+
yarn
35+
yarn dev
36+
```
37+
38+
To compile `src/add.rs` to `add.wasm` use `npm run build-rust`.
39+
40+
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
41+
42+
```bash
43+
now
44+
```
45+
46+
## The idea behind the example
47+
48+
This example shows how to import WebAssembly files (`.wasm`) and use them inside of a React component that is server rendered. So the WebAssembly code is executed on the server too. In the case of this example we're showing Rust compiled to WebAssembly.

‎examples/with-webassembly/server.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const { createServer } = require('http')
2+
const { parse } = require('url')
3+
const next = require('next')
4+
5+
const dev = process.env.NODE_ENV !== 'production'
6+
const app = next({ dev })
7+
const handle = app.getRequestHandler()
8+
9+
app.prepare().then(() => {
10+
createServer((req, res) => {
11+
// Be sure to pass `true` as the second argument to `url.parse`.
12+
// This tells it to parse the query portion of the URL.
13+
const parsedUrl = parse(req.url, true)
14+
15+
// Set Content-Type to application/wasm for wasm files
16+
if (parsedUrl.pathname.includes('/_next/static/wasm')) {
17+
res.setHeader('Content-Type', 'application/wasm')
18+
}
19+
20+
handle(req, res, parsedUrl)
21+
}).listen(3000, err => {
22+
if (err) throw err
23+
console.log('> Ready on http://localhost:3000')
24+
})
25+
})

‎examples/with-webassembly/src/add.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[no_mangle]
2+
pub extern "C" fn add_one(x: i32) -> i32 {
3+
x + 1
4+
}

0 commit comments

Comments
 (0)
Please sign in to comment.