Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions apps/desktop/scripts/dev.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,12 +20,12 @@ import { existsSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { createServer } from 'vite';
import { build as esbuildBuild } from 'esbuild';

const DESKTOP_DIR = resolve(fileURLToPath(new URL('..', import.meta.url)));
const REPO_ROOT = resolve(DESKTOP_DIR, '..', '..');
const ON_WINDOWS = process.platform === 'win32';
const TSC_CLI = join(REPO_ROOT, 'node_modules', 'typescript', 'bin', 'tsc');
const ESBUILD_CLI = join(REPO_ROOT, 'node_modules', 'esbuild', 'bin', 'esbuild');

// ── helpers ──────────────────────────────────────────────────────────────────

Expand DownExpand Up@@ -71,7 +71,20 @@ await Promise.all([
() => log('build', 'libraries (all) — done'),
(e) => { log('build', `libraries — FAILED: ${e.message}`); throw e; },
),
runNodeTool(DESKTOP_DIR, ESBUILD_CLI, ['src/preload/preload.ts', '--bundle', '--platform=node', '--format=cjs', '--outfile=dist/preload/preload.cjs', '--external:electron']).then(
// esbuild via its JS API — NOT `node node_modules/esbuild/bin/esbuild`:
// esbuild's postinstall swaps that file for a platform-native binary,
// and executing a Mach-O file with node throws SyntaxError (broke
// `npm run dev` on any machine where postinstall ran).
esbuildBuild({
absWorkingDir: DESKTOP_DIR,
entryPoints: ['src/preload/preload.ts'],
bundle: true,
platform: 'node',
format: 'cjs',
outfile: 'dist/preload/preload.cjs',
external: ['electron'],
logLevel: 'warning',
}).then(
() => log('build', 'preload — done'),
(e) => { log('build', `preload — FAILED: ${e.message}`); throw e; },
),
Expand All@@ -81,7 +94,17 @@ await Promise.all([
// tsconfig.main.json still compiles tests for `npm test` and typechecks
// main-process code in verification commands.
log('build', 'main — starting');
await runNodeTool(DESKTOP_DIR, ESBUILD_CLI, ['src/main/main.ts', '--bundle', '--platform=node', '--format=esm', '--packages=external', '--outfile=dist/main/main.js', '--external:electron']);
await esbuildBuild({
absWorkingDir: DESKTOP_DIR,
entryPoints: ['src/main/main.ts'],
bundle: true,
platform: 'node',
format: 'esm',
packages: 'external',
outfile: 'dist/main/main.js',
external: ['electron'],
logLevel: 'warning',
});
log('build', 'main — done');

const BUILD_MS = Date.now() - TIMER_START;
Expand Down
9 changes: 6 additions & 3 deletions apps/desktop/src/main/__tests__/dev-startup-contract.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,10 +7,13 @@ test('dev launcher bundles app main sources without compiling main-process tests
const cwd = process.cwd();
const desktopRoot = cwd.endsWith(join('apps', 'desktop')) ? cwd : join(cwd, 'apps', 'desktop');
const devScript = await readFile(join(desktopRoot, 'scripts', 'dev.mjs'), 'utf8');
assert.match(devScript, /esbuild/);
// dev.mjs now calls esbuild's JS API instead of `node bin/esbuild`
// (postinstall replaces that file with a platform-native binary that
// node cannot execute) — assert on the API options instead of CLI flags.
assert.match(devScript, /esbuildBuild\(/);
assert.match(devScript, /src\/main\/main\.ts/);
assert.match(devScript, /--bundle/);
assert.match(devScript, /--packages=external/);
assert.match(devScript, /bundle:\s*true/);
assert.match(devScript, /packages:\s*'external'/);
assert.doesNotMatch(devScript, /\['tsc', '-p'/);
assert.doesNotMatch(devScript, /tsconfig\.main\.app\.json/);
});
Expand Down