create-young-proj 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }