Z ZPI 文档 v0.3.8
介绍页

源码

scripts/dev.mjs

javascript88 行查看原文
import { execFileSync, spawn } from "node:child_process";
import { constants } from "node:fs";
import { cp } from "node:fs/promises";
import { dirname, join, resolve } from "node:path";
import electron from "electron";
import { build } from "tsup";
import { createServer } from "vite";
import { buildAppIcon } from "./app-icon.mjs";
import { cleanDesktopBuild, mainBuild, preloadBuild } from "./desktop-build.mjs";
import { stopDesktopProcess } from "./dev-process.ts";
import { prepareTerminal } from "./prepare-terminal.ts";

if (process.env.ZPI_TEST_SCOPE || process.env.ZPI_TEST_MODE || process.env.VITEST)
  throw new Error("Tests must use launchDesktop; the development launcher is interactive");

await cleanDesktopBuild();
await prepareTerminal();
await buildAppIcon();
let executable = electron;
if (process.platform === "darwin") {
  // Match Preview's identity without modifying the installed Electron bundle.
  const bundle = resolve("node_modules/.cache/zpi-dev/ZPI Preview.app");
  await cp(resolve(dirname(electron), "../.."), bundle, {
    recursive: true,
    verbatimSymlinks: true,
    mode: constants.COPYFILE_FICLONE,
  });
  const plist = join(bundle, "Contents/Info.plist");
  for (const key of ["CFBundleName", "CFBundleDisplayName"]) {
    execFileSync("/usr/libexec/PlistBuddy", ["-c", `Set :${key} ZPI Preview`, plist]);
  }
  executable = join(bundle, "Contents/MacOS/Electron");
}
let child;
let shuttingDown = false;
const server = await createServer({
  configFile: "packages/desktop/vite.config.ts",
  ...(process.env.ZPI_DEV_PORT ? { server: { port: Number(process.env.ZPI_DEV_PORT) } } : {}),
});
await server.listen();
const devUrl = server.resolvedUrls?.local[0];
if (!devUrl) throw new Error("Vite did not expose a local URL");
await build({
  ...mainBuild,
  watch: [
    "packages/desktop/src/main",
    "packages/desktop/src/shared",
    "packages/desktop/src/preload",
    "packages/ai/src",
    "packages/agent/src",
    "packages/coding-agent/src",
  ],
  onSuccess: async () => {
    if (shuttingDown) return;
    await build(preloadBuild);
    await stopDesktopProcess(child);
    if (shuttingDown) return;
    const env = { ...process.env, ZPI_DEV_URL: devUrl };
    delete env.ELECTRON_RUN_AS_NODE;
    child = spawn(
      executable,
      [
        "--enable-source-maps",
        ...(process.env.ZPI_DEV_DEBUG === "1" ? ["--remote-debugging-port=0"] : []),
        "packages/desktop/dist/main/index.js",
      ],
      { stdio: "inherit", env },
    );
    console.log("ZPI Preview Desktop started. Ctrl+C stops the app and development server.");
  },
});
async function close() {
  if (shuttingDown) return;
  shuttingDown = true;
  let code = 0;
  try {
    await stopDesktopProcess(child);
  } catch (error) {
    console.error(error);
    code = 1;
  } finally {
    await server.close();
  }
  process.exit(code);
}
process.on("SIGINT", close);
process.on("SIGTERM", close);