59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
import { spawn } from "node:child_process";
|
|
import { existsSync, readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { parse } from "dotenv";
|
|
|
|
const [environment = "development", command = "dev", ...args] = process.argv.slice(2);
|
|
if (
|
|
!["development", "test", "production"].includes(environment) ||
|
|
!["dev", "build", "start"].includes(command)
|
|
) {
|
|
throw new Error(
|
|
"Usage: tsx scripts/next-env.ts development|test|production dev|build|start",
|
|
);
|
|
}
|
|
|
|
const config = (file: string) => (existsSync(file) ? parse(readFileSync(file)) : {});
|
|
|
|
const childEnv: NodeJS.ProcessEnv = {
|
|
...config(resolve(`config/${environment}.env`)),
|
|
...config(resolve(`config/${environment}.local.env`)),
|
|
...process.env,
|
|
APP_ENV: environment,
|
|
NODE_ENV: command === "dev" ? "development" : "production",
|
|
};
|
|
|
|
const nodeOptions = [childEnv.NODE_OPTIONS, "--dns-result-order=ipv4first"]
|
|
.filter(Boolean)
|
|
.join(" ");
|
|
childEnv.NODE_OPTIONS = nodeOptions;
|
|
|
|
if (command !== "build") {
|
|
const api =
|
|
childEnv.API_PROXY_TARGET?.trim() || childEnv.NEXT_PUBLIC_API_BASE_URL?.trim();
|
|
if (!api) {
|
|
throw new Error(
|
|
`API_PROXY_TARGET 或 NEXT_PUBLIC_API_BASE_URL 必填(${environment})。可写在 config/${environment}.local.env`,
|
|
);
|
|
}
|
|
}
|
|
|
|
const nextBin = resolve("node_modules/next/dist/bin/next");
|
|
// CLI 参数比 NODE_OPTIONS 更稳:Next 子进程有时会改写 NODE_OPTIONS,导致仍走 IPv6。
|
|
const child = spawn(
|
|
process.execPath,
|
|
[
|
|
"--dns-result-order=ipv4first",
|
|
nextBin,
|
|
command,
|
|
...(command === "build" ? [] : ["--port", childEnv.PORT || "3000"]),
|
|
...args,
|
|
],
|
|
{ stdio: "inherit", env: childEnv },
|
|
);
|
|
|
|
for (const signal of ["SIGINT", "SIGTERM"] as const) {
|
|
process.on(signal, () => child.kill(signal));
|
|
}
|
|
child.on("exit", (code) => process.exit(code ?? 1));
|