Skip to content

Commit

Permalink
Fix with-webassembly example and convert to Typescript (#43677)
Browse files Browse the repository at this point in the history
- Fixes `with-webassembly` example unable to build with the current
`next.config.js`.
#29362 (comment)
- Converted example to TypeScript

```js
// Before
config.output.webassemblyModuleFilename = 'static/wasm/[modulehash].wasm'

// After
config.output.webassemblyModuleFilename =
  isServer && !dev
    ? '../static/wasm/[modulehash].wasm'
    : 'static/wasm/[modulehash].wasm'
```

```
> Build error occurred
Error: Export encountered errors on following paths:
        /
    at /Users/max/dev/next.js/examples/with-webassembly/node_modules/next/dist/export/index.js:408:19
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Span.traceAsyncFn (/Users/max/dev/next.js/examples/with-webassembly/node_modules/next/dist/trace/trace.js:79:20)
    at async /Users/max/dev/next.js/examples/with-webassembly/node_modules/next/dist/build/index.js:1342:21
    at async Span.traceAsyncFn (/Users/max/dev/next.js/examples/with-webassembly/node_modules/next/dist/trace/trace.js:79:20)
    at async /Users/max/dev/next.js/examples/with-webassembly/node_modules/next/dist/build/index.js:1202:17
    at async Span.traceAsyncFn (/Users/max/dev/next.js/examples/with-webassembly/node_modules/next/dist/trace/trace.js:79:20)
    at async Object.build [as default] (/Users/max/dev/next.js/examples/with-webassembly/node_modules/next/dist/build/index.js:65:29)
 ELIFECYCLE  Command failed with exit code 1.
```

## Documentation / Examples

- [X] Make sure the linting passes by running `pnpm build && pnpm lint`
- [X] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
  • Loading branch information
maxproske committed Dec 12, 2022
1 parent ce0bcd3 commit bfd96ac
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 43 deletions.
2 changes: 2 additions & 0 deletions examples/with-webassembly/README.md
Expand Up @@ -32,4 +32,6 @@ To compile `src/add.rs` to `add.wasm` run:
npm run build-rust
# or
yarn build-rust
# or
pnpm build-rust
```
24 changes: 24 additions & 0 deletions examples/with-webassembly/components/RustComponent.tsx
@@ -0,0 +1,24 @@
import type { AddModuleExports } from '../wasm'
import dynamic from 'next/dynamic'

interface RustComponentProps {
number: Number
}

const RustComponent = dynamic({
loader: async () => {
// Import the wasm module
// @ts-ignore
const exports = (await import('../add.wasm')) as AddModuleExports
const { add_one: addOne } = exports

// Return a React component that calls the add_one method on the wasm module
return ({ number }: RustComponentProps) => (
<div>
<>{addOne(number)}</>
</div>
)
},
})

export default RustComponent
13 changes: 10 additions & 3 deletions examples/with-webassembly/next.config.js
@@ -1,11 +1,18 @@
/** @type {import('next').NextConfig} */
module.exports = {
webpack(config) {
config.output.webassemblyModuleFilename = 'static/wasm/[modulehash].wasm'
const nextConfig = {
webpack(config, { isServer, dev }) {
// Use the client static directory in the server bundle and prod mode
// Fixes `Error occurred prerendering page "/"`
config.output.webassemblyModuleFilename =
isServer && !dev
? '../static/wasm/[modulehash].wasm'
: 'static/wasm/[modulehash].wasm'

// Since Webpack 5 doesn't enable WebAssembly by default, we should do it manually
config.experiments = { ...config.experiments, asyncWebAssembly: true }

return config
},
}

module.exports = nextConfig
16 changes: 11 additions & 5 deletions examples/with-webassembly/package.json
@@ -1,14 +1,20 @@
{
"private": true,
"dependencies": {
"next": "latest",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"scripts": {
"dev": "next",
"build": "next build",
"build-rust": "rustc --target wasm32-unknown-unknown -O --crate-type=cdylib src/add.rs -o add.wasm",
"start": "next start"
},
"dependencies": {
"next": "latest",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^18.11.10",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"typescript": "^4.9.3"
}
}
11 changes: 0 additions & 11 deletions examples/with-webassembly/pages/api/edge.js

This file was deleted.

16 changes: 16 additions & 0 deletions examples/with-webassembly/pages/api/edge.ts
@@ -0,0 +1,16 @@
import type { AddModuleExports } from '../../wasm'
// @ts-ignore
import addWasm from '../../add.wasm?module'

const module$ = WebAssembly.instantiate(addWasm)

export default async function handler() {
const instance = (await module$) as any
const exports = instance.exports as AddModuleExports
const { add_one: addOne } = exports
const number = addOne(10)

return new Response(`got: ${number}`)
}

export const config = { runtime: 'experimental-edge' }
24 changes: 0 additions & 24 deletions examples/with-webassembly/pages/index.js

This file was deleted.

15 changes: 15 additions & 0 deletions examples/with-webassembly/pages/index.tsx
@@ -0,0 +1,15 @@
import { useRouter } from 'next/router'
import Link from 'next/link'
import RustComponent from '../components/RustComponent'

export default function Page() {
const { query } = useRouter()
const number = parseInt(query.number as string) || 30

return (
<div>
<RustComponent number={number} />
<Link href={`/?number=${number + 1}`}>+</Link>
</div>
)
}
20 changes: 20 additions & 0 deletions examples/with-webassembly/tsconfig.json
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "wasm.d.ts"],
"exclude": ["node_modules"]
}
3 changes: 3 additions & 0 deletions examples/with-webassembly/wasm.d.ts
@@ -0,0 +1,3 @@
export interface AddModuleExports {
add_one(number: Number): Number
}

0 comments on commit bfd96ac

Please sign in to comment.