#!/usr/bin/env node /** * 打包:发布构建 + 打成可直接上传 Chrome / 用于自托管自更新的 zip。 * * 只收运行时文件,源码、脚本、部署产物(updates.xml / install-policy.reg)不入包。 * * 用法: * node scripts/package.mjs 构建并打包 * node scripts/package.mjs --skip-build 仅打包(复用现有 dist) */ import { execFileSync } from "node:child_process"; import { mkdir, readFile, rm } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; import { buildAll } from "./build.mjs"; const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); /** 扩展包内容:manifest 及其引用的所有运行时资源 */ const PACKAGE_FILES = ["manifest.json", "popup.html", "popup.css", "icons", "_locales", "dist"]; export async function packageExtension({ skipBuild = false } = {}) { if (!skipBuild) await buildAll({ release: true }); const manifest = JSON.parse(await readFile(path.join(ROOT, "manifest.json"), "utf8")); const outDir = path.join(ROOT, "release"); await mkdir(outDir, { recursive: true }); const zipPath = path.join(outDir, `auto-login-v${manifest.version}.zip`); await rm(zipPath, { force: true }); try { execFileSync("zip", ["-r", "-q", zipPath, ...PACKAGE_FILES], { cwd: ROOT, stdio: "inherit" }); } catch (err) { throw new Error(`打包失败(需要系统 zip 命令):${err.message}`, { cause: err }); } console.log(`[package] v${manifest.version} → ${path.relative(ROOT, zipPath)}`); return { version: manifest.version, zipPath }; } const isDirectRun = process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href; if (isDirectRun) { await packageExtension({ skipBuild: process.argv.includes("--skip-build") }); }