-
Notifications
You must be signed in to change notification settings - Fork 3
Hello world (Vite)
In this example we're going to create a very simple web app that outputs "Hello world!" to the console through Zig. It demonstrates the basics of working with rollup-plugin-zigar.
First, we'll create a boilerplate app. In a terminal window, run the following command:
npm create vite@latest
Enter hello
as name, and select React
and JavaScript + SWC
:
Need to install the following packages:
[email protected]
Ok to proceed? (y) y
✔ Project name: … hello
✔ Select a framework: › React
✔ Select a variant: › JavaScript + SWC
Once the project is created, go into its directory and install the necessary files:
cd hello
npm install
Next, install the Zigar plugin:
npm install --save-dev rollup-plugin-zigar
Create a sub-directory for zig code:
mkdir zig
And add hello.zig
:
const std = @import("std");
pub fn hello() void {
std.debug.print("Hello world!", .{});
}
In a text editor, open vite.config.js
and insert the plugin:
import react from '@vitejs/plugin-react-swc';
import zigar from 'rollup-plugin-zigar'; // <---
import { defineConfig } from 'vite';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [ react(), zigar() ], // <---
})
Add an import statement to App.jsx
and change the button handler so that it calls hello()
every time the button is clicked:
import { useState } from 'react'
import { hello } from '../zig/hello.zig' // <---
import './App.css'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
function App() {
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => hello()}>{/* <--- */}
Say hello
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App
Finally, start Vite in dev mode:
npm run dev
VITE v5.1.6 ready in 329 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
Open the link shown onscreen in Chrome. Press Ctrl-Shift-I to open Chrome's development console. The text message should appear there every time you click the button.
Now, let us test Vite's Hot Module Replacement feature. In the development console, change
the display level to Verbose
:
Switch to your text editor and change the message in hello.zig
. When you return to Chrome, you
should see a notification in the development console:
Run the usual command to build the app:
npm run build
Most likely you will encounter the following error:
Error: [vite:esbuild-transpile] Transform failed with 1 error:
assets/index-!~{001}~.js:3130:0: ERROR: Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides)
As of April 2024, support for top-level await is still not wide-spread enough for it be safely assumed. To work around this issue, we need to change the settings for rollup-plugin-zigar:
export default defineConfig({
plugins: [react(), zigar({ topLevelAwait: false })],
})
Run the build command again. It will succeed this time. With top-level await switched off, our
hello
function can potentially be asynchronous momentarily (in the breif moment it takes to
compile the WASM bytecodes). It's not a problem in this example, since we don't care about the
return value.
FYI: According to caniuse.com, support for top-level await is available starting from Chrome 89, Edge 89, Firefox 89, and Safari 15.
To verify that the production code does in fact work, start Vite in preview mode:
npm run preview
And check the app once more in Chrome.
You can find the complete source code for this example here.
You have just learned how you can easily make use of WebAssembly in your Vite project with the help of Zig and Zigar. The app we built in this example doesn't do anything. Our code will do something more useful in the next example.