#21089: fix(ui): externalize all Node builtins in Vite build
app: web-ui
gateway
size: S
Cluster:
UI Improvements and Fixes
## Summary
- The control UI Vite build fails because server-side code (`logging/logger.ts`, `media/image-ops.ts`, etc.) is transitively imported by shared modules used in the UI
- Vite auto-externalizes most `node:*` builtins but misses `node:module`, causing a hard error when `createRequire` is encountered
- Adds all Node builtins to `build.rollupOptions.external` so Rollup emits empty shims instead of erroring
## Root cause
Recent refactors (shared helpers across logging, media, plugins) pulled server-side imports deeper into the dependency graph of modules shared with the UI. `node:fs`, `node:path`, etc. produce warnings but work; `node:module` (`createRequire`) causes a hard failure because Vite's browser-external shim doesn't provide it.
## Test plan
- [x] `pnpm run ui:build` succeeds (301 modules, built in ~1s)
- [x] `pnpm run lint` passes (0 warnings, 0 errors)
- [x] No change to runtime behavior — only affects the Vite browser build externalization
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed Vite browser build failure by externalizing all Node built-in modules (including `node:module` which exports `createRequire`), preventing hard errors when server-side imports are transitively pulled into the UI bundle. Also fixed macOS launchd EPERM errors by falling back to `/tmp/openclaw` for log paths when the state directory resolves to a removable volume under `/Volumes`.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- Both fixes are targeted, well-tested, and address specific build/runtime failures. The Vite externalization approach is standard practice for preventing browser builds from including Node.js code. The launchd fallback logic is defensive and properly tested with comprehensive test coverage including mocking and platform-specific guards.
- No files require special attention
<sub>Last reviewed commit: a6c497d</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#7824: fix(ui): remove --prod install flag that causes vite not found error
by adityarao3 · 2026-02-03
77.5%
#9628: fix: resolve tsconfig rootDir errors by separating UI config (AI-as...
by KGBos · 2026-02-05
77.0%
#7023: feat(ui): inject build SHA fingerprint into index.html
by sergi039 · 2026-02-02
74.8%
#13176: fix: resolve llm-task module import for global installs
by striking · 2026-02-10
72.6%
#17393: fix(ci): resolve TS2742 type error blocking all PRs
by miloudbelarebia · 2026-02-15
72.4%
#20843: docs: add troubleshooting for A2UI bundling and missing node_modules
by yahiag04 · 2026-02-19
71.9%
#21500: fix(test): resolve vi.mock hoisting failures on macOS runners
by irchelper · 2026-02-20
70.9%
#8644: Fix Control UI asset resolution for global installs
by codvik · 2026-02-04
70.6%
#11980: CLI: add external message lint + warn on tables/mentions
by moestradamos · 2026-02-08
70.3%
#8988: fix: resolve security vulnerabilities in dependencies
by fotorpics · 2026-02-04
70.3%