build: electron-builder 打包配置 + 首次构建(win-unpacked 可运行 168MB,cross-env 注入 npmmirror 镜像;打包产物冒烟测试启动 .exe)

This commit is contained in:
hunter-dev
2026-08-24 23:18:39 +08:00
parent 403a28cb2f
commit b9aefa3c17
6 changed files with 1793 additions and 96 deletions
+25 -1
View File
@@ -1,14 +1,36 @@
{
"name": "@hunter/desktop",
"version": "0.0.0",
"description": "狩夜人笔记 — 本地优先的 Markdown 知识库",
"author": "hunter-dev",
"private": true,
"type": "module",
"main": "dist-electron/main/index.js",
"build": {
"appId": "com.hunter.notes",
"productName": "HunterNotes",
"directories": {
"output": "release"
},
"files": [
"dist-electron/**/*",
"package.json"
],
"asar": true,
"win": {
"target": "dir"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
}
},
"scripts": {
"dev": "electron-vite dev",
"build": "electron-vite build",
"typecheck": "tsc -b",
"test:e2e": "electron-vite build && playwright test"
"test:e2e": "electron-vite build && playwright test",
"dist": "electron-vite build && cross-env ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/ electron-builder --win"
},
"dependencies": {
"@hunter/shared": "workspace:*",
@@ -44,7 +66,9 @@
"@types/node": "^20.0.0",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"cross-env": "^10.1.0",
"electron": "^30.0.0",
"electron-builder": "^26.15.3",
"electron-vite": "^2.3.0",
"playwright": "^1.62.1",
"react": "^18.3.1",
+22
View File
@@ -0,0 +1,22 @@
import { test, expect } from '@playwright/test';
import { _electron as electron } from 'playwright';
import { promises as fs } from 'node:fs';
import nodePath from 'node:path';
import os from 'node:os';
// 打包产物冒烟:启动 electron-builder 产出的 win-unpacked 可执行文件(FR-A0 可安装/可运行基线)
const EXE = nodePath.join(process.cwd(), 'release/win-unpacked/HunterNotes.exe');
test('packaged app launches and renders title bar', async () => {
const exists = await fs.stat(EXE).then(() => true).catch(() => false);
if (!exists) test.skip(true, 'HunterNotes.exe 未构建:先跑 pnpm --filter @hunter/desktop dist');
const tmp = await fs.mkdtemp(nodePath.join(os.tmpdir(), 'hn-pkg-'));
const app = await electron.launch({ executablePath: EXE, args: ['--user-data-dir=' + nodePath.join(tmp, 'userdata')] });
try {
const page = await app.firstWindow();
await page.waitForLoadState('domcontentloaded');
await expect(page.getByText('狩夜人笔记').first()).toBeVisible({ timeout: 15000 });
} finally {
await app.close();
}
});