diff --git a/examples/with-webassembly/.gitignore b/examples/with-webassembly/.gitignore new file mode 100644 index 00000000..a680367e --- /dev/null +++ b/examples/with-webassembly/.gitignore @@ -0,0 +1 @@ +.next diff --git a/examples/with-webassembly/Cargo.toml b/examples/with-webassembly/Cargo.toml new file mode 100644 index 00000000..0c537fa4 --- /dev/null +++ b/examples/with-webassembly/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "next-rust" +version = "0.1.0" +authors = ["Tim Neutkens "] + +[dependencies] diff --git a/examples/with-webassembly/add.wasm b/examples/with-webassembly/add.wasm new file mode 100755 index 00000000..f22496d0 Binary files /dev/null and b/examples/with-webassembly/add.wasm differ diff --git a/examples/with-webassembly/next.config.js b/examples/with-webassembly/next.config.js new file mode 100644 index 00000000..e38e5b21 --- /dev/null +++ b/examples/with-webassembly/next.config.js @@ -0,0 +1,6 @@ +module.exports = { + webpack (config) { + config.output.webassemblyModuleFilename = 'static/wasm/[modulehash].wasm' + return config + } +} diff --git a/examples/with-webassembly/package.json b/examples/with-webassembly/package.json new file mode 100644 index 00000000..b9e1daa5 --- /dev/null +++ b/examples/with-webassembly/package.json @@ -0,0 +1,13 @@ +{ + "dependencies": { + "next": "canary", + "react": "^16.4.2", + "react-dom": "^16.4.2" + }, + "scripts": { + "dev": "node server.js", + "build": "next build", + "build-rust": "rustc +nightly --target wasm32-unknown-unknown -O --crate-type=cdylib src/add.rs -o add.wasm", + "start": "NODE_ENV=production node server.js" + } +} diff --git a/examples/with-webassembly/pages/index.js b/examples/with-webassembly/pages/index.js new file mode 100644 index 00000000..62ef91df --- /dev/null +++ b/examples/with-webassembly/pages/index.js @@ -0,0 +1,24 @@ +import {withRouter} from 'next/router' +import dynamic from 'next/dynamic' +import Link from 'next/link' + +const RustComponent = dynamic({ + loader: async () => { + // Import the wasm module + const rustModule = await import('../add.wasm') + // Return a React component that calls the add_one method on the wasm module + return (props) =>
+ {rustModule.add_one(props.number)} +
+ } +}) + +const Page = ({router: {query}}) => { + const number = parseInt(query.number || 30) + return
+ + + +
+} + +export default withRouter(Page) diff --git a/examples/with-webassembly/readme.md b/examples/with-webassembly/readme.md new file mode 100644 index 00000000..f3de5b37 --- /dev/null +++ b/examples/with-webassembly/readme.md @@ -0,0 +1,48 @@ +[![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) + +# WebAssembly example + +## How to use + +### Using `create-next-app` + +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: + +```bash +npx create-next-app --example with-webassembly with-webassembly-app +# or +yarn create next-app --example with-webassembly with-webassembly-app +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-webassembly +cd with-webassembly +``` + +Install it and run: + +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. + +```bash +npm install +npm run dev +# or +yarn +yarn dev +``` + +To compile `src/add.rs` to `add.wasm` use `npm run build-rust`. + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) + +```bash +now +``` + +## The idea behind the example + +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. diff --git a/examples/with-webassembly/server.js b/examples/with-webassembly/server.js new file mode 100644 index 00000000..393bef32 --- /dev/null +++ b/examples/with-webassembly/server.js @@ -0,0 +1,25 @@ +const { createServer } = require('http') +const { parse } = require('url') +const next = require('next') + +const dev = process.env.NODE_ENV !== 'production' +const app = next({ dev }) +const handle = app.getRequestHandler() + +app.prepare().then(() => { + createServer((req, res) => { + // Be sure to pass `true` as the second argument to `url.parse`. + // This tells it to parse the query portion of the URL. + const parsedUrl = parse(req.url, true) + + // Set Content-Type to application/wasm for wasm files + if (parsedUrl.pathname.includes('/_next/static/wasm')) { + res.setHeader('Content-Type', 'application/wasm') + } + + handle(req, res, parsedUrl) + }).listen(3000, err => { + if (err) throw err + console.log('> Ready on http://localhost:3000') + }) +}) diff --git a/examples/with-webassembly/src/add.rs b/examples/with-webassembly/src/add.rs new file mode 100644 index 00000000..da5a5692 --- /dev/null +++ b/examples/with-webassembly/src/add.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn add_one(x: i32) -> i32 { + x + 1 +} \ No newline at end of file