create-young-proj 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +7 -1
  3. package/dist/index.mjs +6 -6
  4. package/package.json +1 -1
  5. package/src/index.ts +6 -1
  6. package/template-electron-win7/.vscode/extensions.json +5 -0
  7. package/template-electron-win7/.vscode/settings.json +49 -0
  8. package/template-electron-win7/README.md +65 -0
  9. package/template-electron-win7/RELEASE_NOTES.md +11 -0
  10. package/template-electron-win7/_gitignore +27 -0
  11. package/template-electron-win7/dev-app-update.yml +2 -0
  12. package/template-electron-win7/electron/config/0.local.config.ts +13 -0
  13. package/template-electron-win7/electron/config/1.dev.config.ts +13 -0
  14. package/template-electron-win7/electron/config/2.test.config.ts +13 -0
  15. package/template-electron-win7/electron/config/3.wtest.config.ts +13 -0
  16. package/template-electron-win7/electron/config/4.online.config.ts +13 -0
  17. package/template-electron-win7/electron/config.ts +13 -0
  18. package/template-electron-win7/electron/electron-env.d.ts +58 -0
  19. package/template-electron-win7/electron/main.ts +318 -0
  20. package/template-electron-win7/electron/preload.ts +23 -0
  21. package/template-electron-win7/electron/update.ts +78 -0
  22. package/template-electron-win7/electron-builder.yaml +67 -0
  23. package/template-electron-win7/env/.env +1 -0
  24. package/template-electron-win7/env/.env.development +9 -0
  25. package/template-electron-win7/env/.env.production +9 -0
  26. package/template-electron-win7/eslint.config.mjs +33 -0
  27. package/template-electron-win7/index.html +16 -0
  28. package/template-electron-win7/package.json +71 -0
  29. package/template-electron-win7/public/icon.ico +0 -0
  30. package/template-electron-win7/scripts/afterPack.mjs +36 -0
  31. package/template-electron-win7/scripts/build.mjs +55 -0
  32. package/template-electron-win7/src/App.vue +23 -0
  33. package/template-electron-win7/src/auto-imports.d.ts +305 -0
  34. package/template-electron-win7/src/components/UpdateDialog.vue +166 -0
  35. package/template-electron-win7/src/components.d.ts +18 -0
  36. package/template-electron-win7/src/layouts/blank.vue +11 -0
  37. package/template-electron-win7/src/layouts/default.vue +13 -0
  38. package/template-electron-win7/src/main.ts +36 -0
  39. package/template-electron-win7/src/modules/1-router.ts +72 -0
  40. package/template-electron-win7/src/modules/2-pinia.ts +13 -0
  41. package/template-electron-win7/src/styles/variables.scss +8 -0
  42. package/template-electron-win7/src/types/global.d.ts +0 -0
  43. package/template-electron-win7/src/utils/env.ts +4 -0
  44. package/template-electron-win7/src/utils/ls.ts +118 -0
  45. package/template-electron-win7/src/views/[...all_404].vue +539 -0
  46. package/template-electron-win7/src/views/index.vue +34 -0
  47. package/template-electron-win7/src/vite-env.d.ts +27 -0
  48. package/template-electron-win7/tsconfig.json +29 -0
  49. package/template-electron-win7/tsconfig.node.json +11 -0
  50. package/template-electron-win7/uno.config.ts +32 -0
  51. package/template-electron-win7/vite.config.ts +78 -0
  52. package/template-electron-win7/yarn.lock +5964 -0
  53. package/template-nuxt-admin/error.vue +3 -3
  54. package/template-nuxt-admin/nuxt.config.ts +20 -7
  55. package/template-nuxt-admin/package.json +5 -3
  56. package/template-nuxt-admin/yarn.lock +3438 -2586
  57. package/template-nuxt-website/app.vue +45 -1
  58. package/template-nuxt-website/layouts/default.vue +18 -16
  59. package/template-nuxt-website/layouts/home.vue +14 -12
  60. package/template-nuxt-website/layouts/tabbar.vue +18 -16
  61. package/template-nuxt-website/nuxt.config.ts +20 -5
  62. package/template-nuxt-website/package.json +2 -1
  63. package/template-nuxt-website/yarn.lock +4677 -3598
