feat(build): adopt electron-vite for dev + build pipeline#228
Merged
CoderCoco merged 24 commits intoJun 3, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR switches the desktop app dev/build workflow to electron-vite, adding a dedicated Electron entrypoint and adjusting scripts so the desktop main/preload/renderer pipelines can be built and run under a single orchestrator.
Changes:
- Add
electron-viteat the workspace root and introducedesktop:dev/desktop:buildscripts. - Add a new Electron main-process entry (
electron-entry.ts) that creates theBrowserWindow, loads dev/prod renderer targets, and boots the NestJS IPC microservice. - Update desktop-main bootstrap flow (export
bootstrap()and adjust tests accordingly); add dedicated unit tests for the new Electron entry module.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds electron-vite and root desktop:* scripts. |
| package-lock.json | Locks electron-vite@5.0.0 and transitive deps. |
| electron.vite.config.ts | Defines electron-vite pipelines for main/preload/renderer. |
| CLAUDE.md | Documents the new desktop:dev / desktop:build commands. |
| app/eslint.config.js | Ignores **/out/** build output. |
| app/package.json | Replaces prior placeholder dev/start scripts with electron-vite commands. |
| app/packages/desktop-main/package.json | Updates desktop-main scripts to use electron-vite for dev/build entrypoints. |
| app/packages/desktop-main/src/main.ts | Exports bootstrap() and removes the module-level invocation. |
| app/packages/desktop-main/src/main.test.ts | Updates tests to call bootstrap() explicitly. |
| app/packages/desktop-main/src/electron-entry.ts | New Electron entry that wires preload, loads renderer, and starts IPC microservice. |
| app/packages/desktop-main/src/electron-entry.test.ts | Adds unit tests covering dev/prod loading and lifecycle behaviors. |
…s-platform optional packages npm 10 on Linux omitted optional platform packages for darwin/win32/android from the lockfile. npm 11 (Node 24, used by CI) requires them to be present for npm ci. Refs #144
electron-vite@5.0.0 requires ^20.19.0 || >=22.12.0. The previous >=20 allowed versions where electron-vite would refuse to run. Refs #144
Both files were fully commented out (no-ops) but still appeared as failed check runs on every PR push. Removing them cleans up the CI status view. Refs #144
--with-deps in a single step was hanging silently. Split into: - install-deps (DEBIAN_FRONTEND=noninteractive, 5min timeout) - install binary (5min timeout) Added job-level timeout-minutes: 20 so hung jobs fail fast. Refs #144
npx playwright install chromium hangs after download (extraction phase never exits). ubuntu-latest ships google-chrome-stable; use channel: 'chrome' in CI so Playwright picks it up with no download. Drops the browser binary install step from both e2e and integration workflows. Keeps install-deps for system library requirements. Refs #144
Ensures apt-get step can't hang silently — the job-level 20min cap remains as the overall ceiling. Refs #144
video: 'retain-on-failure' requires ffmpeg. Previously it was pulled in by 'npx playwright install chromium --with-deps' but we switched to system Chrome. Install ffmpeg explicitly (3min timeout). Refs #144
npx playwright install hangs post-download on ubuntu-latest regardless of binary size. Video is not needed in CI — traces retain-on-failure are sufficient for debugging. Locally video still records on failure. Refs #144
…on binary in tests
electron-store v11 imports electron at the top of its index.js, so any
require('electron-store') fails in plain-Node environments where the
electron binary hasn't been downloaded (e.g. integration test CI).
Switch the import to `import type` (type-only, no runtime effect) and
use createRequire inside createStore(), which is only called when
readIsElectron() returns true. Plain-Node paths continue to use the
in-memory Map fallback without ever loading electron-store.
Refs #144
…hs and stale docs - electron.vite.config.ts: renderer input was 'app/packages/web/index.html' which double-prefixed the root; change to 'index.html' (resolved relative to root) - app/package.json: add --config ../electron.vite.config.ts to dev; fix start to launch the built app instead of re-building it - app/packages/desktop-main/package.json: same --config fix at correct relative depth - CLAUDE.md: remove stale 'Nest on 3001 / http://localhost:3001' description; document that app:dev now launches the Electron desktop app Refs #144 Co-Authored-By: copilot-pull-request-reviewer (via PR comment)
typeof Store is invalid when Store is an import-type binding — TypeScript
treats it as a value reference even in type positions. Replace the cast
with typeof import('electron-store') which queries the module type directly.
Refs #144
Co-Authored-By: copilot-pull-request-reviewer (via PR comment)
void-ing the promise dropped renderer-load failures silently. Chain a .catch() that logs and calls app.quit(), consistent with the bootstrap failure path. Adds a unit test for the new rejection branch. Refs #144 Co-Authored-By: copilot-pull-request-reviewer (via PR comment)
…s to import.meta.url electron-store@11 is ESM-only — require() throws ERR_REQUIRE_ESM at runtime. Replace createRequire with a module-level conditional dynamic import guarded by process.versions.electron; plain-Node tests never trigger the import. All entrypoint/root paths in electron.vite.config.ts were relative strings resolved against cwd, breaking workspace invocations with --config. Anchor every path via fileURLToPath(new URL(p, import.meta.url)) so the config is cwd-independent. Refs #144 Co-Authored-By: copilot-pull-request-reviewer (via PR comment)
npm run app:build compiles TypeScript workspaces but does not run electron-vite, so out/main/index.js is never produced. app:start (electron out/main/index.js) therefore fails unless desktop:build ran first. Document the correct three-step production flow. Refs #144 Co-Authored-By: copilot-pull-request-reviewer (via PR comment)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #144
Summary
electron-vite ^5.0.0as the build orchestrator at the workspace root, replacing separatetsc -b/viteinvocations with a single three-pipeline build (main, preload, renderer)electron-entry.ts— the Electron app shell that creates theBrowserWindow, wires the preload script, loadsELECTRON_RENDERER_URLin dev (HMR) or the productionout/renderer/index.html, and starts the NestJS IPC microservice; bootstrap failures surface via.catch()+app.quit()instead of being silently swallowedbootstrap()frommain.tssoelectron-entry.tscontrols call timing; wiresdesktop:dev/desktop:buildscripts at root and removes Epic A placeholder stubsChanges
Test plan
npm run app:test)npm run app:lint)tsc --noEmit)electron-vite buildexits 0 and producesout/main,out/preload,out/renderernpm run desktop:devlaunches Electron with HMR on renderer saves🚀 Mission log
🤖 Generated via /mission