Skip to content

Hello world (Webpack)

Chung Leong edited this page Apr 27, 2024 · 1 revision

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 zigar-loader.

Create the app

First, we'll create our Node project. In a terminal window, run the following commands:

mkdir hello
cd hello
npm init -y

Next, we'll install React, Webpack, and Babel:

npm install --save-dev react react-dom\
    webpack webpack-cli webpack-dev-server css-loader style-loader html-webpack-plugin\
    @babel/core @babel/preset-env @babel/preset-react babel-loader http-server

Then we install zig-loader:

npm install --save-dev zigar-loader

We create one directory for JavaScript files and another for Zig files:

mkdir src zig

And place hello.zig in the latter:

const std = @import("std");

pub fn hello() void {
    std.debug.print("Hello world!", .{});
}

We create App.jsx in src:

import { hello } from '../zig/hello.zig';

function App() {
  return (
    <div className="App">
      <button onClick={() => hello()}>
        Say hello
      </button>
    </div>
  );
}

export default App

Then index.js:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

And finally index.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>WebPack + React + Zigar</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

We then create webpack.config.js:

const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.join(__dirname, '/dist'),
    filename: 'bundle.js',
  },
  plugins: [
    new htmlWebpackPlugin({
      template: 'src/index.html',
    }),
  ],
  devServer: {
    port: 3030,
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ],
      },
      {
        test: /\.zig$/,
        exclude: /node_modules/,
        use: 'zigar-loader',
      },
    ],
  },
};

And .babelrc for Babel:

{
  "presets": [
    "@babel/preset-env",
    [ "@babel/preset-react", { "runtime": "automatic" } ]
  ]
}

In package.json we add three commands:

  "scripts": {
    "dev": "webpack serve --mode development",
    "build": "webpack --mode production",
    "preview": "http-server ./dist"
  },

Run the dev command and open the link provided by webpack-dev-server:

npm run dev

Press Ctrl-Alt-I to open Chrome's development console. Click the button and verify that it causes a test message to appear. Close the browser and shut down webpack-dev-server when you're done.

Creating production build

Run the build command to build the app:

npm run build

Run the preview command and open the link provided:

npm run preview

Verify that the production build behaves the same.

Conclusion

You have just learned how you can easily make use of WebAssembly in your WebPack 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 sample.


SHA1 digest example