Initial clean project import
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const net = require("node:net");
|
||||
const { spawn, spawnSync } = require("node:child_process");
|
||||
|
||||
const projectRoot = path.resolve(__dirname, "..");
|
||||
const serverUrl = process.env.VITE_DEV_SERVER_URL || "http://127.0.0.1:3354";
|
||||
const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
|
||||
const requiredNodeMajor = 20;
|
||||
const checkOnly = process.argv.includes("--check");
|
||||
|
||||
function log(message = "") {
|
||||
process.stdout.write(`${message}\n`);
|
||||
}
|
||||
|
||||
function fail(message) {
|
||||
process.stderr.write(`\n[start-local] ${message}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function parseServerUrl(url) {
|
||||
try {
|
||||
return new URL(url);
|
||||
} catch {
|
||||
fail(`VITE_DEV_SERVER_URL 无效:${url}`);
|
||||
}
|
||||
}
|
||||
|
||||
function checkCommand(command, args, label) {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd: projectRoot,
|
||||
encoding: "utf8",
|
||||
stdio: "pipe",
|
||||
shell: process.platform === "win32",
|
||||
});
|
||||
|
||||
if (result.error || result.status !== 0) {
|
||||
fail(`未检测到 ${label},请先安装后再运行。`);
|
||||
}
|
||||
|
||||
return (result.stdout || result.stderr || "").trim();
|
||||
}
|
||||
|
||||
function checkNodeVersion() {
|
||||
const major = Number(process.versions.node.split(".")[0]);
|
||||
if (!Number.isFinite(major) || major < requiredNodeMajor) {
|
||||
fail(`当前 Node.js 为 ${process.version},建议使用 .nvmrc 指定的 Node.js ${requiredNodeMajor}。`);
|
||||
}
|
||||
}
|
||||
|
||||
function checkDependencies() {
|
||||
const viteBin = path.join(projectRoot, "node_modules", ".bin", process.platform === "win32" ? "vite.cmd" : "vite");
|
||||
const electronPackage = path.join(projectRoot, "node_modules", "electron", "package.json");
|
||||
|
||||
if (!fs.existsSync(viteBin) || !fs.existsSync(electronPackage)) {
|
||||
fail("依赖尚未安装,请先执行:npm install");
|
||||
}
|
||||
}
|
||||
|
||||
function assertPortAvailable(host, port) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = net.createServer();
|
||||
|
||||
server.once("error", error => {
|
||||
if (error.code === "EADDRINUSE") {
|
||||
reject(new Error(`端口 ${port} 已被占用,请先关闭已有 Vite/Electron 开发进程。`));
|
||||
return;
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
|
||||
server.once("listening", () => {
|
||||
server.close(resolve);
|
||||
});
|
||||
|
||||
server.listen(port, host);
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
process.chdir(projectRoot);
|
||||
|
||||
const parsedUrl = parseServerUrl(serverUrl);
|
||||
const host = parsedUrl.hostname || "127.0.0.1";
|
||||
const port = Number(parsedUrl.port || 3344);
|
||||
|
||||
log("========================================");
|
||||
log(" 本地快速启动:Vite + Electron");
|
||||
log("========================================");
|
||||
log(`项目目录:${projectRoot}`);
|
||||
log(`开发地址:${serverUrl}`);
|
||||
log("");
|
||||
|
||||
checkNodeVersion();
|
||||
const npmVersion = checkCommand(npmCommand, ["--version"], "npm");
|
||||
checkDependencies();
|
||||
await assertPortAvailable(host, port);
|
||||
|
||||
log(`Node.js:${process.version}`);
|
||||
log(`npm:${npmVersion}`);
|
||||
log("");
|
||||
|
||||
if (checkOnly) {
|
||||
log("自检通过:可以执行 npm run start:local 或双击 start-local.bat 启动。");
|
||||
return;
|
||||
}
|
||||
|
||||
log("正在启动应用,关闭此窗口即可停止开发服务。");
|
||||
log("");
|
||||
|
||||
const child = spawn(npmCommand, ["run", "dev:electron"], {
|
||||
cwd: projectRoot,
|
||||
stdio: "inherit",
|
||||
env: {
|
||||
...process.env,
|
||||
VITE_DEV_SERVER_URL: serverUrl,
|
||||
},
|
||||
shell: process.platform === "win32",
|
||||
});
|
||||
|
||||
child.on("exit", code => {
|
||||
process.exit(code ?? 0);
|
||||
});
|
||||
|
||||
child.on("error", error => {
|
||||
fail(`启动失败:${error.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
fail(error.message);
|
||||
});
|
||||
Reference in New Issue
Block a user