Files
mnote/scripts/prepare-desktop-next.js
T
2026-01-15 20:54:21 +08:00

122 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* 生成桌面端内置的 Next standalone 产物到 `desktop-electron/desktop-next`。
*
* 目标:
* - 打包时不依赖用户机器上的 pnpm / node 环境即可运行(Electron 自身携带 Node)。
* - 运行期文件读写落到安装目录的 data/(由 Electron 注入 MNOTE_DATA_DIR)。
*
* 注意:需要 wolai-frontend 的 next.config.ts 开启 output: "standalone"。
*/
const { spawnSync } = require("child_process");
const fs = require("fs");
const path = require("path");
const rootDir = path.resolve(__dirname, "..");
const frontendDir = path.join(rootDir, "wolai-frontend");
const outDir = path.join(rootDir, "desktop-electron", "desktop-next");
function parseDotenv(filePath) {
if (!fs.existsSync(filePath)) return {};
const raw = fs.readFileSync(filePath, { encoding: "utf8" });
const out = {};
for (const line of raw.split(/\r?\n/)) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) continue;
const idx = trimmed.indexOf("=");
if (idx === -1) continue;
const key = trimmed.slice(0, idx).trim();
const value = trimmed.slice(idx + 1).trim();
if (!key) continue;
out[key] = value;
}
return out;
}
function ensureDir(dir) {
fs.mkdirSync(dir, { recursive: true });
}
function rmDir(dir) {
fs.rmSync(dir, { recursive: true, force: true });
}
function run(command, cwd, env) {
const r = spawnSync(command, {
cwd,
env: { ...process.env, ...env },
stdio: "inherit",
shell: true,
});
if (r.status !== 0) {
process.exit(r.status ?? 1);
}
}
function assertExists(filePath, hint) {
if (!fs.existsSync(filePath)) {
console.error(`\n[prepare-desktop-next] 缺少:${filePath}`);
if (hint) console.error(`[prepare-desktop-next] 提示:${hint}`);
process.exit(1);
}
}
function copyDir(from, to) {
// 关键:Next standalone 在 pnpm 环境下可能包含大量 symlink/junction。
// electron-builder 在复制 extraResources 时对链接目录处理不稳定,
// 因此这里强制“解引用复制”,把真实文件复制出来,确保运行期能 require('next')。
fs.cpSync(from, to, { recursive: true, force: true, dereference: true });
}
function main() {
console.log("[prepare-desktop-next] 开始构建 wolai-frontendstandalone)…");
// 说明:桌面端默认不走 Cloudflare(避免 NEXT_PUBLIC_* 写死导致“像网页版一样卡”)。
// 优先读取 wolai-frontend/.env.local,并允许用 wolai-frontend/.env.desktop.local 覆盖。
const desktopEnv = {
...parseDotenv(path.join(frontendDir, ".env.local")),
...parseDotenv(path.join(frontendDir, ".env.desktop.local")),
};
console.log("[prepare-desktop-next] 桌面端 env 摘要:", {
NEXT_PUBLIC_SUPABASE_URL: desktopEnv.NEXT_PUBLIC_SUPABASE_URL,
NEXT_PUBLIC_BACKEND_URL: desktopEnv.NEXT_PUBLIC_BACKEND_URL,
NEXT_PUBLIC_ONLYOFFICE_BASE_URL: desktopEnv.NEXT_PUBLIC_ONLYOFFICE_BASE_URL,
});
run("pnpm -C wolai-frontend build", rootDir, {
NODE_ENV: "production",
NEXT_TELEMETRY_DISABLED: "1",
...desktopEnv,
});
const standaloneDir = path.join(frontendDir, ".next", "standalone");
const staticDir = path.join(frontendDir, ".next", "static");
const publicDir = path.join(frontendDir, "public");
assertExists(
path.join(standaloneDir, "server.js"),
'请在 wolai-frontend/next.config.ts 增加 `output: "standalone"` 后重试。',
);
assertExists(staticDir, "Next build 未生成 .next/static(可能构建失败或目录异常)。");
assertExists(publicDir, "wolai-frontend/public 不存在。");
console.log(`[prepare-desktop-next] 清理旧产物:${outDir}`);
rmDir(outDir);
ensureDir(outDir);
console.log("[prepare-desktop-next] 复制 standalone …");
copyDir(standaloneDir, outDir);
console.log("[prepare-desktop-next] 补齐 .next/static …");
ensureDir(path.join(outDir, ".next"));
copyDir(staticDir, path.join(outDir, ".next", "static"));
console.log("[prepare-desktop-next] 补齐 public …");
copyDir(publicDir, path.join(outDir, "public"));
console.log("[prepare-desktop-next] 完成。");
}
main();