1import "vite-plus/test/config";
2import { defineConfig } from "vite-plus";
3
4import { isDesktopRuntimeExternalDependency } from "../../scripts/lib/desktop-external-packages.ts";
5import { loadRepoEnv } from "../../scripts/lib/public-config.ts";
6
7const repoEnv = loadRepoEnv();
8
9// The main process is bundled the same way the server CLI is: every JS
10// dependency is inlined and only packages Node must load from disk stay
11// external. The packaged app then installs just those externals, instead of a
12// full production install of apps/desktop's dependency tree next to a server
13// bundle that already carries its own copy of the same libraries.
14const isMainProcessExternal = (id: string) =>
15 id === "electron" || id.startsWith("electron/") || isDesktopRuntimeExternalDependency(id);
16const shouldLaunchElectronAfterPack = process.env.T3CODE_DESKTOP_DEV === "1";
17const publicConfigDefine = {
18 __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__: JSON.stringify(
19 repoEnv.T3CODE_CLERK_PUBLISHABLE_KEY?.trim() ?? "",
20 ),
21};
22
23export default defineConfig({
24 run: {
25 tasks: {
26 build: {
27 command:
28 "node scripts/build-browser-secret.mjs && node scripts/build-preview-annotation-css.mjs && vp pack",
29 dependsOn: ["t3#build"],
30 cache: false,
31 },
32 dev: {
33 command:
34 "node scripts/build-browser-secret.mjs && node scripts/build-preview-annotation-css.mjs && cross-env T3CODE_DESKTOP_DEV=1 vp pack --watch",
35 dependsOn: ["t3#build"],
36 cache: false,
37 },
38 "dev:bundle": {
39 command:
40 "node scripts/build-browser-secret.mjs && node scripts/build-preview-annotation-css.mjs && vp pack --watch",
41 cache: false,
42 },
43 "dev:electron": {
44 command: "node scripts/dev-electron.mjs",
45 dependsOn: ["t3#build"],
46 cache: false,
47 },
48 },
49 },
50 pack: [
51 {
52 format: "cjs",
53 outDir: "dist-electron",
54 dts: false,
55 sourcemap: true,
56 outExtensions: () => ({ js: ".cjs" }),
57 define: publicConfigDefine,
58 outputOptions: { codeSplitting: false },
59 entry: ["src/main.ts"],
60 clean: true,
61 deps: {
62 alwaysBundle: (id) => !id.startsWith("node:") && !isMainProcessExternal(id),
63 neverBundle: isMainProcessExternal,
64 onlyBundle: false,
65 },
66 ...(shouldLaunchElectronAfterPack ? { onSuccess: "node scripts/dev-electron.mjs" } : {}),
67 },
68 {
69 format: "cjs",
70 outDir: "dist-electron",
71 dts: false,
72 sourcemap: true,
73 outExtensions: () => ({ js: ".cjs" }),
74 define: publicConfigDefine,
75 entry: [
76 "src/electron/WindowsForegroundFocusWorker.ts",
77 "src/snapShot/GlobalShiftShortcutWorker.ts",
78 "src/snapShot/RegionSnapShotWorker.ts",
79 "src/snapShot/SnapShotAccessibilityWorker.ts",
80 ],
81 clean: false,
82 deps: {
83 alwaysBundle: (id) => !id.startsWith("node:") && !isMainProcessExternal(id),
84 neverBundle: isMainProcessExternal,
85 onlyBundle: false,
86 },
87 },
88 {
89 // boot.cjs requires the other two at runtime, so all three stay separate files.
90 format: "cjs",
91 outDir: "dist-electron",
92 dts: false,
93 sourcemap: true,
94 outExtensions: () => ({ js: ".cjs" }),
95 entry: ["src/boot.ts", "src/compileCache.ts"],
96 clean: false,
97 deps: {
98 alwaysBundle: (id) => !id.startsWith("node:") && id !== "electron",
99 neverBundle: (id) =>
100 id === "electron" || id === "./main.cjs" || id === "./compileCache.cjs",
101 },
102 },
103 {
104 format: "cjs",
105 outDir: "dist-electron",
106 dts: false,
107 sourcemap: true,
108 outExtensions: () => ({ js: ".cjs" }),
109 define: publicConfigDefine,
110 entry: ["src/preload.ts"],
111 deps: {
112 // Sandboxed Electron preloads cannot reliably resolve package imports
113 // from inside the packaged ASAR. Bundle Clerk's preload bridge into the
114 // preload artifact instead of leaving a runtime require() behind.
115 alwaysBundle: (id) => id === "@clerk/electron" || id.startsWith("@clerk/electron/"),
116 },
117 },
118 {
119 format: "cjs",
120 outDir: "dist-electron",
121 dts: false,
122 sourcemap: true,
123 outExtensions: () => ({ js: ".cjs" }),
124 entry: ["src/preview-pick-preload.ts"],
125 deps: {
126 alwaysBundle: (id) => id === "react-grab" || id.startsWith("react-grab/"),
127 },
128 },
129 {
130 format: "cjs",
131 outDir: "dist-electron",
132 dts: false,
133 sourcemap: true,
134 outExtensions: () => ({ js: ".cjs" }),
135 entry: ["src/preview-pip-preload.ts"],
136 },
137 {
138 // Sandboxed preloads must be self-contained, without shared runtime chunks.
139 format: "cjs",
140 outDir: "dist-electron",
141 dts: false,
142 sourcemap: true,
143 outExtensions: () => ({ js: ".cjs" }),
144 entry: ["src/mac-permission-preload.ts"],
145 },
146 ],
147 test: {
148 // The Windows lane runs workspace suites concurrently; filesystem-heavy
149 // desktop integration tests can exceed Vitest's 5 second default there.
150 testTimeout: 15_000,
151 setupFiles: ["../../packages/shared/src/testing/longTempDir.ts"],
152 },
153});