build-with-env.mjs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #!/usr/bin/env node
  2. /**
  3. * 用指定 env 文件注入 process.env 后执行 next build。
  4. * 已注入的变量优先于 .env.production(Next 不会覆盖已有 process.env)。
  5. */
  6. import { readFileSync, existsSync } from "fs";
  7. import { spawnSync } from "child_process";
  8. import { resolve, dirname } from "path";
  9. import { fileURLToPath } from "url";
  10. const __dirname = dirname(fileURLToPath(import.meta.url));
  11. const root = resolve(__dirname, "..");
  12. const envFile = process.argv[2] || ".env.development";
  13. const envPath = resolve(root, envFile);
  14. if (!existsSync(envPath)) {
  15. console.error(`[build-with-env] 找不到 ${envPath}`);
  16. process.exit(1);
  17. }
  18. const env = { ...process.env, NODE_ENV: "production" };
  19. for (const line of readFileSync(envPath, "utf8").split("\n")) {
  20. const trimmed = line.trim();
  21. if (!trimmed || trimmed.startsWith("#")) continue;
  22. const eq = trimmed.indexOf("=");
  23. if (eq === -1) continue;
  24. const key = trimmed.slice(0, eq).trim();
  25. let val = trimmed.slice(eq + 1).trim();
  26. if (
  27. (val.startsWith('"') && val.endsWith('"')) ||
  28. (val.startsWith("'") && val.endsWith("'"))
  29. ) {
  30. val = val.slice(1, -1);
  31. }
  32. env[key] = val;
  33. }
  34. console.log(
  35. `[build-with-env] ${envFile} → NEXT_PUBLIC_APP_ENV=${env.NEXT_PUBLIC_APP_ENV}, API_PROXY_TARGET=${env.API_PROXY_TARGET}`,
  36. );
  37. const nextCli = resolve(root, "node_modules/next/dist/bin/next");
  38. if (!existsSync(nextCli)) {
  39. console.error("[build-with-env] 未找到 next,请先在项目目录执行 npm install");
  40. process.exit(1);
  41. }
  42. const r = spawnSync(process.execPath, [nextCli, "build"], {
  43. cwd: root,
  44. env,
  45. stdio: "inherit",
  46. });
  47. if (r.error) {
  48. console.error("[build-with-env] 启动 next build 失败:", r.error.message);
  49. process.exit(1);
  50. }
  51. process.exit(r.status ?? 1);