Deployment - chung-leong/zigar GitHub Wiki

Sider-side code

node-zigar and bun-zigar allow you to import functions from .zig files:

import { tar, startup, shutdown } from '../zig/tar.zig';

This feature is designed to make Zig more approachable to JavaScript programmers. It mimicks the behavior of JavaScript, where modules and their source files are one and the same. To know which file to edit, you just need to look at the import statement.

Of course, Zig is not a scripting language. Compilation happens ahead of time and not just-in-time. Modules are binary files containing machine instructions. They're dynamically loaded libraries (.dll in Windows, .so in Linux, and .dynlib in MacOS). While it's convenient during development to treat .zig files like .js, at some point we have to stop the pretense.

When a JavaScript + Zig application is deployed onto a server, the .js files are needed along with the libraries generated from Zig source code. The .zig files themselves are not need on the server. Import statements in JavaScript need to be updated beforehand to avoid a situation where we have references in our code pointing to non-existing files.

Zigar gives you two options. An import statement can point to a .zigar module directory:

import { tar, startup, shutdown } from '../lib/tar.zigar';

Or it can point to a standalone loader that loads that particular module:

import { tar, startup, shutdown } from './tar.js';

The first approach has the advantage that the module get recompiled automatically when the source code changes. It's more convenient when your Zig code experiences continual development.

The second approach has the advantage of freeing your app from dependency on node-zigar at runtime. The command-line flag --loader=node-zigar would no longer be required. It also gives you the option of running your app in other JavaScript runtimes like Deno and Bun.

Use the second approach when you plan to share your project on npm.

In both cases you use the node-zigar (or bun-zigar) CLI tool to build the libraries:

npx node-zigar build

You'd likely want to add an script entry in package.json for this purpose:

  "scripts": {
    "build": "node-zigar build"
  },

The config file node-zigar.config.json must be present in the project directory. You can create a barebone copy with the following command:

npx node-zigar init

The key setting is modules. It maps modules to their source files and let you specify the location of the standalone loader if you choose to use one.

Client-side code

Client-side JavaScript code always undergoes a transform before execution, even during development, so there's no need to adjust import statements. rollup-plugin-zigar or zigar-loader, once configured, will do the adjustments for you, handing the correct module loading code to Rollup/WebPack.

Zig code that uses threads introduces one deployment complication: the web page must be cross-origin isolated. The following HTTP header must accompany the response:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

In practice, this means you cannot deploy your app on many free web-hosting services, with GitHub pages being a prime example. Luckily, Cloudflare's free tier does allow the addition of custom HTTP headers. Simply put a file by the name of _headers at the root level with the following rule:

/*
  Cross-Origin-Opener-Policy: same-origin
  Cross-Origin-Embedder-Policy: require-corp

This project's web-site along with all its demos are hosted there.