import type { NextConfig } from "next"; import fs from "fs"; import path from "path"; function loadEnvAll() { // 约定:全局仅使用仓库根目录的 .env.all 作为配置来源(生产优先)。 // 说明:这里仅“补齐缺失项”,避免覆盖系统环境变量(方便部署/容器注入)。 const envAllPath = path.resolve(__dirname, "..", ".env.all"); if (!fs.existsSync(envAllPath)) return; const raw = fs.readFileSync(envAllPath, { encoding: "utf8" }); 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; if (process.env[key] === undefined) { process.env[key] = value; } } } loadEnvAll(); const nextConfig: NextConfig = { // 供桌面端打包使用(Electron 内置 Next server.js + 最小依赖)。 // 说明:`pnpm run build:desktop:next` 会依赖该产物。 output: "standalone", turbopack: { // 避免 monorepo/多 lockfile 场景下 root 误判,减少构建与热更新的不确定性 root: __dirname, }, async headers() { // 说明:ONLYOFFICE 文档服务器会在其 iframe 内跨域拉取插件 manifest/js/html。 // 这里对插件资源放开 CORS,避免 pluginsData 加载失败。 return [ // 说明:远程通过 Cloudflare Tunnel 访问时,Next.js(Turbopack dev)默认对 // `/_next/static/chunks/*` 返回 `no-store`,导致 Cloudflare 无法缓存大体积 // bundle,网络稍慢时会出现页面长期停留在“正在载入编辑器...”的现象。 // 这些资源带 hash 文件名,设置 immutable 不会导致更新不一致。 { source: "/_next/static/chunks/:path*", headers: [{ key: "Cache-Control", value: "public, max-age=31536000, immutable" }], }, { source: "/_next/static/media/:path*", headers: [{ key: "Cache-Control", value: "public, max-age=31536000, immutable" }], }, // Luckysheet 静态资源:文件位于 public/luckysheet,路径稳定(并且我们在 URL 上追加了版本参数),可长期缓存。 { source: "/luckysheet/:path*", headers: [{ key: "Cache-Control", value: "public, max-age=31536000, immutable" }], }, { source: "/onlyoffice/plugins/:path*", headers: [ { key: "Access-Control-Allow-Origin", value: "*" }, { key: "Access-Control-Allow-Methods", value: "GET,OPTIONS" }, { key: "Access-Control-Allow-Headers", value: "*" }, ], }, ]; }, }; export default nextConfig;