WU / DOCSUNIVERSAL MICROFRONTENDS
EN

CLI internals

Zig dispatcher, configuration, servers, compilation, HMR, ownership, and contribution tests.

Following an invocation

The npm launcher identifies the platform and executes the binary. main.zig receives arguments and dispatches the first token to a command module. Each command decides how to interpret the remainder, which is why there is no uniform global flag grammar.

Project commands obtain a WuConfig structure from the loader. This configuration stores its strings in its own arena and exposes deinit to free its memory. This prevents returning views into an already-freed JSON buffer. Discovery is an alternative configuration source, not a step that is always merged with an explicit file.

Module map

Source path Responsibility
src/main.zig Dispatcher, version, and Zig test aggregator
src/cli/ Help, banner, terminal mode, menus, and prompts
src/config/config.zig Configuration parsing and writing
src/config/discovery.zig Project heuristics in subdirectories
src/config/deps.zig Consumption of aliases and local toolchains
src/commands/ Use cases and artifact generation
src/runtime/dev_server.zig Listener, routes, modules, and reload bridge
src/runtime/compile.zig Compiler selection and daemon connection
src/runtime/compiler_daemon.js Node compilers and message framing
src/runtime/transform.zig Import, alias, and CSS rewriting
src/runtime/hypervisor/ Watcher and prefix router
src/runtime/security.zig Path validation and HTTP policy
src/orchestrator/ Vite development processes and supervision
src/util/jobobject.zig Child-process lifecycle on Windows

The presence of src/proxy/server.zig or src/commands/test.zig does not prove they are a command’s active path. To establish that, start at the dispatcher and follow calls instead of inferring capabilities from filenames.

src/runtime/dev/ separates routes, files, imports, CSS, environment, sockets and HMR. module_graph.zig maintains identity and importer-based resolution; project_fs.zig contains file access. catalog.zig, semver.zig and json_doc.zig centralize versions, intersections and manifest writing. deploy.zig and build_cache.zig implement transactional local output replacement and build reuse.

Server and compiler

A request arrives over HTTP, is validated, assigned to an app or the shell, and resolved to a file or dependency. Compilation produces JavaScript; imports are then adapted to the server URLs. App identity must accompany the entire flow to resolve its dependencies, styles, and toolchain.

The daemon maintains a channel over pipes. Requests carry an identifier, compilation type, file, loader, length, and app directory. The response repeats the identifier and transmits code or an error. Lengths frame the content; errors are reduced to a single protocol line.

The protocol multiplexes requests by identifier. compile_pool.zig manages multiple daemons with deadlines and compile_warmup.zig precompiles imports; Angular reuses its incremental compiler. The VFS, previous transform pool and disabled native JSX transformer were removed.

The daemon’s standard output belongs to the protocol. Accidental plugin messages can desynchronize it; the daemon redirects several console levels to its log. The parent checks the response identifier and restarts a desynchronized conversation.

Watcher and router

The hypervisor registers app prefixes in a router and watches project directories. It integrates file-event mechanisms and content caches. Its ownership requires care: when returning the server by value, pointers to internal fields must be bound to the final location. bindRunning handles this lifecycle relationship.

The server coordinates shutdown, connection closure, and the daemon. On Windows, Job Objects help prevent child processes from outliving their owner. This feature requires tests on the real operating system; inspecting code is not equivalent to observing process cleanup on every platform.

Building and testing a change

zig build
zig build test --summary all
npm test

build.zig defines Zig build and test steps. npm test runs the invariants in scripts/check-invariants.mjs and the tests/*.test.cjs files, which check the launcher, daemon protocol, and contracts such as doctor output. Run tests against the binary you just built. The summary shows how many cases ran and which were skipped; browser tests are still needed to validate generated apps.

main.zig explicitly imports modules with tests; invariants check the aggregator and command reference. npm run test:fuzz exercises HTTP, WebSocket, path, JSON, SemVer and import parsers. Releases use ReleaseSafe, checksums and reproducible rebuilds.

For protocol changes, test fragmented messages, multiple requests in one chunk, long errors, and mismatched identifiers. Scaffold changes require generation, compilation, and browser mounting. HTTP changes require testing routes, methods, missing assets, and final response headers.

Implementation references

  • wu-cli/src/main.zig
  • wu-cli/src/runtime/dev/
  • wu-cli/src/runtime/compile_pool.zig
  • wu-cli/src/runtime/compiler_daemon.js
  • wu-cli/src/runtime/module_graph.zig
  • wu-cli/src/runtime/project_fs.zig
  • wu-cli/src/commands/deploy.zig
  • wu-cli/scripts/check-invariants.mjs
  • wu-cli/src/fuzz.zig
BUILD WU WITH US

Found a bug? Have an idea?

Your experience improves WU. Tell us what went wrong or help support its development.