From ada7dd8548a5665f05176bc1758a043badfd65b8 Mon Sep 17 00:00:00 2001 From: Hu Gang <18768366022@163.com> Date: Sat, 29 Mar 2025 10:57:46 +0800 Subject: [PATCH] feat : conf electron --- .gitignore | 1 + electron/main/index.ts | 20 +++++++ electron/main/window/create.ts | 32 +++++++++++ electron/main/window/index.ts | 1 + electron/main/window/options.ts | 23 ++++++++ electron/preload/index.ts | 0 installer.nsh | 21 +++++++ package.json | 98 +++++++++++++++++++++++++++++--- public/app_favicon.ico | Bin 0 -> 50962 bytes scripts/build-main.ts | 59 +++++++++++++++++++ scripts/build-preload.ts | 39 +++++++++++++ scripts/rollup.config.ts | 68 ++++++++++++++++++++++ scripts/utils.ts | 43 ++++++++++++++ src/apis/server.ts | 3 + tsconfig.json | 15 ++++- vite.config.ts | 35 +----------- 16 files changed, 413 insertions(+), 45 deletions(-) create mode 100644 electron/main/index.ts create mode 100644 electron/main/window/create.ts create mode 100644 electron/main/window/index.ts create mode 100644 electron/main/window/options.ts create mode 100644 electron/preload/index.ts create mode 100644 installer.nsh create mode 100644 public/app_favicon.ico create mode 100644 scripts/build-main.ts create mode 100644 scripts/build-preload.ts create mode 100644 scripts/rollup.config.ts create mode 100644 scripts/utils.ts diff --git a/.gitignore b/.gitignore index 7fdc5652..04c4535f 100755 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ coverage .gitee/ .npmrc +release \ No newline at end of file diff --git a/electron/main/index.ts b/electron/main/index.ts new file mode 100644 index 00000000..2babc5b1 --- /dev/null +++ b/electron/main/index.ts @@ -0,0 +1,20 @@ +import { app, ipcMain } from 'electron' +import { createDefaultWindow } from './window' + +app.whenReady().then(() => { + createDefaultWindow() + // const defaultWindow = createDefaultWindow() + + // 监听渲染进程崩溃或被杀死,重新运行程序 + // defaultWindow.webContents.on('render-process-gone', () => { + // app.relaunch() + // app.exit(0) + // }) +}) + +app.on('window-all-closed', () => { + ipcMain.removeAllListeners() + if (process.platform !== 'darwin') { + app.quit() + } +}) diff --git a/electron/main/window/create.ts b/electron/main/window/create.ts new file mode 100644 index 00000000..1d47863d --- /dev/null +++ b/electron/main/window/create.ts @@ -0,0 +1,32 @@ +import path from 'node:path' +import { BrowserWindow, app } from 'electron' +import { options as allWindow } from './options' + +export function createWindow(options: Electron.BrowserWindowConstructorOptions, hash: string): BrowserWindow { + const win = new BrowserWindow({ + ...options, + webPreferences: { + devTools: true, + preload: path.join(__dirname, '../preload/index.js'), + }, + }) + + if (app.isPackaged) { + win.loadFile(path.join(__dirname, `../index.html`)) + } + else { + win.webContents.openDevTools() + win.loadURL(`http://localhost:${process.env.PORT}`) + } + + return win +} + +let defaultWindow: BrowserWindow | null = null +export function createDefaultWindow(): BrowserWindow { + if (defaultWindow) return defaultWindow + + defaultWindow = createWindow(allWindow.defaultWin.window, allWindow.defaultWin.hash) + + return defaultWindow +} diff --git a/electron/main/window/index.ts b/electron/main/window/index.ts new file mode 100644 index 00000000..fd953c62 --- /dev/null +++ b/electron/main/window/index.ts @@ -0,0 +1 @@ +export { createWindow, createDefaultWindow } from './create' diff --git a/electron/main/window/options.ts b/electron/main/window/options.ts new file mode 100644 index 00000000..06e9bfb7 --- /dev/null +++ b/electron/main/window/options.ts @@ -0,0 +1,23 @@ +export interface allWindowType { + [propName: string]: { + window: Electron.BrowserWindowConstructorOptions + hash: string + } +} + +export const options: allWindowType = { + defaultWin: { + window: { + width: 800, + height: 600, + resizable: true, + show: true, + alwaysOnTop: false, + useContentSize: true, + frame: true, + backgroundColor: '#ffffff', + icon: 'dist/favicon.ico', + }, + hash: 'defaultWin', + }, +} diff --git a/electron/preload/index.ts b/electron/preload/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/installer.nsh b/installer.nsh new file mode 100644 index 00000000..750916ed --- /dev/null +++ b/installer.nsh @@ -0,0 +1,21 @@ +# Custom NSIS script + +# 预初始化时,根据机器位数决定默认安装路径 + +!include "x64.nsh" +!include "LogicLib.nsh" + +Var INSTALL_PATH + +!macro preInit + ${If} ${RunningX64} + SetRegView 64 + StrCpy $INSTALL_PATH "C:\Program Files\eulercopilot" + ${Else} + SetRegView 32 + StrCpy $INSTALL_PATH "C:\Program Files (x86)\eulercopilot" + ${EndIf} + + WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$INSTALL_PATH" + WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$INSTALL_PATH" +!macroend diff --git a/package.json b/package.json index 6fdca229..32e5cded 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,12 @@ { "name": "euler-copilot-web", "version": "1.0.0", + "description": "Openeuler intelligent question and answer assistant", + "author": { + "name": "Openeuler" + }, "private": true, - "type": "module", + "main": "./dist/main/index.js", "scripts": { "dev": "vite", "dev:micro": "vite --mode micro", @@ -11,15 +15,69 @@ "preview": "vite preview", "lint": "eslint . --fix", "format": "prettier --write src/", - "type-check": "tsc --noEmit" + "type-check": "tsc --noEmit", + "dev:desktop": "concurrently -n=R,P,M -c=green,yellow,blue \"pnpm run dev:render\" \"pnpm run dev:preload\" \"pnpm run dev:main\"", + "dev:render": "vite", + "dev:preload": "node -r ts-node/register scripts/build-preload --env=development --watch", + "dev:main": "node -r ts-node/register scripts/build-main --env=development --watch", + "build:render": "vite build --mode electron-production", + "build:preload": "node -r ts-node/register scripts/build-preload --env=production", + "build:main": "node -r ts-node/register scripts/build-main --env=production", + "build:desktop": "rimraf dist && pnpm run build:render && pnpm run build:preload && pnpm run build:main", + "package:win32": "pnpm run build:desktop && electron-builder --win --ia32", + "package:win64": "pnpm run build:desktop && electron-builder --win --x64", + "package:mac": "pnpm run build:desktop && electron-builder --mac", + "package:linux": "pnpm run build:desktop && electron-builder --linux" + }, + "build": { + "appId": "com.openeuler.eulercopilot", + "productName": "eulercopilot", + "asar": true, + "copyright": "", + "directories": { + "output": "release/eulercopilot-${version}" + }, + "win": { + "icon": "dist/app_favicon.ico", + "target": [ + { + "target": "nsis" + } + ], + "artifactName": "${productName}_${version}.${ext}" + }, + "mac": { + "artifactName": "${productName}_${version}.${ext}", + "target": [ + "dmg" + ] + }, + "linux": { + "artifactName": "${productName}_${version}.${ext}", + "target": [ + "deb", + "rpm", + "AppImage" + ] + }, + "nsis": { + "oneClick": false, + "allowElevation": true, + "allowToChangeInstallationDirectory": true, + "installerIcon": "dist/app_favicon.ico", + "uninstallerIcon": "dist/app_favicon.ico", + "installerHeaderIcon": "dist/app_favicon.ico", + "createDesktopShortcut": true, + "createStartMenuShortcut": true, + "shortcutName": "eulercopilot", + "deleteAppDataOnUninstall": true, + "include": "./installer.nsh" + } }, "engines": { "node": ">= 18.18.2" }, "dependencies": { - "@babel/core": "^7.26.0", - "@babel/plugin-transform-runtime": "^7.25.9", - "@babel/preset-env": "^7.26.0", "@codemirror/lang-json": "^6.0.1", "@codemirror/lang-yaml": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2", @@ -27,7 +85,6 @@ "@computing/opendesign2": "file:lib\\opendesign2-2.0.23.tgz", "@dagrejs/dagre": "1.1.2", "axios": "1.7.9", - "babel-loader": "^9.2.1", "codemirror": "^6.0.1", "dayjs": "1.11.9", "echarts": "^5.5.1", @@ -36,9 +93,6 @@ "js-yaml": "^4.1.0", "marked": "4.3", "pinia": "2.1.6", - "sass": "1.62.0", - "typescript": "4.9.5", - "vite": "5.4.11", "vue": "3.3.4", "vue-codemirror": "^6.1.1", "vue-echarts": "^7.0.3", @@ -50,7 +104,17 @@ "xterm-addon-fit": "0.6.0" }, "devDependencies": { + "@babel/core": "^7.26.0", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.26.0", "@eslint/js": "9.16.0", + "@rollup/plugin-alias": "^5.1.1", + "@rollup/plugin-commonjs": "^28.0.3", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.1", + "@rollup/plugin-replace": "^6.0.2", + "@rollup/plugin-typescript": "^12.1.2", + "@types/minimist": "^1.2.5", "@types/node": "18.19.67", "@typescript-eslint/eslint-plugin": "8.17.0", "@typescript-eslint/parser": "8.17.0", @@ -61,13 +125,29 @@ "@vue-flow/minimap": "^1.5.0", "@vue-flow/node-resizer": "^1.4.0", "@vue-flow/node-toolbar": "^1.1.0", + "babel-loader": "^9.2.1", + "chalk": "^5.4.1", + "concurrently": "^9.1.2", + "dotenv": "^16.4.7", + "electron": "35.1.0", + "electron-builder": "^26.0.12", "eslint": "9.16.0", "eslint-plugin-vue": "9.32.0", "globals": "15.13.0", + "minimist": "^1.2.8", "mitt": "^3.0.1", + "ora": "^8.2.0", "prettier": "3.4.2", + "rimraf": "^6.0.1", + "rollup": "^4.37.0", + "rollup-plugin-copy": "^3.5.0", + "sass": "1.62.0", + "ts-node": "^10.9.2", + "tslib": "^2.8.1", + "typescript": "4.9.5", "typescript-eslint": "8.17.0", "uuid": "^11.0.5", + "vite": "5.4.11", "vite-plugin-qiankun": "1.0.15" } } diff --git a/public/app_favicon.ico b/public/app_favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..71f3ce0b8e3f2596c44e5fa3f6364b58ee335f58 GIT binary patch literal 50962 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ξ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�Hh>&K$N-sqL7-3iV+cYL$zVTN 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 ?)mauUwrS^floda zUzPY?fM5SA!oh<`i$iN_ivSc6l+b`|CACOgNf=4!l5^xGp;KU^#4ZFjDIo^q4hT*g zmWhKTACaXzNTUKISrnv|;{#S9*sW=>Y#Mb7tJ5<@NB^Wd-nPE};ybDEBA?8-UCTjz_>1Cj<7LKEV@Tbv>qM z_VI#O-mkCxi?2w!NpHOxy5~+{dRAOn5Z}o7?>i+%1VvdXFTzHnCk8~yXu6qDl5pO5 zWN2IOr)NDX%X6K`;2_#0A6E!n2#QUku5A%VV|C-5F7BN?j4!_RAH=u4{$2Qs*9vDR zD}bHP2t>hFbC990GOm}`qqZ(9fN#JmWKy_$3DS6{tQb3d#k>rR%ra&dJ?l#OBcpo&z0zk?hfMF7h9`3XqvNO7_g)0K~%#((_6Ux+vT)PKfx-vT7AkYt2Cb^pEAh5s^Q=Nq#AFBZ5^ U8Sg5ZMgRZ+07*qoM6N<$g7o&XjQ{`u literal 0 HcmV?d00001 diff --git a/scripts/build-main.ts b/scripts/build-main.ts new file mode 100644 index 00000000..651d92e0 --- /dev/null +++ b/scripts/build-main.ts @@ -0,0 +1,59 @@ +import path from 'node:path' +import chalk from 'chalk' +import ora from 'ora' +import minimist from 'minimist' +import electron from 'electron' +import { rollup, watch } from 'rollup' +import { getEnv, waitOn } from './utils' +import options from './rollup.config' +import { spawn } from 'node:child_process' +import { main } from '../package.json' + +import type { OutputOptions } from 'rollup' +import type { ChildProcess } from 'child_process' + +const TAG = '[build-main.ts]' + +const env = getEnv() +const argv = minimist(process.argv.slice(2)) +const opt = options({ proc: 'main', env: argv.env }) +const spinner = ora(`${TAG} Electron main build...`) + +;(async () => { + if (argv.watch) { + // Wait on vite server launched + await waitOn({ port: env.PORT as string }) + + const watcher = watch(opt) + let child: ChildProcess + watcher.on('change', (filename) => { + const log = chalk.green(`change -- ${filename}`) + console.log(TAG, log) + }) + watcher.on('event', (ev) => { + if (ev.code === 'END') { + if (child) child.kill() + child = spawn(electron as unknown as string, [path.join(__dirname, `../${main}`)], { + stdio: 'inherit', + }) + } + else if (ev.code === 'ERROR') { + console.log(ev.error) + } + }) + } + else { + spinner.start() + try { + const build = await rollup(opt) + await build.write(opt.output as OutputOptions) + spinner.succeed() + process.exit() + } + catch (error) { + console.log(`\n${TAG} ${chalk.red('构建报错')}\n`, error, '\n') + spinner.fail() + process.exit(1) + } + } +})() diff --git a/scripts/build-preload.ts b/scripts/build-preload.ts new file mode 100644 index 00000000..6b376562 --- /dev/null +++ b/scripts/build-preload.ts @@ -0,0 +1,39 @@ +import type { OutputOptions } from 'rollup' +import { watch, rollup } from 'rollup' +import minimist from 'minimist' +import chalk from 'chalk' +import ora from 'ora' +import options from './rollup.config' + +const argv = minimist(process.argv.slice(2)) +const opt = options({ proc: 'preload', env: argv.env }) +const TAG = '[build-preload.ts]' +const spinner = ora(`${TAG} Electron preload build...`) + +;(async () => { + if (argv.watch) { + const watcher = watch(opt) + watcher.on('change', (filename) => { + const log = chalk.yellow(`change -- ${filename}`) + console.log(TAG, log) + + /** + * @todo Hot reload render process !!! + */ + }) + } + else { + spinner.start() + try { + const build = await rollup(opt) + await build.write(opt.output as OutputOptions) + spinner.succeed() + process.exit() + } + catch (error) { + console.log(`\n${TAG} ${chalk.red('构建报错')}\n`, error, '\n') + spinner.fail() + process.exit(1) + } + } +})() diff --git a/scripts/rollup.config.ts b/scripts/rollup.config.ts new file mode 100644 index 00000000..813e953b --- /dev/null +++ b/scripts/rollup.config.ts @@ -0,0 +1,68 @@ +import path from 'path' +import type { RollupOptions } from 'rollup' +import copy from 'rollup-plugin-copy' +import nodeResolve from '@rollup/plugin-node-resolve' +import typescript from '@rollup/plugin-typescript' +import commonjs from '@rollup/plugin-commonjs' +import replace from '@rollup/plugin-replace' +import alias from '@rollup/plugin-alias' +import json from '@rollup/plugin-json' +import { builtins, getEnv } from './utils' + +export interface ConfigOptions { + env?: typeof process.env.NODE_ENV + proc: 'main' | 'render' | 'preload' +} + +const compilationInclude = ['electron/**/*.ts'] + +export default function (opts: ConfigOptions) { + const sourcemap = opts.proc === 'render' + const options: RollupOptions = { + input: path.join(__dirname, `../electron/${opts.proc}/index.ts`), + output: { + dir: path.join(__dirname, `../dist/${opts.proc}`), + format: 'cjs', + sourcemap, + }, + plugins: [ + nodeResolve({ + extensions: ['.ts', '.js', 'json'], + }), + commonjs({ + include: compilationInclude + }), + json(), + typescript({ + sourceMap: sourcemap, + noEmitOnError: true, + include: compilationInclude + }), + alias({ + entries: { + '@': path.join(__dirname, '../src'), + }, + }), + copy({ + // 复制 favicon.ico 到指定目录 + targets: [{ src: 'app_favicon.ico', dest: 'dist' }], + }), + replace({ + ...Object.entries({ ...getEnv(), NODE_ENV: opts.env }).reduce( + (acc, [k, v]) => Object.assign(acc, { [`process.env.${k}`]: JSON.stringify(v) }), + {}, + ), + preventAssignment: true, + }), + ], + external: [...builtins(), 'electron'], + onwarn: (warning) => { + // https://github.com/rollup/rollup/issues/1089#issuecomment-365395213 + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + console.error(`(!) ${warning.message}`) + } + }, + } + + return options +} diff --git a/scripts/utils.ts b/scripts/utils.ts new file mode 100644 index 00000000..e07752cb --- /dev/null +++ b/scripts/utils.ts @@ -0,0 +1,43 @@ +import fs from 'node:fs' +import path from 'node:path' +import chalk from 'chalk' +import { get } from 'http' +import { builtinModules } from 'module' +import { parse as parseEnv } from 'dotenv' + +export function getEnv(): Record { + try { + if (getEnv.env) { + return getEnv.env + } + const env = parseEnv(fs.readFileSync(path.join(process.cwd(), '.env'))) + return (getEnv.env = env) + } + catch { + return {} + } +} +getEnv.env = undefined as Record | undefined + +/** node.js builtins module */ +export const builtins = () => + builtinModules.filter(x => !/^_|^(internal|v8|node-inspect)\/|\//.test(x)) + +// 轮询监听vite启动 +export function waitOn(arg0: { port: string | number, interval?: number }) { + return new Promise((resolve) => { + const { port, interval = 149 } = arg0 + const url = `http://localhost:${port}` + let counter = 0 + const timer: NodeJS.Timer = setInterval(() => { + get(url, (res) => { + clearInterval(timer as unknown as number) + console.log('[waitOn]', chalk.green(`"${url}" are already responsive.`)) + resolve(res.statusCode) + }).on('error', (error) => { + console.log(error) + console.log('[waitOn]', `counter: ${counter++}`) + }) + }, interval) + }) +} diff --git a/src/apis/server.ts b/src/apis/server.ts index e185043e..64d34b33 100644 --- a/src/apis/server.ts +++ b/src/apis/server.ts @@ -34,8 +34,11 @@ export interface IAnyObj { export type Fn = (data: FcResponse) => unknown; + +const baseURL = import.meta.env.MODE === 'electron-production' ? import.meta.env.VITE_BASE_PROXY_URL : './'; // 创建 axios 实例 export const server = axios.create({ + baseURL, // API 请求的默认前缀 timeout: 60 * 1000, // 请求超时时间 }); diff --git a/tsconfig.json b/tsconfig.json index c88a583d..5ad27fa3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -33,7 +33,18 @@ }, "lib": ["esnext", "dom", "dom.iterable", "scripthost"] }, - "types": [ "vite/client" ], - "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "vite.config.ts"], + "ts-node": { + "compilerOptions": { + "module": "CommonJS" + } + }, + "types": ["vite/client"], + "include": [ + "env.d.ts", + "src/**/*", + "src/**/*.vue", + "vite.config.ts", + "electron/**/*" + ], "exclude": ["node_modules", "dist"] } diff --git a/vite.config.ts b/vite.config.ts index 1229411d..179aadd2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -22,7 +22,7 @@ export default ({ mode }): UserConfigExport => { VITE_BASE_URL } = env - const baseUrl = mode === 'production' ? VITE_BASE_URL : '/' + const baseUrl = mode === 'micro' ? VITE_BASE_URL : './' return defineConfig({ base: baseUrl, resolve: { @@ -67,45 +67,12 @@ export default ({ mode }): UserConfigExport => { server: { host: "localhost", hmr: true, - open: true, port: 3000, origin: 'http://localhost:3000', headers: { "Access-Control-Allow-Origin": "*", }, proxy: { - "/plugin": { - target: env.VITE_BASE_PROXY_URL, - changeOrigin: true, - ws: false, - secure: false, - }, - "/rag": { - target: env.VITE_BASE_PROXY_URL, - secure: false, - changeOrigin: true, - ws: false, - rewrite: (path: string) => path.replace(/^\/rag/, ""), - }, - "/stream": { - target: env.VITE_BASE_PROXY_URL, - secure: false, - changeOrigin: true, - ws: false, - rewrite: (path: string) => path.replace(/^\/stream/, ""), - }, - "/qabot": { - target: env.VITE_QABOT_URL, - changeOrigin: true, - ws: false, - rewrite: (path: string) => path.replace(/^\/qabot/, ""), - }, - "/test": { - target: env.VITE_BASE_PROXY_URL, - changeOrigin: true, - ws: false, - rewrite: (path: string) => path.replace(/^\/test/, ""), - }, "/api": { target: env.VITE_BASE_PROXY_URL, changeOrigin: true, -- Gitee