Skip to content

Hello world (NW.js)

Chung Leong edited this page Mar 22, 2024 · 9 revisions

Creating the app

``sh mkdir hello cd hello npm init -y


```sh
npm install node-zigar
mkdir src zig
const std = @import("std");

pub fn hello() void {
    std.debug.print("Hello world!", .{});
}
require('node-zigar/cjs');
const { hello } = require('./zig/hello.zig');
console.log = (s) => process.stderr.write(`${s}\n`);
hello(); 

nw.Window.open('./src/index.html', { width: 800, height: 600 });
<!DOCTYPE html>
<html>
  <head>
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>
  "main": "src/index.js",

Configuring app for deployment

When you use require on a Zig file, node-zigar will place the resultant library file at a temporary location. At the root level of the app you will notice a zigar-cache sub-directory with the following structure:

📁 zigar-cache
  📁 zig-34cc0bd0
    📁 Debug
      📁 hello.zigar
        📑 linux.x64.so
      📁 node-zigar-addon
        📑 linux.x64.node

hello.zigar is a node-zigar module. It's a directory containing dynamic-link libraries for different platforms. node-zigar-addon is the Node.js native addon used to load node-zigar modules. It too comes in platform-specific versions.

The files in the cache directory aren't ones we want delivered to end-users. They're compiled at the Debug level and are therefore large and slow. Moreover, they only cover the platform we're using for development (Linux in this case) and not others (Windows and Mac).

To prepare our app for deployment, we first change the require statement so that it references a .zigar instead, stored at a more permanent location:

const { hello } = require('./lib/hello.zigar');

We then create a configure file for node-zigar with the help of its CLI script:

npx node-zigar init

node-zigar.config.json will be populated with some default options:

{
  "optimize": "ReleaseSmall",
  "sourceFiles": {},
  "targets": [
    {
      "platform": "linux",
      "arch": "x64"
    }
  ]
}

sourceFiles maps .zigar modules to source files. Paths are relative to the config file.

optimize can be Debug, ReleaseSafe, ReleaseSmall, or ReleaseFast.

targets is a list of cross-compile targets. platform and arch can be one of the possible values returned by os.platform and os.arch.

We insert the following into our config file:

{
  "optimize": "ReleaseSmall",
  "sourceFiles": {
    "lib/hello.zigar": "zig/hello.zig"
  },
  "targets": [
    { "platform": "win32", "arch": "x64" },
    { "platform": "win32", "arch": "arm64" },
    { "platform": "win32", "arch": "ia32" },
    { "platform": "linux", "arch": "x64" },
    { "platform": "linux", "arch": "arm64" },
    { "platform": "darwin", "arch": "x64" },
    { "platform": "darwin", "arch": "arm64" }
  ]
}

Then we ask node-zigar to create the necessary library files:

npx node-zigar build
Building hello.zigar:
  win32.x64.dll
  win32.arm64.dll
  win32.ia32.dll
  linux.x64.so
  linux.arm64.so
  darwin.x64.dylib
  darwin.arm64.dylib
Building node-zigar-addon:
  win32.x64.node
  win32.arm64.node
  win32.ia32.node
  linux.x64.node
  linux.arm64.node
  darwin.x64.node
  darwin.arm64.node

When the script completes, start the app again to confirm that it's correctly configured.

Clone this wiki locally