A:调整构建

This commit is contained in:
jimmy committed 2025-08-11 23:25:23 +08:00
1 parent 4d60f349df
commit 59367c7880
15 files changed
+156 -54

No files matched your search

+2 -1
View File
@@ -5,7 +5,8 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"build": "vite build",
"build-with-types": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"test:unit": "vitest",
"build-only": "vite build",
+5 -4
View File
@@ -8,7 +8,7 @@ import { ref, onMounted, provide } from 'vue'
import { NButton } from 'naive-ui'
import { NConfigProvider, NGlobalStyle, NMessageProvider, NLoadingBarProvider, NDialogProvider } from 'naive-ui'
import { useThemeStore } from '@/stores/theme'
import NetworkConnectionPanel1 from '@/components/NetworkConnectionPanel1.vue'
import NetworkConnectionPanel2 from '@/components/NetworkConnectionPanel2.vue'
import MainLayout from './layouts/MainLayout.vue'
const router = useRouter()
@@ -30,7 +30,7 @@ const route = useRoute()
// 子路由列表
const subRouteLists: subRouteList = []
// 遍历路由page列表进行路由渲染
Object.keys(routes).map((path) => {
Object.keys(routes).map((path: string) => {
if ('.vue' === PathUtils.extname(path).trim()) {
const fileName = PathUtils.basename(path).split('.')[0]
const s = StringUtils.toCustomCase(fileName).toLowerCase().split('-')[0]
@@ -88,12 +88,13 @@ const navPosition = ref({ x: 10, y: 10 }) // 默认位置
const dragOffset = ref({ x: 0, y: 0 })
// 拖拽相关函数
function startDrag(event) {
function startDrag(event: MouseEvent) {
if (event.target.closest('.drag-handle')) {
isDragging.value = true
// 计算鼠标与元素左上角的偏移量
const navElement = navRef.value
if (!navElement) return
const rect = navElement.getBoundingClientRect()
dragOffset.value = {
x: event.clientX - rect.left,
@@ -105,7 +106,7 @@ function startDrag(event) {
}
}
function onDrag(event) {
function onDrag(event: MouseEvent) {
if (isDragging.value) {
// 计算新位置
navPosition.value = {
@@ -17,11 +17,11 @@ const bridge = CSharpBridgeV2.getBridge()
const useWebSocket = useWebSocketStore()
const newVar = (data) => {
logN.warning('后端返回的参数', module.name, data)
module.result = JSON.stringify(data, null, 2)
const newVar = (data: any) => {
logN.warning('后端返回的参数', modules.value[0]?.name, data)
modules.value[0].result = JSON.stringify(data, null, 2)
useWebSocket.unsubscribe(module.name)
useWebSocket.unsubscribe(modules.value[0]?.name)
}
/**
* 指令触发
@@ -36,12 +36,12 @@ const invokeCommand = async (module: CommandType) => {
useWebSocket.send(module.name)
} else {
try {
bridge.send(module.name, params, (data) => {
bridge?.send(module.name, params, (data: any) => {
logN.warning('后端返回的参数', module.name, data)
module.result = JSON.stringify(data, null, 2)
})
} catch (error) {
console.error(err)
console.error(error)
module.result = `Error: ${error}`
}
}
@@ -223,8 +223,8 @@ import {
NButton,
NIcon,
NSpace,
FormInst,
FormRules,
type FormInst,
type FormRules,
useMessage,
} from 'naive-ui'
import {
@@ -200,9 +200,9 @@ const loadRule = async () => {
if (loadedRule) {
rule.value = loadedRule
}
} catch (error) {
} catch (error: any) {
// 忽略取消错误
if (error.name !== 'AbortError' && !error.message?.includes('Cancel')) {
if (error?.name !== 'AbortError' && !error?.message?.includes('Cancel')) {
console.error('加载规则失败:', error)
}
} finally {
@@ -69,14 +69,14 @@ const tabConfig = [
]
// 根据当前路由设置激活的Tab
const activeTab = ref(route.name || 'monitor')
const activeTab = ref(String(route.name) || 'monitor')
// 监听路由变化,同步Tab状态
watch(
() => route.name,
(newRouteName) => {
if (newRouteName) {
activeTab.value = newRouteName
activeTab.value = String(newRouteName)
}
},
)
@@ -1,8 +1,8 @@
import { MessagePayload } from '@/correspond/IBridge'
import CSharpBridge from '@/correspond/CSharpBridge'
import TauriBridge from '@/correspond/TauriBridge'
import type { MessagePayload } from '@/correspond/IBridge'
import { CSharpBridge } from '@/correspond/CSharpBridge'
import { TauriBridge } from '@/correspond/TauriBridge'
type MessagePayload<T> = {
interface BridgeMessagePayload<T = any> {
channel: string
payload: T
}
@@ -11,12 +11,13 @@ class CSharpBridgeV2 {
private static CSBridge: CSharpBridgeV2 | null = null
static getBridge(): CSharpBridgeV2 | null {
if (CSharpBridgeV2.CSBridge === null || CSharpBridgeV2.CSBridge.CSBridge === undefined) {
if (CSharpBridgeV2.CSBridge === null) {
if (window.chrome && window.chrome.webview) {
// window.chrome.webview.postMessage("hello");
CSharpBridgeV2.CSBridge = new CSharpBridgeV2()
window.externalFunctions.__BRIDGE_LISTEN__ = CSharpBridgeV2.CSBridge.bridgeInvoke
window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__ = new Map()
;(window as any).externalFunctions = (window as any).externalFunctions || {}
;(window as any).externalFunctions.__BRIDGE_LISTEN__ = CSharpBridgeV2.CSBridge.bridgeInvoke
;(window as any).externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__ = new Map()
} else {
console.error('Not running in WebView2 environment')
}
@@ -25,10 +26,10 @@ class CSharpBridgeV2 {
}
bridgeInvoke(channel: string, json: string) {
const bridgeListenFunctions = window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__
const bridgeListenFunctions = (window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__
const listeners = bridgeListenFunctions.get(channel)
if (listeners) {
listeners.forEach((listener) => {
listeners.forEach((listener: any) => {
try {
listener.callback(json)
if (listener.once && CSharpBridgeV2.CSBridge) {
@@ -42,23 +43,25 @@ class CSharpBridgeV2 {
}
// 发送消息到后端
send<T, V>(channel: string, data?: T | null = null, callback: ((data: V) => void) | null = null) {
const obj: MessagePayload = {
send<T, V>(channel: string, data: T | null = null, callback: ((data: V) => void) | null = null) {
const obj: BridgeMessagePayload<T> = {
channel,
payload: data,
}
if (callback !== null && callback !== undefined) {
this.listen(channel, callback, true)
}
window.chrome.webview.postMessage(obj)
if (window.chrome?.webview) {
window.chrome.webview.postMessage(obj)
}
}
/**
* 监听后端消息
*/
listen<V>(channel: string, callback: (data: V) => void, once: boolean = false) {
const bridgeListenFunctions = window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__
if (!bridgeListenFunctions.has(channel)) {
const bridgeListenFunctions = (window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__
if (!bridgeListenFunctions?.has(channel)) {
bridgeListenFunctions.set(channel, new Set())
}
@@ -70,12 +73,12 @@ class CSharpBridgeV2 {
// 移除指定通道的所有监听器
off(channel: string) {
window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__.delete(channel)
;(window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__?.delete(channel)
}
// 移除特定监听器
removeListen(channel: string, listener: unknown) {
const bridgeListenFunctions = window.externalFunctions.__BRIDGE_LISTEN__FUNCTIONS__
const bridgeListenFunctions = (window as any).externalFunctions?.__BRIDGE_LISTEN__FUNCTIONS__
const channelListeners = bridgeListenFunctions.get(channel)
if (channelListeners) {
// 需要类型转换以匹配存储的监听器类型
@@ -89,3 +92,14 @@ class CSharpBridgeV2 {
}
export default CSharpBridgeV2
// 扩展 Window 接口
declare global {
interface Window {
chrome?: {
webview?: {
postMessage: (data: any) => void
}
}
}
}
+8 -15
View File
@@ -4,15 +4,8 @@ import {
type RouteComponent,
type RouteRecordRaw,
} from 'vue-router'
import HomeView from '../views/HomeView.vue'
import DevIndex from '@/views/dev/DevIndex.vue'
import StringUtils from '@/utils/stringUtils'
import PathUtils from '@/utils/pathUtils'
import NotFound from '@/views/NotFoundView.vue'
import AboutView from '@/views/AboutView.vue'
import FirewallView from '@/views/FirewallView.vue'
import AnalyseView from '@/views/AnalyseView/AnalyseView.vue'
import MonitorView from '@/views/MonitorView/index.vue'
// 导入所有 .vue 文件
const routes = import.meta.glob('@/views/dev/**/*.vue')
@@ -51,11 +44,11 @@ const router = createRouter({
{
path: '/home',
name: 'home',
component: HomeView,
component: () => import('../views/HomeView.vue'),
children: [
{
path: '/', // 捕获所有其他路径
component: NotFound, // 任何其他路径都跳转到默认页面
component: () => import('@/views/NotFoundView.vue'), // 任何其他路径都跳转到默认页面
},
],
},
@@ -63,39 +56,39 @@ const router = createRouter({
{
path: '/monitor',
name: 'monitor',
component: MonitorView,
component: () => import('@/views/MonitorView/index.vue'),
meta: { layout: 'main' },
},
// 防火墙
{
path: '/firewall',
name: 'firewall',
component: FirewallView,
component: () => import('@/views/FirewallView.vue'),
meta: { layout: 'main' },
},
// 网络分析
{
path: '/analyse',
name: 'analyse',
component: AnalyseView,
component: () => import('@/views/AnalyseView/AnalyseView.vue'),
meta: { layout: 'main' },
},
{
path: '/dev',
name: 'dev',
component: DevIndex,
component: () => import('@/views/dev/DevIndex.vue'),
children: [...devPageViews],
},
{
path: '/about',
name: 'about',
component: AboutView,
component: () => import('@/views/AboutView.vue'),
},
{
path: '/:pathMatch(.*)*', // 通配符路由
name: 'NotFound',
component: NotFound,
component: () => import('@/views/NotFoundView.vue'),
},
],
})
@@ -164,3 +164,18 @@ export interface FirewallStatistics {
topApplications: string[]
topPorts: string[]
}
// 显示用的规则类型(简化版本)
export interface DisplayRule {
id: string
name: string
description?: string
enabled: boolean
direction: RuleDirection
action: RuleAction
program: string
protocol: string
port: string
profiles: string[]
grouping?: string
}
@@ -20,6 +20,7 @@ export interface FirewallRuleShow {
protocol: string
port: string
profiles: string[]
grouping?: string
}
export interface FirewallRuleResponse {
+1
View File
@@ -3,6 +3,7 @@
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"paths": {
+4 -3
View File
@@ -29,9 +29,10 @@
// 加载 Node 和 Vite 类型声明
"types": [
"vite/client",
"node",
"element-plus/global"
]
"node"
],
"skipLibCheck": true,
"verbatimModuleSyntax": false
},
"include": [
"src/**/*.ts",
+2 -1
View File
@@ -9,7 +9,8 @@
"eslint.config.*"
],
"compilerOptions": {
"noEmit": true,
"composite": true,
"noEmit": false,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"module": "ESNext",
@@ -3,6 +3,7 @@
"include": ["src/**/__tests__/*", "env.d.ts"],
"exclude": [],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
"lib": [],
+75 -2
View File
@@ -26,10 +26,14 @@ export default defineConfig(({ mode }) => {
'useLoadingBar'
]
}
]
],
// 生成类型声明文件
dts: true
}),
Components({
resolvers: [NaiveUiResolver()]
resolvers: [NaiveUiResolver()],
// 生成类型声明文件
dts: true
})
],
// 防止 Vite 掩盖 Rust 错误
@@ -42,6 +46,75 @@ export default defineConfig(({ mode }) => {
},
},
build: {
// 打包优化配置
rollupOptions: {
output: {
// 手动分割 chunks
manualChunks: (id) => {
// node_modules 中的第三方库
if (id.includes('node_modules')) {
// Vue 生态
if (id.includes('vue') || id.includes('vue-router') || id.includes('pinia')) {
return 'vue-vendor'
}
// UI 库
if (id.includes('naive-ui')) {
return 'ui-vendor'
}
// 图表相关
if (id.includes('echarts') || id.includes('vue-echarts')) {
return 'charts-vendor'
}
// 图标库
if (id.includes('@vicons') || id.includes('vicons')) {
return 'icons-vendor'
}
// 其他第三方库
if (id.includes('axios') || id.includes('lodash') || id.includes('gsap') || id.includes('pako')) {
return 'utils-vendor'
}
// 其他 node_modules
return 'vendor'
}
// 业务代码分割
if (id.includes('src/views')) {
return 'views'
}
if (id.includes('src/components')) {
return 'components'
}
},
// 资产文件名称策略
assetFileNames: (assetInfo) => {
const info = assetInfo.name.split('.')
const ext = info[info.length - 1]
if (/\.(png|jpe?g|gif|svg|webp|ico)$/.test(assetInfo.name)) {
return 'assets/images/[name].[hash][extname]'
} else if (/\.(woff2?|eot|ttf|otf)$/.test(assetInfo.name)) {
return 'assets/fonts/[name].[hash][extname]'
}
return `assets/[ext]/[name].[hash][extname]`
},
// 入口文件名称
entryFileNames: 'assets/js/[name].[hash].js',
// chunk 文件名称
chunkFileNames: 'assets/js/[name].[hash].js'
}
},
// 压缩配置
minify: 'esbuild',
// 移除控制台输出
esbuild: {
drop: ['console', 'debugger']
},
// 警告阈值
chunkSizeWarningLimit: 1000,
// CSS 代码分割
cssCodeSplit: true,
// 生成 source map
sourcemap: false,
// 资产内联阈值
assetsInlineLimit: 4096
},
resolve: {
alias: {