2025-08-19 14:33:59 +08:00
|
|
|
|
import { resolve } from 'path'
|
|
|
|
|
|
import { defineConfig, externalizeDepsPlugin, bytecodePlugin } from 'electron-vite'
|
|
|
|
|
|
import vue from '@vitejs/plugin-vue'
|
|
|
|
|
|
import AutoImport from 'unplugin-auto-import/vite'
|
|
|
|
|
|
import Components from 'unplugin-vue-components/vite'
|
|
|
|
|
|
import tsconfigPaths from 'vite-tsconfig-paths'
|
|
|
|
|
|
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
|
|
|
|
|
|
|
2025-09-23 15:20:47 +08:00
|
|
|
|
export default defineConfig(({ command }) => {
|
|
|
|
|
|
const isProduction = command === 'build'
|
|
|
|
|
|
const enableObfuscation = process.env.OBFUSCATE === 'true'
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
main: {
|
|
|
|
|
|
resolve: {
|
|
|
|
|
|
alias: {
|
|
|
|
|
|
'@': resolve('src'),
|
|
|
|
|
|
'@renderer': resolve('src/renderer/src')
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
plugins: [externalizeDepsPlugin(), bytecodePlugin(), tsconfigPaths()]
|
2025-08-19 14:33:59 +08:00
|
|
|
|
},
|
2025-09-23 15:20:47 +08:00
|
|
|
|
preload: {
|
|
|
|
|
|
plugins: [externalizeDepsPlugin(), bytecodePlugin()],
|
|
|
|
|
|
resolve: {
|
|
|
|
|
|
alias: {
|
|
|
|
|
|
'@': resolve('src'),
|
|
|
|
|
|
'@renderer': resolve('src/renderer/src')
|
|
|
|
|
|
}
|
2025-08-19 14:33:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-09-23 15:20:47 +08:00
|
|
|
|
renderer: {
|
|
|
|
|
|
resolve: {
|
|
|
|
|
|
alias: {
|
|
|
|
|
|
'@': resolve('src'),
|
|
|
|
|
|
'@renderer': resolve('src/renderer/src')
|
2025-08-19 14:33:59 +08:00
|
|
|
|
}
|
2025-09-23 15:20:47 +08:00
|
|
|
|
},
|
|
|
|
|
|
plugins: [
|
|
|
|
|
|
bytecodePlugin(),
|
|
|
|
|
|
vue({
|
|
|
|
|
|
template: {
|
|
|
|
|
|
compilerOptions: {
|
|
|
|
|
|
// 将webview标签标记为自定义元素
|
|
|
|
|
|
isCustomElement: (tag) => ['webview'].includes(tag)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}),
|
|
|
|
|
|
AutoImport({
|
|
|
|
|
|
imports: [
|
|
|
|
|
|
'vue',
|
|
|
|
|
|
{
|
|
|
|
|
|
'naive-ui': ['useDialog', 'useMessage', 'useNotification', 'useLoadingBar']
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}),
|
|
|
|
|
|
Components({
|
|
|
|
|
|
resolvers: [NaiveUiResolver()]
|
|
|
|
|
|
})
|
|
|
|
|
|
],
|
|
|
|
|
|
build: {
|
|
|
|
|
|
// 为生产环境添加代码混淆和优化
|
|
|
|
|
|
...(isProduction ? {
|
|
|
|
|
|
minify: 'terser',
|
|
|
|
|
|
terserOptions: {
|
|
|
|
|
|
compress: {
|
|
|
|
|
|
// 安全的压缩选项 - 避免破坏Vue响应式系统
|
|
|
|
|
|
drop_console: enableObfuscation, // 根据环境变量决定是否移除console
|
|
|
|
|
|
drop_debugger: true, // 移除debugger
|
|
|
|
|
|
pure_funcs: enableObfuscation ? ['console.log', 'console.info', 'console.debug', 'console.warn'] : [],
|
|
|
|
|
|
passes: 1, // 只进行一轮压缩,避免过度优化
|
|
|
|
|
|
keep_fargs: true, // 保留函数参数,对Vue很重要
|
|
|
|
|
|
// 关闭所有unsafe选项,确保Vue和响应式系统正常工作
|
|
|
|
|
|
unsafe: false,
|
|
|
|
|
|
unsafe_comps: false,
|
|
|
|
|
|
unsafe_Function: false,
|
|
|
|
|
|
unsafe_math: false,
|
|
|
|
|
|
unsafe_symbols: false,
|
|
|
|
|
|
unsafe_methods: false,
|
|
|
|
|
|
unsafe_proto: false,
|
|
|
|
|
|
unsafe_regexp: false,
|
|
|
|
|
|
unsafe_undefined: false,
|
|
|
|
|
|
// 保留一些对Vue重要的功能
|
|
|
|
|
|
keep_classnames: true, // 保留类名
|
|
|
|
|
|
keep_fnames: true, // 保留函数名,对Vue组件很重要
|
|
|
|
|
|
// 移除条件编译,避免影响动态代码
|
|
|
|
|
|
global_defs: {}
|
|
|
|
|
|
},
|
|
|
|
|
|
mangle: enableObfuscation ? {
|
|
|
|
|
|
// 更保守的混淆策略
|
|
|
|
|
|
properties: false, // 完全关闭属性名混淆,避免破坏Vue
|
|
|
|
|
|
// 保留更多重要的标识符
|
|
|
|
|
|
reserved: [
|
|
|
|
|
|
// Vue 核心
|
|
|
|
|
|
'Vue', 'vue', 'VNode', 'Component', 'Directive', 'Plugin', 'App', 'app',
|
|
|
|
|
|
'reactive', 'ref', 'computed', 'watch', 'watchEffect', 'onMounted', 'onUnmounted',
|
|
|
|
|
|
'provide', 'inject', 'createApp', 'mount', 'unmount', 'nextTick',
|
|
|
|
|
|
// Vue Router
|
|
|
|
|
|
'router', 'route', 'useRouter', 'useRoute', 'RouterView', 'RouterLink',
|
|
|
|
|
|
// Pinia
|
|
|
|
|
|
'pinia', 'store', 'useStore', 'defineStore', 'storeToRefs',
|
|
|
|
|
|
// Naive UI 相关
|
|
|
|
|
|
'naive', 'NaiveUi', 'n-', 'NButton', 'NInput', 'NForm', 'NSelect', 'NModal',
|
|
|
|
|
|
'NCard', 'NLayout', 'NSpace', 'NGrid', 'NGridItem', 'NIcon', 'NText',
|
|
|
|
|
|
'useDialog', 'useMessage', 'useNotification', 'useLoadingBar',
|
|
|
|
|
|
// Electron 相关
|
|
|
|
|
|
'ElectronAPI', 'electron', 'ipcRenderer', 'contextBridge', 'electronAPI',
|
|
|
|
|
|
// 通用保留
|
|
|
|
|
|
'require', 'exports', 'module', '__dirname', '__filename',
|
|
|
|
|
|
'window', 'document', 'global', 'process', 'Buffer',
|
|
|
|
|
|
// 保留以$开头的Vue特殊属性
|
|
|
|
|
|
'$', '$emit', '$props', '$attrs', '$slots', '$refs', '$parent', '$root',
|
|
|
|
|
|
// 保留一些常用的方法名
|
|
|
|
|
|
'toString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf',
|
|
|
|
|
|
// 保留事件相关
|
|
|
|
|
|
'addEventListener', 'removeEventListener', 'dispatchEvent'
|
|
|
|
|
|
]
|
|
|
|
|
|
} : false,
|
|
|
|
|
|
format: {
|
|
|
|
|
|
// 更安全的格式化选项
|
|
|
|
|
|
comments: false, // 移除注释
|
|
|
|
|
|
beautify: false, // 不美化代码
|
|
|
|
|
|
// 使用更保守的格式化设置
|
|
|
|
|
|
ascii_only: false, // 不强制ASCII,避免中文问题
|
|
|
|
|
|
wrap_iife: false, // 不包装IIFE,避免作用域问题
|
|
|
|
|
|
semicolons: true // 保留分号,确保代码正确性
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
rollupOptions: {
|
|
|
|
|
|
output: {
|
|
|
|
|
|
// 文件名混淆保持简单
|
|
|
|
|
|
chunkFileNames: enableObfuscation ?
|
|
|
|
|
|
'assets/c[hash:8].js' :
|
|
|
|
|
|
'assets/[name]-[hash].js',
|
|
|
|
|
|
entryFileNames: enableObfuscation ?
|
|
|
|
|
|
'assets/e[hash:8].js' :
|
|
|
|
|
|
'assets/[name]-[hash].js',
|
|
|
|
|
|
assetFileNames: enableObfuscation ?
|
|
|
|
|
|
'assets/a[hash:8].[ext]' :
|
|
|
|
|
|
'assets/[name]-[hash].[ext]'
|
|
|
|
|
|
}
|
2025-08-19 14:33:59 +08:00
|
|
|
|
}
|
2025-09-23 15:20:47 +08:00
|
|
|
|
} : {})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-19 14:33:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
})
|