@@ -0,0 +1,318 @@
1
+ import path from 'node:path'
2
+ import Store from 'electron-store'
3
+ import { BrowserWindow, Menu, Notification, Tray, app, globalShortcut, ipcMain, nativeImage } from 'electron'
4
+ import Logger from 'electron-log'
5
+ import AutoLaunch from 'auto-launch'
6
+ import { isDev } from 'electron-util/main'
7
+ import { name } from '../package.json'
8
+ import { checkUpdate, triggerCheckUpdate } from './update'
9
+
10
+ // The built directory structure
11
+ //
12
+ // ├─┬─┬ dist
13
+ // │ │ └── index.html
14
+ // │ │
15
+ // │ ├─┬ dist-electron
16
+ // │ │ ├── main.js
17
+ // │ │ └── preload.js
18
+ // │
19
+
20
+ process.env.DIST = path.join(__dirname, '../dist')
21
+ process.env.VITE_PUBLIC = path.join(process.env.DIST, '../public')
22
+
23
+ if (app.isPackaged) {
24
+ process.env.VITE_PUBLIC = process.env.DIST
25
+
26
+ const ex = process.execPath
27
+
28
+ const autoLaunch = new AutoLaunch({
29
+ name,
30
+ path: ex,
31
+ })
32
+
33
+ autoLaunch
34
+ .enable()
35
+ .then(() => {
36
+ Logger.info('开机自启设置成功')
37
+ })
38
+ .catch((err) => {
39
+ Logger.error('开机自启设置失败:', err)
40
+ })
41
+ }
42
+
43
+ const store = new Store()
44
+
45
+ const ICON = nativeImage.createFromPath(path.join(process.env.VITE_PUBLIC, 'icon.ico'))
46
+
47
+ // 窗口
48
+ let win: BrowserWindow | null
49
+ // 托盘
50
+ let tray: Tray | null
51
+ let trayFlashInterval: NodeJS.Timeout | null
52
+ let trayFlag = false
53
+
54
+ /**
55
+ * 内嵌应用的地址
56
+ */
57
+ let VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL
58
+ /**
59
+ * 是否允许切换环境
60
+ * ? 非正式环境都允许切换环境(打开调试控制台)
61
+ */
62
+ let ENABLE_SWITCH_ENV = isDev
63
+
64
+ async function loadServe() {
65
+ if (!win) {
66
+ throw new Error('窗口未创建')
67
+ }
68
+
69
+ try {
70
+ const serve = store.get('VITE_DEV_SERVER_URL') as string
71
+ if (serve && ENABLE_SWITCH_ENV) {
72
+ VITE_DEV_SERVER_URL = serve
73
+ Logger.log('🚀 ~ load address from config file:', VITE_DEV_SERVER_URL)
74
+
75
+ await win.loadURL(VITE_DEV_SERVER_URL)
76
+ }
77
+ else if (VITE_DEV_SERVER_URL) {
78
+ Logger.log('🚀 ~ load address from build injection:', VITE_DEV_SERVER_URL)
79
+
80
+ await win.loadURL(VITE_DEV_SERVER_URL)
81
+ }
82
+ else {
83
+ await win.loadFile(path.join(process.env.DIST as string, 'index.html'))
84
+ }
85
+
86
+ // 窗口加载完成后最大化
87
+ win.maximize()
88
+ }
89
+ catch (error) {
90
+ console.error('🚀 ~ error:', error)
91
+ }
92
+ }
93
+
94
+ /**
95
+ * 创建窗口
96
+ */
97
+ async function createWindow() {
98
+ win = new BrowserWindow({
99
+ icon: ICON,
100
+ webPreferences: {
101
+ preload: path.join(__dirname, 'preload.js'),
102
+ sandbox: false,
103
+ },
104
+ // 隐藏菜单栏
105
+ autoHideMenuBar: true,
106
+ })
107
+
108
+ // 检查更新
109
+ try {
110
+ checkUpdate(win)
111
+ }
112
+ catch (error) {
113
+ Logger.error(error)
114
+ }
115
+
116
+ // 隐藏窗口而不是退出,保持后台常驻
117
+ win.on('close', (e) => {
118
+ e.preventDefault()
119
+ win?.hide()
120
+ })
121
+
122
+ // Test active push message to Renderer-process.
123
+ win.webContents.on('did-finish-load', () => {
124
+ win?.webContents.send('main-process-message', new Date().toLocaleString())
125
+ // 版本更新
126
+ })
127
+
128
+ // 读取配置,加载窗口
129
+ loadServe()
130
+ }
131
+
132
+ /**
133
+ * 创建托盘
134
+ */
135
+ async function createTray() {
136
+ tray = new Tray(ICON)
137
+ tray.setToolTip('YourApp1')
138
+
139
+ const BASE_MENU: Electron.MenuItemConstructorOptions[] = [
140
+ {
141
+ type: 'normal',
142
+ label: '检查更新',
143
+ click: () => {
144
+ triggerCheckUpdate()
145
+ },
146
+ },
147
+ {
148
+ type: 'separator',
149
+ },
150
+ {
151
+ label: '退出应用',
152
+ type: 'normal',
153
+ click: () => {
154
+ // 彻底退出应用
155
+ app.exit(0)
156
+ win = null
157
+ },
158
+ },
159
+ ]
160
+
161
+ const contextMenu = Menu.buildFromTemplate(
162
+ ENABLE_SWITCH_ENV && ServerConfig.length
163
+ ? [
164
+ {
165
+ label: '切换服务地址',
166
+ type: 'submenu',
167
+ submenu: ServerConfig.map(v => ({
168
+ label: v.label,
169
+ type: 'radio',
170
+ checked: v.value === VITE_DEV_SERVER_URL,
171
+ click: () => {
172
+ store.set('VITE_DEV_SERVER_URL', v.value)
173
+ loadServe()
174
+ },
175
+ }),
176
+ ),
177
+ },
178
+ ...BASE_MENU,
179
+ ]
180
+ : BASE_MENU,
181
+ )
182
+
183
+ tray.setContextMenu(contextMenu)
184
+
185
+ // 点击托盘图标显示窗口
186
+ tray.on('click', () => {
187
+ trayFlashInterval && clearInterval(trayFlashInterval)
188
+ tray?.setImage(ICON)
189
+ tray?.setToolTip('YourApp1')
190
+
191
+ if (!win?.isVisible()) {
192
+ win?.maximize()
193
+ }
194
+
195
+ win?.focus()
196
+ })
197
+ }
198
+
199
+ /**
200
+ * 注册快捷键
201
+ */
202
+ function registerShortcuts() {
203
+ if (ENABLE_SWITCH_ENV) {
204
+ // 在编辑器中打开存储的配置文件
205
+ globalShortcut.register('CommandOrControl+Shift+Alt+L', () => {
206
+ store.openInEditor()
207
+ })
208
+
209
+ // 打开控制台
210
+ globalShortcut.register('CommandOrControl+Shift+I', () => {
211
+ win?.webContents.toggleDevTools()
212
+ })
213
+ }
214
+ }
215
+
216
+ const ServerConfig: SelectOptionItem[] = []
217
+
218
+ /**
219
+ * 读取配置文件
220
+ */
221
+ async function readConfig() {
222
+ const allConfigs = await import.meta.glob<{
223
+ default: YoungAppConfig
224
+ }>('./config/**.ts', { eager: true })
225
+ Logger.log('🚀 ~ readConfig ~ allConfigs:', allConfigs)
226
+
227
+ ServerConfig.length = 0
228
+
229
+ for (const { default: m } of Object.values(allConfigs)) {
230
+ ServerConfig.push({
231
+ label: m.VITE_APP_LABEL,
232
+ value: m.VITE_APP_SERVER_URL,
233
+ })
234
+ }
235
+
236
+ if (app.isPackaged) {
237
+ try {
238
+ const config = await (await import('./config.ts')).default as YoungAppConfig
239
+ Logger.log('🚀 ~ readConfig ~ config:', config)
240
+
241
+ ENABLE_SWITCH_ENV = config.VITE_APP_MODE !== 'online'
242
+ VITE_DEV_SERVER_URL = config.VITE_APP_SERVER_URL
243
+ }
244
+ catch (error) {
245
+ Logger.error('🚀 ~ readConfig ~ error:', error)
246
+ }
247
+ }
248
+ else {
249
+ VITE_DEV_SERVER_URL = ServerConfig[0].value
250
+ Logger.log('🚀 ~ dev mode, set local addr as default', VITE_DEV_SERVER_URL)
251
+ }
252
+ }
253
+
254
+ async function init() {
255
+ // ! 如果不是嵌入外部网页,而使用一体化开发,注释下面的一行代码
256
+ await readConfig()
257
+
258
+ createWindow()
259
+ createTray()
260
+ registerShortcuts()
261
+ }
262
+
263
+ app.on('activate', () => {
264
+ // On OS X it's common to re-create a window in the app when the
265
+ // dock icon is clicked and there are no other windows open.
266
+ if (BrowserWindow.getAllWindows().length === 0) {
267
+ createWindow()
268
+ }
269
+ })
270
+
271
+ app.whenReady().then(init)
272
+
273
+ /**
274
+ * ipc通信
275
+ */
276
+ /** 打开控制台 */
277
+ ipcMain.on('openDevtools', (event: Electron.IpcMainEvent) => {
278
+ event.sender.openDevTools()
279
+ })
280
+
281
+ /** 获取electron-store的配置文件 */
282
+ ipcMain.handle(
283
+ 'getStore',
284
+ (_event: Electron.IpcMainInvokeEvent, arg: string) => {
285
+ return store.get(arg)
286
+ },
287
+ )
288
+
289
+ /** 设置electron-store的配置文件 */
290
+ ipcMain.on(
291
+ 'setStore',
292
+ (_event: Electron.IpcMainInvokeEvent, ...args: any[]) => {
293
+ ; (store.set as (...args: any[]) => void)(...args)
294
+ },
295
+ )
296
+
297
+ /** 有新消息(托盘闪烁) */
298
+ ipcMain.on('newMessage', (_event: Electron.IpcMainEvent, ...args: any) => {
299
+ Logger.log('🚀 ~ ipcMain.on ~ args:', args)
300
+
301
+ const NOTIFICATION_TITLE = '通知(主进程)'
302
+ const NOTIFICATION_BODY = 'Notification from the Main process'
303
+
304
+ new Notification({
305
+ title: NOTIFICATION_TITLE,
306
+ body: NOTIFICATION_BODY,
307
+ }).show()
308
+
309
+ if (tray) {
310
+ trayFlashInterval && clearInterval(trayFlashInterval)
311
+
312
+ trayFlashInterval = setInterval(() => {
313
+ trayFlag = !trayFlag
314
+ tray?.setImage(trayFlag ? nativeImage.createEmpty() : ICON)
315
+ tray?.setToolTip('You have a new message')
316
+ }, 300)
317
+ }
318
+ })
@@ -0,0 +1,23 @@
1
+ import { contextBridge, ipcRenderer } from 'electron'
2
+ // --------- Expose some API to the Renderer process ---------
3
+ contextBridge.exposeInMainWorld('ipcRenderer', {
4
+ on(...args: Parameters<typeof ipcRenderer.on>) {
5
+ const [channel, listener] = args
6
+ return ipcRenderer.on(channel, (event, ...args) => listener(event, ...args))
7
+ },
8
+ off(...args: Parameters<typeof ipcRenderer.off>) {
9
+ const [channel, ...omit] = args
10
+ return ipcRenderer.off(channel, ...omit)
11
+ },
12
+ send(...args: Parameters<typeof ipcRenderer.send>) {
13
+ const [channel, ...omit] = args
14
+ return ipcRenderer.send(channel, ...omit)
15
+ },
16
+ invoke(...args: Parameters<typeof ipcRenderer.invoke>) {
17
+ const [channel, ...omit] = args
18
+ return ipcRenderer.invoke(channel, ...omit)
19
+ },
20
+
21
+ // You can expose other APTs you need here.
22
+ // ...
23
+ })
@@ -0,0 +1,78 @@
1
+ import { autoUpdater } from 'electron-updater'
2
+ import type { BrowserWindow } from 'electron'
3
+ import { ipcMain } from 'electron'
4
+ import log from 'electron-log' // 如果没有自己封装
5
+
6
+ let mainWindow: BrowserWindow | null
7
+ // 封装更新相关的进程通信方法
8
+ function sendUpdateMessage(opt: { cmd: IPCOneWay, data: any }) {
9
+ if (!mainWindow)
10
+ return
11
+ mainWindow.webContents.send(opt.cmd, opt.data)
12
+ }
13
+ export function checkUpdate(win: BrowserWindow | null) {
14
+ if (!win)
15
+ return
16
+ mainWindow = win
17
+ // 关闭自动更新
18
+ autoUpdater.autoDownload = false
19
+ autoUpdater.forceDevUpdateConfig = true
20
+ // 日志记录设置
21
+ log.transports.file.level = 'debug'
22
+ autoUpdater.logger = log
23
+ // 监听升级失败事件
24
+ autoUpdater.on('error', (error) => {
25
+ sendUpdateMessage({
26
+ cmd: 'update-error',
27
+ data: error,
28
+ })
29
+ })
30
+ // 监听发现可用更新事件
31
+ autoUpdater.on('update-available', (message) => {
32
+ sendUpdateMessage({
33
+ cmd: 'update-available',
34
+ data: message,
35
+ })
36
+ })
37
+ // 监听没有可用更新事件
38
+ autoUpdater.on('update-not-available', (message) => {
39
+ sendUpdateMessage({
40
+ cmd: 'update-not-available',
41
+ data: message,
42
+ })
43
+ })
44
+
45
+ // 更新下载进度事件
46
+ autoUpdater.on('download-progress', (progressObj) => {
47
+ sendUpdateMessage({
48
+ cmd: 'download-progress',
49
+ data: progressObj,
50
+ })
51
+ })
52
+ // 监听下载完成事件
53
+ autoUpdater.on('update-downloaded', (releaseObj) => {
54
+ sendUpdateMessage({
55
+ cmd: 'update-downloaded',
56
+ data: releaseObj,
57
+ })
58
+ // 退出并安装更新包
59
+ autoUpdater.quitAndInstall()
60
+ })
61
+
62
+ // 接收渲染进程消息,开始检查更新
63
+ ipcMain.on('check-update', () => {
64
+ // 执行自动更新检查
65
+ console.log('页面请求检查更新')
66
+ autoUpdater.checkForUpdates()
67
+ })
68
+
69
+ // 触发更新
70
+ ipcMain.on('update-app', () => {
71
+ autoUpdater.downloadUpdate()
72
+ })
73
+ }
74
+
75
+ export function triggerCheckUpdate() {
76
+ console.log('托盘手动检查更新')
77
+ autoUpdater.checkForUpdates()
78
+ }
@@ -0,0 +1,67 @@
1
+ # 包名
2
+ appId: com.electron.your-app-1
3
+ # 应用展示名称,用于桌面显示
4
+ productName: 我是你的应用名称
5
+
6
+ asar: true
7
+ # asarUnpack:
8
+ # - public/**/*
9
+
10
+ # 打包之后执行
11
+ afterPack: ./scripts/afterPack.mjs
12
+
13
+ directories:
14
+ output: release/${version}
15
+
16
+ files:
17
+ - dist
18
+ - dist-electron
19
+
20
+ mac:
21
+ target:
22
+ - dmg
23
+ icon: ./public/icon.ico
24
+ artifactName: ${productName}-Mac-${version}-Installer.${ext}
25
+
26
+ win:
27
+ target:
28
+ - target: nsis
29
+ # 现在基本上都是 64 位的机器
30
+ arch:
31
+ - x64
32
+ # 如果确实需要打包成 32 位的,取消注释即可
33
+ # - ia32
34
+ icon: ./public/icon.ico
35
+ artifactName: ${productName}-Windows-${version}-Setup.${ext}
36
+
37
+ nsis:
38
+ # 一键安装
39
+ oneClick: false
40
+ # 卸载时删除用户数据
41
+ deleteAppDataOnUninstall: true
42
+ # 是否开启安装时权限限制(此电脑或当前用户)
43
+ perMachine: true
44
+ # 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序
45
+ allowElevation: true
46
+ # 允许修改安装目录
47
+ allowToChangeInstallationDirectory: true
48
+ # 创建桌面图标
49
+ createDesktopShortcut: true
50
+ # 创建开始菜单图标
51
+ createStartMenuShortcut: true
52
+ # 安装图标
53
+ installerIcon: ./public/icon.ico
54
+
55
+ linux:
56
+ target:
57
+ - AppImage
58
+ icon: ./public/icon.ico
59
+ artifactName: ${productName}-Linux-${version}.${ext}
60
+
61
+ releaseInfo:
62
+ releaseNotesFile: RELEASE_NOTES.md
63
+
64
+ publish:
65
+ - provider: generic
66
+ # 更新地址(最新安装包存放的地址)
67
+ url: http://192.168.50.208:9876/electron-app/your-app-1/update
@@ -0,0 +1 @@
1
+ VITE_APP_TITLE=应用名称
@@ -0,0 +1,9 @@
1
+ ###
2
+ # @Author: zhangyang
3
+ # @Date: 2024-07-31 09:14:08
4
+ # @LastEditTime: 2024-07-31 19:47:10
5
+ # @Description:
6
+ # @LastEditors: zhangyang
7
+ # Copyright (c) 2024 to current by BluesYoung-web, All Rights Reserved.
8
+ ###
9
+ VITE_BASE_URL=/api
@@ -0,0 +1,9 @@
1
+ ###
2
+ # @Author: zhangyang
3
+ # @Date: 2024-07-31 09:14:08
4
+ # @LastEditTime: 2024-07-31 19:11:25
5
+ # @Description:
6
+ # @LastEditors: zhangyang
7
+ # Copyright (c) 2024 to current by BluesYoung-web, All Rights Reserved.
8
+ ###
9
+ VITE_BASE_URL=/api
@@ -0,0 +1,33 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-11-01 10:13:50
4
+ * @LastEditTime: 2024-08-02 09:01:58
5
+ * @Description:
6
+ */
7
+ import antfu from '@antfu/eslint-config'
8
+
9
+ export default antfu({
10
+ overrides: {
11
+ vue: {
12
+ 'vue/valid-v-model': 'off',
13
+ },
14
+ typescript: {
15
+ 'ts/no-use-before-define': 'off',
16
+ 'ts/no-unused-vars': 'off',
17
+ 'ts/ban-types': 'off',
18
+ 'ts/ban-ts-comment': 'off',
19
+ 'ts/no-unused-expressions': 'off',
20
+ },
21
+ },
22
+ rules: {
23
+ 'no-console': 'off',
24
+ 'node/prefer-global/process': 'off',
25
+ 'unused-imports/no-unused-vars': 'off',
26
+ 'no-throw-literal': 'off',
27
+ 'antfu/consistent-list-newline': 'off',
28
+ 'style/jsx-indent': 'off',
29
+ },
30
+ ignores: [
31
+ 'public',
32
+ ],
33
+ })
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta
7
+ http-equiv="Content-Security-Policy"
8
+ content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'"
9
+ />
10
+ <title>%VITE_APP_TITLE%</title>
11
+ </head>
12
+ <body>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "your-app-1",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "description": "an electron app",
6
+ "author": "<bluesyoung_web@163.com>",
7
+ "main": "dist-electron/main.js",
8
+ "scripts": {
9
+ "dev": "vite --mode development",
10
+ "pro": "vite --mode production",
11
+ "build": "node ./scripts/build.mjs",
12
+ "preview": "vite preview",
13
+ "lint": "eslint .",
14
+ "lint:fix": "eslint . --fix",
15
+ "postinstall": "simple-git-hooks"
16
+ },
17
+ "dependencies": {
18
+ "@element-plus/icons-vue": "^2.3.1",
19
+ "@vueuse/core": "^10.11.0",
20
+ "auto-launch": "^5.0.6",
21
+ "axios": "^1.6.8",
22
+ "electron-log": "^5.1.6",
23
+ "electron-store": "^8.2.0",
24
+ "electron-updater": "^6.2.1",
25
+ "element-plus": "^2.7.0",
26
+ "pinia": "^2.1.7",
27
+ "vue": "^3.4.21",
28
+ "vue-router": "^4.3.0"
29
+ },
30
+ "devDependencies": {
31
+ "@antfu/eslint-config": "^2.24.0",
32
+ "@iconify/json": "^2.2.232",
33
+ "@types/auto-launch": "^5.0.5",
34
+ "@types/dompurify": "^3.0.5",
35
+ "@unocss/reset": "^0.61.8",
36
+ "@vitejs/plugin-vue": "^5.0.4",
37
+ "@vitejs/plugin-vue-jsx": "^4.0.0",
38
+ "compare-versions": "^6.1.1",
39
+ "consola": "^3.2.3",
40
+ "dompurify": "^3.1.6",
41
+ "electron": "^22.1.4",
42
+ "electron-builder": "^24.13.3",
43
+ "electron-util": "^0.18.1",
44
+ "eslint": "^9.8.0",
45
+ "execa": "^9.3.1",
46
+ "lint-staged": "^15.2.7",
47
+ "marked": "^14.1.0",
48
+ "mdbox": "^0.1.0",
49
+ "prompts": "^2.4.2",
50
+ "sass": "^1.75.0",
51
+ "simple-git-hooks": "^2.11.1",
52
+ "tasuku": "^2.0.1",
53
+ "typescript": "^5.2.2",
54
+ "unocss": "0.58",
55
+ "unplugin-auto-import": "^0.17.5",
56
+ "unplugin-vue-components": "^0.26.0",
57
+ "vite": "^5.1.6",
58
+ "vite-plugin-electron": "^0.28.4",
59
+ "vite-plugin-electron-renderer": "^0.14.5",
60
+ "vite-plugin-optimize-persist": "^0.1.2",
61
+ "vite-plugin-package-config": "^0.1.1",
62
+ "vite-plugin-pages": "^0.32.3",
63
+ "vite-plugin-vue-layouts": "^0.11.0"
64
+ },
65
+ "simple-git-hooks": {
66
+ "pre-commit": "pnpm lint-staged"
67
+ },
68
+ "lint-staged": {
69
+ "*": "eslint --fix"
70
+ }
71
+ }
@@ -0,0 +1,36 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2024-08-23 11:53:06
4
+ * @LastEditTime: 2024-08-23 12:11:51
5
+ * @Description:
6
+ * @LastEditors: zhangyang
7
+ * Copyright (c) 2024 to current by BluesYoung-web, All Rights Reserved.
8
+ */
9
+ import { readdir, rm } from 'node:fs/promises'
10
+ import { resolve } from 'node:path'
11
+
12
+ export default async function (context) {
13
+ console.log('🚀 ~ afterPack context:', context)
14
+
15
+ const localeDir = resolve(context.appOutDir, 'locales')
16
+
17
+ const saveLocales = ['zh', 'en']
18
+
19
+ try {
20
+ const files = await readdir(localeDir)
21
+ // 删除无用的语言文件
22
+ const unusedFiles = files.filter(file => !saveLocales.some(l => file.startsWith(l)))
23
+ console.log('🚀 ~ unusedFiles:', unusedFiles)
24
+
25
+ for (const file of unusedFiles) {
26
+ await rm(resolve(localeDir, file), { recursive: true }).catch((error) => {
27
+ console.error('🚀 ~ rm .pak fail:', error)
28
+ })
29
+ }
30
+ }
31
+ catch (error) {
32
+ console.error('🚀 ~ error:', error)
33
+ }
34
+
35
+ console.log('🚀 ~ afterPack end')
36
+ }