From 710448a75fd4b9b8e20100d6a53cf155ad4d6c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Wed, 22 Apr 2026 18:31:24 -0400 Subject: [PATCH] fix(preload): keep zod out of sandbox bundle --- .gitignore | 1 + electron.vite.config.ts | 5 +---- src/preload/index.ts | 6 +++--- tests/unit/preload-bundling-contract.test.ts | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 tests/unit/preload-bundling-contract.test.ts diff --git a/.gitignore b/.gitignore index db74c483..95f0d23a 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ oldreference/ !/docs/architecture/*.md !/CLAUDE.md !/AGENTS.md +!/问题.md !/.planning/**/*.md !/src/main/prompt-builder/**/*.md !/scripts/README.md diff --git a/electron.vite.config.ts b/electron.vite.config.ts index e32d60da..c02e9a5b 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -22,10 +22,7 @@ export default defineConfig({ }, }, preload: { - // zod is bundled into preload because preload runs as sandboxed CJS - // and cannot resolve externalized ESM deps at runtime. Inlining keeps - // IPC Zod validation working inside the preload layer. - plugins: [externalizeDepsPlugin({ exclude: ["zod"] })], + plugins: [externalizeDepsPlugin()], resolve: { alias: { "@shared": resolve("src/shared"), diff --git a/src/preload/index.ts b/src/preload/index.ts index 1324ab20..a8fea974 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -1,11 +1,11 @@ import { contextBridge, ipcRenderer } from "electron"; +import { IPC_CHANNELS } from "@shared/contracts/channels"; +import type { DesktopApi } from "@shared/contracts/desktop-api"; import { - IPC_CHANNELS, PRELOAD_FORWARDERS, mapPreloadInvokeArgs, - type DesktopApi, type PreloadForwardedApi, -} from "@shared/contracts"; +} from "@shared/contracts/preload-forwarders"; import type { DesktopEvent } from "@shared/types"; function createForwardedApi(): PreloadForwardedApi { diff --git a/tests/unit/preload-bundling-contract.test.ts b/tests/unit/preload-bundling-contract.test.ts new file mode 100644 index 00000000..214ef016 --- /dev/null +++ b/tests/unit/preload-bundling-contract.test.ts @@ -0,0 +1,14 @@ +import { readFileSync } from "node:fs"; +import { join } from "node:path"; +import { describe, expect, it } from "vitest"; + +describe("preload bundling contract", () => { + it("keeps Zod validation on the main-process IPC boundary", () => { + const configSource = readFileSync(join(process.cwd(), "electron.vite.config.ts"), "utf8"); + const preloadSource = readFileSync(join(process.cwd(), "src/preload/index.ts"), "utf8"); + + expect(configSource).not.toContain('exclude: ["zod"]'); + expect(preloadSource).not.toContain('from "@shared/contracts"'); + expect(preloadSource).not.toMatch(/from ["']zod["']|require\(["']zod["']\)/); + }); +});