Przeglądaj źródła

chore(build): 优化项目配置并统一代码格式

- 调整package.json,新增代码格式化相关脚本和依赖 oxfmt,优化lint-staged配置
- 精简.eslintrc.json配置格式,保持规则一致但更紧凑
- rollup.config.js中统一使用双引号,格式化代码,增加注释说明和插件配置细节
- 监控SDK源码main.js优化代码风格,使用一致的字符串样式和格式
- 增强监控SDK功能逻辑的可读性,调整空行和注释布局,保持代码整洁
- 测试相关文件(index.html,test-cjs.js,test-esm.html)规范HTML及JS代码格式,修正缩进与引号
- 更新pnpm-lock.yaml同步新依赖,支持oxfmt格式化工具的多平台版本
- 优化浏览器和Node.js环境下的监控SDK测试流程,完善事件绑定和日志输出描述
xbx 3 miesięcy temu
rodzic
commit
5c41720192
11 zmienionych plików z 485 dodań i 384 usunięć
  1. 5 17
      .eslintrc.json
  2. 9 0
      .oxfmtrc.json
  3. 44 37
      package.json
  4. 95 0
      pnpm-lock.yaml
  5. 23 23
      rollup.config.js
  6. 77 79
      src/main.js
  7. 2 2
      src/test.js
  8. 97 95
      test/index.html
  9. 58 60
      test/test-cjs.js
  10. 73 69
      test/test-esm.html
  11. 2 2
      tsconfig.json

+ 5 - 17
.eslintrc.json

@@ -10,23 +10,11 @@
     "sourceType": "module"
   },
   "rules": {
-    "indent": [
-      "error",
-      2
-    ],
-    "linebreak-style": [
-      "error",
-      "unix"
-    ],
-    "quotes": [
-      "error",
-      "single"
-    ],
-    "semi": [
-      "error",
-      "always"
-    ],
+    "indent": ["error", 2],
+    "linebreak-style": ["error", "unix"],
+    "quotes": ["error", "single"],
+    "semi": ["error", "always"],
     "no-console": "warn",
     "no-unused-vars": "warn"
   }
-}
+}

+ 9 - 0
.oxfmtrc.json

@@ -0,0 +1,9 @@
+{
+  "indentWidth": 2,
+  "useTabs": false,
+  "lineWidth": 100,
+  "semicolons": true,
+  "trailingComma": "es5",
+  "quoteStyle": "single",
+  "arrowParens": "always"
+}

+ 44 - 37
package.json

@@ -1,39 +1,46 @@
 {
-	"name": "internal-monitoring-platform",
-	"version": "1.0.0",
-	"description": "内部监控平台,收集并上报代码报错、性能数据、用户行为、加载资源、个性化指标等数据",
-	"main": "dist/bundle-iife.js",
-	"scripts": {
-		"build": "rollup -c",
-		"dev": "rollup -c -w",
-		"build:prod": "rollup -c --environment NODE_ENV:production",
-		"test": "echo \"Error: no test specified\" && exit 1",
-		"lint": "oxlint src/",
-		"lint:fix": "oxlint --fix src/",
-		"prebuild": "if exist dist (rmdir /s /q dist) || echo dist does not exist"
-	},
-	"devDependencies": {
-		"@rollup/plugin-commonjs": "^25.0.7",
-		"@rollup/plugin-node-resolve": "^15.2.3",
-		"@rollup/plugin-terser": "^0.4.4",
-		"lint-staged": "^16.2.7",
-		"oxlint": "^1.39.0",
-		"rollup": "^4.54.0",
-		"rollup-plugin-typescript2": "^0.36.0",
-		"ts-loader": "^9.5.4",
-		"typescript": "^5.9.3"
-	},
-	"keywords": [
-		"monitoring",
-		"error-tracking",
-		"performance",
-		"analytics",
-		"frontend",
-		"sdk"
-	],
-	"author": "Internal Team",
-	"license": "MIT",
-	"lint-staged": {
-		"*.{js,jsx,ts,tsx,mjs,cjs}": "pnpm run lint"
-	}
+  "name": "internal-monitoring-platform",
+  "version": "1.0.0",
+  "description": "内部监控平台,收集并上报代码报错、性能数据、用户行为、加载资源、个性化指标等数据",
+  "keywords": [
+    "analytics",
+    "error-tracking",
+    "frontend",
+    "monitoring",
+    "performance",
+    "sdk"
+  ],
+  "license": "MIT",
+  "author": "Internal Team",
+  "main": "dist/bundle-iife.js",
+  "scripts": {
+    "build": "rollup -c",
+    "dev": "rollup -c -w",
+    "build:prod": "rollup -c --environment NODE_ENV:production",
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "lint": "oxlint src/",
+    "lint:fix": "oxlint --fix src/",
+    "format": "oxfmt",
+    "format:check": "oxfmt --check",
+    "prebuild": "if exist dist (rmdir /s /q dist) || echo dist does not exist"
+  },
+  "devDependencies": {
+    "@rollup/plugin-commonjs": "^25.0.7",
+    "@rollup/plugin-node-resolve": "^15.2.3",
+    "@rollup/plugin-terser": "^0.4.4",
+    "lint-staged": "^16.2.7",
+    "oxfmt": "^0.24.0",
+    "oxlint": "^1.39.0",
+    "rollup": "^4.54.0",
+    "rollup-plugin-typescript2": "^0.36.0",
+    "ts-loader": "^9.5.4",
+    "typescript": "^5.9.3"
+  },
+  "lint-staged": {
+    "*.{js,jsx,ts,tsx,mjs,cjs}": [
+      "oxfmt",
+      "git add",
+      "oxlint"
+    ]
+  }
 }

+ 95 - 0
pnpm-lock.yaml

@@ -20,6 +20,9 @@ importers:
       lint-staged:
         specifier: ^16.2.7
         version: 16.2.7
+      oxfmt:
+        specifier: ^0.24.0
+        version: 0.24.0
       oxlint:
         specifier: ^1.39.0
         version: 1.39.0
@@ -54,6 +57,50 @@ packages:
   '@jridgewell/trace-mapping@0.3.31':
     resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
 
+  '@oxfmt/darwin-arm64@0.24.0':
+    resolution: {integrity: sha512-aYXuGf/yq8nsyEcHindGhiz9I+GEqLkVq8CfPbd+6VE259CpPEH+CaGHEO1j6vIOmNr8KHRq+IAjeRO2uJpb8A==}
+    cpu: [arm64]
+    os: [darwin]
+
+  '@oxfmt/darwin-x64@0.24.0':
+    resolution: {integrity: sha512-vs3b8Bs53hbiNvcNeBilzE/+IhDTWKjSBB3v/ztr664nZk65j0xr+5IHMBNz3CFppmX7o/aBta2PxY+t+4KoPg==}
+    cpu: [x64]
+    os: [darwin]
+
+  '@oxfmt/linux-arm64-gnu@0.24.0':
+    resolution: {integrity: sha512-ItPDOPoQ0wLj/s8osc5ch57uUcA1Wk8r0YdO8vLRpXA3UNg7KPOm1vdbkIZRRiSUphZcuX5ioOEetEK8H7RlTw==}
+    cpu: [arm64]
+    os: [linux]
+    libc: [glibc]
+
+  '@oxfmt/linux-arm64-musl@0.24.0':
+    resolution: {integrity: sha512-JkQO3WnQjQTJONx8nxdgVBfl6BBFfpp9bKhChYhWeakwJdr7QPOAWJ/v3FGZfr0TbqINwnNR74aVZayDDRyXEA==}
+    cpu: [arm64]
+    os: [linux]
+    libc: [musl]
+
+  '@oxfmt/linux-x64-gnu@0.24.0':
+    resolution: {integrity: sha512-N/SXlFO+2kak5gMt0oxApi0WXQDhwA0PShR0UbkY0PwtHjfSiDqJSOumyNqgQVoroKr1GNnoRmUqjZIz6DKIcw==}
+    cpu: [x64]
+    os: [linux]
+    libc: [glibc]
+
+  '@oxfmt/linux-x64-musl@0.24.0':
+    resolution: {integrity: sha512-WM0pek5YDCQf50XQ7GLCE9sMBCMPW/NPAEPH/Hx6Qyir37lEsP4rUmSECo/QFNTU6KBc9NnsviAyJruWPpCMXw==}
+    cpu: [x64]
+    os: [linux]
+    libc: [musl]
+
+  '@oxfmt/win32-arm64@0.24.0':
+    resolution: {integrity: sha512-vFCseli1KWtwdHrVlT/jWfZ8jP8oYpnPPEjI23mPLW8K/6GEJmmvy0PZP5NpWUFNTzX0lqie58XnrATJYAe9Xw==}
+    cpu: [arm64]
+    os: [win32]
+
+  '@oxfmt/win32-x64@0.24.0':
+    resolution: {integrity: sha512-0tmlNzcyewAnauNeBCq0xmAkmiKzl+H09p0IdHy+QKrTQdtixtf+AOjDAADbRfihkS+heF15Pjc4IyJMdAAJjw==}
+    cpu: [x64]
+    os: [win32]
+
   '@oxlint/darwin-arm64@1.39.0':
     resolution: {integrity: sha512-lT3hNhIa02xCujI6YGgjmYGg3Ht/X9ag5ipUVETaMpx5Rd4BbTNWUPif1WN1YZHxt3KLCIqaAe7zVhatv83HOQ==}
     cpu: [arm64]
@@ -645,6 +692,11 @@ packages:
     resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
     engines: {node: '>=18'}
 
+  oxfmt@0.24.0:
+    resolution: {integrity: sha512-UjeM3Peez8Tl7IJ9s5UwAoZSiDRMww7BEc21gDYxLq3S3/KqJnM3mjNxsoSHgmBvSeX6RBhoVc2MfC/+96RdSw==}
+    engines: {node: ^20.19.0 || >=22.12.0}
+    hasBin: true
+
   oxlint@1.39.0:
     resolution: {integrity: sha512-wSiLr0wjG+KTU6c1LpVoQk7JZ7l8HCKlAkVDVTJKWmCGazsNxexxnOXl7dsar92mQcRnzko5g077ggP3RINSjA==}
     engines: {node: ^20.19.0 || >=22.12.0}
@@ -818,6 +870,10 @@ packages:
     engines: {node: '>=10'}
     hasBin: true
 
+  tinypool@2.0.0:
+    resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==}
+    engines: {node: ^20.0.0 || >=22.0.0}
+
   to-regex-range@5.0.1:
     resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
     engines: {node: '>=8.0'}
@@ -901,6 +957,30 @@ snapshots:
       '@jridgewell/resolve-uri': 3.1.2
       '@jridgewell/sourcemap-codec': 1.5.5
 
+  '@oxfmt/darwin-arm64@0.24.0':
+    optional: true
+
+  '@oxfmt/darwin-x64@0.24.0':
+    optional: true
+
+  '@oxfmt/linux-arm64-gnu@0.24.0':
+    optional: true
+
+  '@oxfmt/linux-arm64-musl@0.24.0':
+    optional: true
+
+  '@oxfmt/linux-x64-gnu@0.24.0':
+    optional: true
+
+  '@oxfmt/linux-x64-musl@0.24.0':
+    optional: true
+
+  '@oxfmt/win32-arm64@0.24.0':
+    optional: true
+
+  '@oxfmt/win32-x64@0.24.0':
+    optional: true
+
   '@oxlint/darwin-arm64@1.39.0':
     optional: true
 
@@ -1422,6 +1502,19 @@ snapshots:
     dependencies:
       mimic-function: 5.0.1
 
+  oxfmt@0.24.0:
+    dependencies:
+      tinypool: 2.0.0
+    optionalDependencies:
+      '@oxfmt/darwin-arm64': 0.24.0
+      '@oxfmt/darwin-x64': 0.24.0
+      '@oxfmt/linux-arm64-gnu': 0.24.0
+      '@oxfmt/linux-arm64-musl': 0.24.0
+      '@oxfmt/linux-x64-gnu': 0.24.0
+      '@oxfmt/linux-x64-musl': 0.24.0
+      '@oxfmt/win32-arm64': 0.24.0
+      '@oxfmt/win32-x64': 0.24.0
+
   oxlint@1.39.0:
     optionalDependencies:
       '@oxlint/darwin-arm64': 1.39.0
@@ -1596,6 +1689,8 @@ snapshots:
       commander: 2.20.3
       source-map-support: 0.5.21
 
+  tinypool@2.0.0: {}
+
   to-regex-range@5.0.1:
     dependencies:
       is-number: 7.0.0

+ 23 - 23
rollup.config.js

@@ -1,47 +1,47 @@
-import { defineConfig } from 'rollup';
-import { nodeResolve } from '@rollup/plugin-node-resolve';
-import commonjs from '@rollup/plugin-commonjs';
-import terser from '@rollup/plugin-terser';
+import { defineConfig } from "rollup";
+import { nodeResolve } from "@rollup/plugin-node-resolve";
+import commonjs from "@rollup/plugin-commonjs";
+import terser from "@rollup/plugin-terser";
 
 export default defineConfig({
-  input: 'src/test.js',
+  input: "src/test.js",
   output: [
     {
-      file: 'dist/bundle-iife.js',
-      format: 'iife',
-      name: 'MonitorSDK',
+      file: "dist/bundle-iife.js",
+      format: "iife",
+      name: "MonitorSDK",
       globals: {
         // 定义全局变量映射
-      }
+      },
     },
     {
-      file: 'dist/bundle-esm.js',
-      format: 'esm'
+      file: "dist/bundle-esm.js",
+      format: "esm",
     },
     {
-      file: 'dist/bundle-cjs.js',
-      format: 'cjs'
+      file: "dist/bundle-cjs.js",
+      format: "cjs",
     },
     {
-      file: 'dist/bundle-umd.js',
-      format: 'umd',
-      name: 'MonitorSDK'
-    }
+      file: "dist/bundle-umd.js",
+      format: "umd",
+      name: "MonitorSDK",
+    },
   ],
   plugins: [
     nodeResolve({
-      browser: true
+      browser: true,
     }),
     commonjs(),
     terser({
       format: {
-        comments: false
+        comments: false,
       },
       compress: {
         drop_console: true, // 生产环境移除console
-        drop_debugger: true
-      }
-    })
+        drop_debugger: true,
+      },
+    }),
   ],
-  external: [] // 外部依赖
+  external: [], // 外部依赖
 });

+ 77 - 79
src/main.js

@@ -4,77 +4,77 @@ class MonitorSDK {
   constructor(options = {}) {
     this.config = {
       // 基础配置
-      appId: options.appId || '',
-      apiUrl: options.apiUrl || '',
+      appId: options.appId || "",
+      apiUrl: options.apiUrl || "",
       enableErrorTracking: options.enableErrorTracking !== false,
       enablePerformanceTracking: options.enablePerformanceTracking !== false,
       enableUserBehaviorTracking: options.enableUserBehaviorTracking !== false,
       enableResourceTracking: options.enableResourceTracking !== false,
       sampleRate: options.sampleRate || 1.0, // 采样率,默认100%
       reportInterval: options.reportInterval || 5000, // 上报间隔,默认5秒
-      ...options
+      ...options,
     };
-    
+
     this.init();
   }
-  
+
   init() {
-    console.log('MonitorSDK initialized');
-    
+    console.log("MonitorSDK initialized");
+
     // 初始化各种监控模块
     if (this.config.enableErrorTracking) {
       this.initErrorTracking();
     }
-    
+
     if (this.config.enablePerformanceTracking) {
       this.initPerformanceTracking();
     }
-    
+
     if (this.config.enableUserBehaviorTracking) {
       this.initUserBehaviorTracking();
     }
-    
+
     if (this.config.enableResourceTracking) {
       this.initResourceTracking();
     }
-    
+
     // 定期上报数据
     this.startReporting();
   }
-  
+
   // 错误监控
   initErrorTracking() {
     // 监控JavaScript错误
-    window.addEventListener('error', (event) => {
+    window.addEventListener("error", (event) => {
       this.reportError({
-        type: 'javascript_error',
+        type: "javascript_error",
         message: event.message,
         filename: event.filename,
         lineno: event.lineno,
         colno: event.colno,
         stack: event.error ? event.error.stack : null,
-        timestamp: Date.now()
+        timestamp: Date.now(),
       });
     });
-    
+
     // 监控未处理的Promise错误
-    window.addEventListener('unhandledrejection', (event) => {
+    window.addEventListener("unhandledrejection", (event) => {
       this.reportError({
-        type: 'promise_rejection',
+        type: "promise_rejection",
         message: event.reason && event.reason.message ? event.reason.message : String(event.reason),
         stack: event.reason && event.reason.stack ? event.reason.stack : null,
-        timestamp: Date.now()
+        timestamp: Date.now(),
       });
     });
   }
-  
+
   // 性能监控
   initPerformanceTracking() {
     // 页面加载性能
     if (performance && performance.timing) {
       setTimeout(() => {
         const perfData = {
-          type: 'performance',
+          type: "performance",
           navigationStart: performance.timing.navigationStart,
           // DNS查询耗时
           dnsTime: performance.timing.domainLookupEnd - performance.timing.domainLookupStart,
@@ -85,172 +85,170 @@ class MonitorSDK {
           // DOM解析耗时
           domParseTime: performance.timing.domComplete - performance.timing.domLoading,
           // DOM内容加载完成耗时
-          domContentLoadedTime: performance.timing.domContentLoadedEventEnd - performance.timing.navigationStart,
+          domContentLoadedTime:
+            performance.timing.domContentLoadedEventEnd - performance.timing.navigationStart,
           // 页面加载完成总耗时
           loadCompleteTime: performance.timing.loadEventEnd - performance.timing.navigationStart,
-          timestamp: Date.now()
+          timestamp: Date.now(),
         };
         this.reportData(perfData);
       }, 0);
     }
-    
+
     // 监控Web Vitals
     this.measureWebVitals();
   }
-  
+
   // 用户行为监控
   initUserBehaviorTracking() {
     // 监控页面点击事件
-    document.addEventListener('click', (event) => {
+    document.addEventListener("click", (event) => {
       const target = event.target;
       this.reportData({
-        type: 'user_behavior',
-        action: 'click',
+        type: "user_behavior",
+        action: "click",
         element: target.tagName,
         elementId: target.id,
         elementClass: target.className,
         pageUrl: window.location.href,
-        timestamp: Date.now()
+        timestamp: Date.now(),
       });
     });
-    
+
     // 监控页面停留时间
     let pageVisibleTime = Date.now();
-    document.addEventListener('visibilitychange', () => {
-      if (document.visibilityState === 'hidden') {
+    document.addEventListener("visibilitychange", () => {
+      if (document.visibilityState === "hidden") {
         this.reportData({
-          type: 'page_stay',
+          type: "page_stay",
           duration: Date.now() - pageVisibleTime,
           pageUrl: window.location.href,
-          timestamp: Date.now()
+          timestamp: Date.now(),
         });
       } else {
         pageVisibleTime = Date.now();
       }
     });
   }
-  
+
   // 资源加载监控
   initResourceTracking() {
     if (performance && performance.getEntriesByType) {
       // 监控资源加载
-      const resources = performance.getEntriesByType('resource');
-      resources.forEach(resource => {
+      const resources = performance.getEntriesByType("resource");
+      resources.forEach((resource) => {
         this.reportData({
-          type: 'resource_load',
+          type: "resource_load",
           name: resource.name,
           duration: resource.duration,
           entryType: resource.entryType,
-          timestamp: Date.now()
+          timestamp: Date.now(),
         });
       });
     }
   }
-  
+
   // 上报错误
   reportError(errorData) {
     // 检查采样率
     if (Math.random() > this.config.sampleRate) {
       return; // 根据采样率决定是否上报
     }
-    
+
     this.reportData({
-      type: 'error',
-      ...errorData
+      type: "error",
+      ...errorData,
     });
   }
-  
+
   // 上报数据
   reportData(data) {
     // 检查采样率
     if (Math.random() > this.config.sampleRate) {
       return; // 根据采样率决定是否上报
     }
-    
+
     // 添加通用信息
     data.sessionId = this.getSessionId();
     data.userAgent = navigator.userAgent;
     data.url = window.location.href;
     data.timestamp = Date.now();
-    
+
     // 发送到服务端
     if (this.config.apiUrl) {
       try {
         // 使用navigator.sendBeacon发送数据,即使页面关闭也能发送
         if (navigator.sendBeacon) {
-          navigator.sendBeacon(
-            this.config.apiUrl,
-            JSON.stringify(data)
-          );
+          navigator.sendBeacon(this.config.apiUrl, JSON.stringify(data));
         } else {
           // 备用方案:使用fetch
           fetch(this.config.apiUrl, {
-            method: 'POST',
+            method: "POST",
             body: JSON.stringify(data),
             headers: {
-              'Content-Type': 'application/json'
-            }
-          }).catch(err => {
-            console.error('MonitorSDK: Failed to send data:', err);
+              "Content-Type": "application/json",
+            },
+          }).catch((err) => {
+            console.error("MonitorSDK: Failed to send data:", err);
           });
         }
       } catch (error) {
-        console.error('MonitorSDK: Error sending data:', error);
+        console.error("MonitorSDK: Error sending data:", error);
       }
     } else {
       // 开发模式下打印到控制台
-      console.log('MonitorSDK: Data to send:', data);
+      console.log("MonitorSDK: Data to send:", data);
     }
   }
-  
+
   // 开始定期上报
   startReporting() {
     setInterval(() => {
       // 这里可以实现批量上报逻辑
     }, this.config.reportInterval);
   }
-  
+
   // 获取会话ID
   getSessionId() {
     if (!this.sessionId) {
-      this.sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
+      this.sessionId = "session_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
     }
     return this.sessionId;
   }
-  
+
   // 测量Web Vitals
   measureWebVitals() {
     // 这里可以集成web-vitals库来测量核心Web指标
     // 如CLS (Cumulative Layout Shift), FID (First Input Delay), LCP (Largest Contentful Paint)
-    if ('PerformanceObserver' in window) {
+    if ("PerformanceObserver" in window) {
       // LCP (Largest Contentful Paint)
       new PerformanceObserver((entryList) => {
         const entries = entryList.getEntries();
         const lastEntry = entries[entries.length - 1];
         if (lastEntry) {
           this.reportData({
-            type: 'web_vitals',
-            metric: 'LCP',
+            type: "web_vitals",
+            metric: "LCP",
             value: lastEntry.startTime,
-            timestamp: Date.now()
+            timestamp: Date.now(),
           });
         }
-      }).observe({ entryTypes: ['largest-contentful-paint'] });
-      
+      }).observe({ entryTypes: ["largest-contentful-paint"] });
+
       // FID (First Input Delay)
       new PerformanceObserver((entryList) => {
         const firstInput = entryList.getEntries()[0];
         if (firstInput) {
           const fid = firstInput.processingStart - firstInput.startTime;
           this.reportData({
-            type: 'web_vitals',
-            metric: 'FID',
+            type: "web_vitals",
+            metric: "FID",
             value: fid,
-            timestamp: Date.now()
+            timestamp: Date.now(),
           });
         }
-      }).observe({ entryTypes: ['first-input'] });
-      
+      }).observe({ entryTypes: ["first-input"] });
+
       // CLS (Cumulative Layout Shift)
       let clsValue = 0;
       new PerformanceObserver((entryList) => {
@@ -260,25 +258,25 @@ class MonitorSDK {
           }
         }
         this.reportData({
-          type: 'web_vitals',
-          metric: 'CLS',
+          type: "web_vitals",
+          metric: "CLS",
           value: clsValue,
-          timestamp: Date.now()
+          timestamp: Date.now(),
         });
-      }).observe({ entryTypes: ['layout-shift'] });
+      }).observe({ entryTypes: ["layout-shift"] });
     }
   }
 }
 
 // 初始化监控SDK
 const monitor = new MonitorSDK({
-  appId: 'monitor-app',
-  apiUrl: '/api/monitor', // 这里应该是实际的API地址
+  appId: "monitor-app",
+  apiUrl: "/api/monitor", // 这里应该是实际的API地址
   enableErrorTracking: true,
   enablePerformanceTracking: true,
   enableUserBehaviorTracking: true,
   enableResourceTracking: true,
-  sampleRate: 1.0
+  sampleRate: 1.0,
 });
 
 // 将monitor实例暴露到全局,方便调用

+ 2 - 2
src/test.js

@@ -10,13 +10,13 @@ function testExport(a) {
 }
 
 // 将函数暴露到全局对象,以便在浏览器中使用
-if (typeof window !== 'undefined') {
+if (typeof window !== "undefined") {
   window.test = test;
   window.testExport = testExport;
 }
 
 // 保持ES模块导出兼容性
-if (typeof exports !== 'undefined') {
+if (typeof exports !== "undefined") {
   module.exports = { test, testExport };
 } else {
   // 对于ES模块,可以这样导出

+ 97 - 95
test/index.html

@@ -1,111 +1,113 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="zh-CN">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Monitor SDK 测试页面</title>
-</head>
-<body>
+  </head>
+  <body>
     <h1>监控SDK测试页面</h1>
     <p>此页面用于测试打包后的监控SDK是否正常工作。</p>
-    
+
     <!-- 引入打包后的测试函数 -->
     <script src="../dist/bundle-iife.js"></script>
-    
+
     <div id="test-container">
-        <button id="trigger-error">触发JavaScript错误</button>
-        <button id="trigger-promise-error">触发Promise错误</button>
-        <button id="simulate-performance-event">模拟性能事件</button>
-        <button id="send-custom-data">发送自定义数据</button>
-        <button id="test-functions">测试函数(test)</button>
+      <button id="trigger-error">触发JavaScript错误</button>
+      <button id="trigger-promise-error">触发Promise错误</button>
+      <button id="simulate-performance-event">模拟性能事件</button>
+      <button id="send-custom-data">发送自定义数据</button>
+      <button id="test-functions">测试函数(test)</button>
     </div>
-    
+
     <div id="result">
-        <h3>控制台输出:</h3>
-        <p>请打开开发者工具查看监控SDK的输出信息</p>
+      <h3>控制台输出:</h3>
+      <p>请打开开发者工具查看监控SDK的输出信息</p>
     </div>
 
     <script>
-        // 页面加载完成后执行测试
-        document.addEventListener('DOMContentLoaded', function() {
-            console.log('页面已加载,监控SDK应该已经初始化');
-            
-            // 检查监控SDK是否已正确加载
-            if (window.MonitorSDK && window.monitorInstance) {
-                console.log('监控SDK已成功加载');
-                console.log('SDK实例:', window.monitorInstance);
-            } else {
-                console.error('监控SDK未正确加载');
-            }
-
-            // 测试全局函数是否存在
-            if (window.test && window.testExport) {
-                console.log('✅ 全局函数已成功加载');
-                
-                // 测试函数功能
-                console.log('test(5) =', window.test(5));
-                console.log('testExport(5) =', window.testExport(5));
-            } else {
-                console.error('❌ 全局函数未找到');
-            }
-            
-            // 绑定按钮事件
-            document.getElementById('test-functions').addEventListener('click', function() {
-                console.log('测试全局函数');
-                
-                if (window.test && window.testExport) {
-                    const result1 = window.test(10);
-                    const result2 = window.testExport(10);
-                    
-                    console.log('window.test(10) =', result1);
-                    console.log('window.testExport(10) =', result2);
-                    
-                    alert(`函数调用结果:\ntest(10) = ${result1}\ntestExport(10) = ${result2}`);
-                } else {
-                    console.error('函数未定义');
-                    alert('函数未定义');
-                }
-            });
-            
-            document.getElementById('trigger-error').addEventListener('click', function() {
-                console.log('触发JavaScript错误测试');
-                // 触发一个JavaScript错误
-                throw new Error('这是测试错误');
-            });
+      // 页面加载完成后执行测试
+      document.addEventListener("DOMContentLoaded", function () {
+        console.log("页面已加载,监控SDK应该已经初始化");
 
-            document.getElementById('trigger-promise-error').addEventListener('click', function() {
-                console.log('触发Promise错误测试');
-                // 触发一个Promise错误
-                Promise.reject(new Error('这是测试Promise错误'));
-            });
-            
-            document.getElementById('simulate-performance-event').addEventListener('click', function() {
-                console.log('模拟性能事件');
-                // 这会触发性能监控
-                const start = performance.now();
-                // 模拟一些计算
-                for(let i = 0; i < 1000000; i++) {}
-                const end = performance.now();
-                console.log(`模拟计算耗时: ${end - start} ms`);
-            });
-            
-            document.getElementById('send-custom-data').addEventListener('click', function() {
-                console.log('发送自定义数据');
-                // 使用监控实例发送自定义数据
-                if (window.monitorInstance) {
-                    window.monitorInstance.reportData({
-                        type: 'custom_event',
-                        message: '自定义事件测试',
-                        timestamp: Date.now()
-                    });
-                }
-            });
+        // 检查监控SDK是否已正确加载
+        if (window.MonitorSDK && window.monitorInstance) {
+          console.log("监控SDK已成功加载");
+          console.log("SDK实例:", window.monitorInstance);
+        } else {
+          console.error("监控SDK未正确加载");
+        }
+
+        // 测试全局函数是否存在
+        if (window.test && window.testExport) {
+          console.log("✅ 全局函数已成功加载");
+
+          // 测试函数功能
+          console.log("test(5) =", window.test(5));
+          console.log("testExport(5) =", window.testExport(5));
+        } else {
+          console.error("❌ 全局函数未找到");
+        }
+
+        // 绑定按钮事件
+        document.getElementById("test-functions").addEventListener("click", function () {
+          console.log("测试全局函数");
+
+          if (window.test && window.testExport) {
+            const result1 = window.test(10);
+            const result2 = window.testExport(10);
+
+            console.log("window.test(10) =", result1);
+            console.log("window.testExport(10) =", result2);
+
+            alert(`函数调用结果:\ntest(10) = ${result1}\ntestExport(10) = ${result2}`);
+          } else {
+            console.error("函数未定义");
+            alert("函数未定义");
+          }
         });
-        
-        // 页面可见性变化事件(用于测试页面停留时间监控)
-        document.addEventListener('visibilitychange', function() {
-            console.log('页面可见性变化:', document.visibilityState);
+
+        document.getElementById("trigger-error").addEventListener("click", function () {
+          console.log("触发JavaScript错误测试");
+          // 触发一个JavaScript错误
+          throw new Error("这是测试错误");
+        });
+
+        document.getElementById("trigger-promise-error").addEventListener("click", function () {
+          console.log("触发Promise错误测试");
+          // 触发一个Promise错误
+          Promise.reject(new Error("这是测试Promise错误"));
         });
+
+        document
+          .getElementById("simulate-performance-event")
+          .addEventListener("click", function () {
+            console.log("模拟性能事件");
+            // 这会触发性能监控
+            const start = performance.now();
+            // 模拟一些计算
+            for (let i = 0; i < 1000000; i++) {}
+            const end = performance.now();
+            console.log(`模拟计算耗时: ${end - start} ms`);
+          });
+
+        document.getElementById("send-custom-data").addEventListener("click", function () {
+          console.log("发送自定义数据");
+          // 使用监控实例发送自定义数据
+          if (window.monitorInstance) {
+            window.monitorInstance.reportData({
+              type: "custom_event",
+              message: "自定义事件测试",
+              timestamp: Date.now(),
+            });
+          }
+        });
+      });
+
+      // 页面可见性变化事件(用于测试页面停留时间监控)
+      document.addEventListener("visibilitychange", function () {
+        console.log("页面可见性变化:", document.visibilityState);
+      });
     </script>
-</body>
-</html>
+  </body>
+</html>

+ 58 - 60
test/test-cjs.js

@@ -3,41 +3,40 @@
  */
 
 // 在Node.js环境中测试CJS格式的bundle
-console.log('开始测试CommonJS格式的监控SDK');
+console.log("开始测试CommonJS格式的监控SDK");
 
 try {
   // 动态引入CJS格式的bundle
-  const MonitorSDK = require('../dist/bundle-cjs.js');
-  
-  console.log('CommonJS格式的监控SDK已加载');
-  console.log('MonitorSDK类型:', typeof MonitorSDK);
-  
+  const MonitorSDK = require("../dist/bundle-cjs.js");
+
+  console.log("CommonJS格式的监控SDK已加载");
+  console.log("MonitorSDK类型:", typeof MonitorSDK);
+
   // 注意:由于Node.js环境缺少浏览器API(如window、document、performance等)
   // 直接初始化可能会出错,所以我们只测试基本导入功能
-  
+
   // 检查MonitorSDK构造函数是否存在
-  if (typeof MonitorSDK === 'function') {
-    console.log('✅ MonitorSDK构造函数存在');
+  if (typeof MonitorSDK === "function") {
+    console.log("✅ MonitorSDK构造函数存在");
   } else {
-    console.log('❌ MonitorSDK不是函数');
+    console.log("❌ MonitorSDK不是函数");
   }
-  
-  console.log('\n注意:由于Node.js环境缺少浏览器API,完整的SDK功能无法在此环境中测试。');
-  console.log('完整的功能测试需要在浏览器环境中进行。');
-  
+
+  console.log("\n注意:由于Node.js环境缺少浏览器API,完整的SDK功能无法在此环境中测试。");
+  console.log("完整的功能测试需要在浏览器环境中进行。");
 } catch (error) {
-  console.error('❌ 加载CommonJS格式的bundle时出错:', error.message);
+  console.error("❌ 加载CommonJS格式的bundle时出错:", error.message);
 }
 
 // 模拟浏览器环境的部分功能以测试SDK
-console.log('\n--- 模拟浏览器环境测试 ---');
+console.log("\n--- 模拟浏览器环境测试 ---");
 
 // 为Node.js环境模拟必要的浏览器API
 global.window = global;
 global.document = {
-  addEventListener: function(event, handler) {
+  addEventListener: function (event, handler) {
     console.log(`模拟添加${event}事件监听器`);
-  }
+  },
 };
 global.performance = {
   timing: {
@@ -53,25 +52,25 @@ global.performance = {
     domContentLoadedEventStart: Date.now() + 6,
     domContentLoadedEventEnd: Date.now() + 7,
     loadEventStart: Date.now() + 8,
-    loadEventEnd: Date.now() + 9
+    loadEventEnd: Date.now() + 9,
   },
-  getEntriesByType: function(type) {
+  getEntriesByType: function (type) {
     console.log(`模拟获取${type}类型的性能条目`);
     return [];
-  }
+  },
 };
 global.navigator = {
-  userAgent: 'Test Node Environment',
-  sendBeacon: function(url, data) {
-    console.log('模拟sendBeacon调用:', url, data);
+  userAgent: "Test Node Environment",
+  sendBeacon: function (url, data) {
+    console.log("模拟sendBeacon调用:", url, data);
     return true;
-  }
+  },
 };
-global.fetch = function(url, options) {
-  console.log('模拟fetch调用:', url, options);
+global.fetch = function (url, options) {
+  console.log("模拟fetch调用:", url, options);
   return Promise.resolve({
     ok: true,
-    json: () => Promise.resolve({})
+    json: () => Promise.resolve({}),
   });
 };
 
@@ -79,54 +78,53 @@ global.fetch = function(url, options) {
 setTimeout(() => {
   try {
     // 重新require以确保使用新的全局变量
-    delete require.cache[require.resolve('../dist/bundle-cjs.js')];
-    const MonitorSDK = require('../dist/bundle-cjs.js');
-    
+    delete require.cache[require.resolve("../dist/bundle-cjs.js")];
+    const MonitorSDK = require("../dist/bundle-cjs.js");
+
     // 创建实例
     const monitor = new MonitorSDK({
-      appId: 'test-app',
-      apiUrl: 'http://localhost:3000/api/monitor',
+      appId: "test-app",
+      apiUrl: "http://localhost:3000/api/monitor",
       enableErrorTracking: true,
       enablePerformanceTracking: true,
       enableUserBehaviorTracking: false, // 避免在Node.js中使用document
       enableResourceTracking: true,
-      sampleRate: 1.0
+      sampleRate: 1.0,
     });
-    
-    console.log('✅ 成功创建MonitorSDK实例');
-    
+
+    console.log("✅ 成功创建MonitorSDK实例");
+
     // 测试错误上报功能
-    if (monitor && typeof monitor.reportError === 'function') {
-      console.log('✅ reportError方法存在');
-      
+    if (monitor && typeof monitor.reportError === "function") {
+      console.log("✅ reportError方法存在");
+
       monitor.reportError({
-        type: 'test_error',
-        message: '测试错误',
-        timestamp: Date.now()
+        type: "test_error",
+        message: "测试错误",
+        timestamp: Date.now(),
       });
-      
-      console.log('✅ 成功调用reportError方法');
+
+      console.log("✅ 成功调用reportError方法");
     } else {
-      console.log('❌ reportError方法不存在');
+      console.log("❌ reportError方法不存在");
     }
-    
+
     // 测试数据上报功能
-    if (monitor && typeof monitor.reportData === 'function') {
-      console.log('✅ reportData方法存在');
-      
+    if (monitor && typeof monitor.reportData === "function") {
+      console.log("✅ reportData方法存在");
+
       monitor.reportData({
-        type: 'test_data',
-        message: '测试数据',
-        timestamp: Date.now()
+        type: "test_data",
+        message: "测试数据",
+        timestamp: Date.now(),
       });
-      
-      console.log('✅ 成功调用reportData方法');
+
+      console.log("✅ 成功调用reportData方法");
     } else {
-      console.log('❌ reportData方法不存在');
+      console.log("❌ reportData方法不存在");
     }
-    
   } catch (error) {
-    console.error('❌ 在模拟环境中初始化SDK时出错:', error.message);
-    console.error('堆栈:', error.stack);
+    console.error("❌ 在模拟环境中初始化SDK时出错:", error.message);
+    console.error("堆栈:", error.stack);
   }
-}, 100);
+}, 100);

+ 73 - 69
test/test-esm.html

@@ -1,84 +1,88 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="zh-CN">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>ESM格式监控SDK测试</title>
-</head>
-<body>
+  </head>
+  <body>
     <h1>ESM格式监控SDK测试页面</h1>
     <p>此页面用于测试ES模块格式的监控SDK是否正常工作。</p>
-    
+
     <div id="test-container">
-        <button id="test-esm-sdk">测试ESM格式SDK</button>
-        <button id="test-esm-functionality">测试ESM功能</button>
+      <button id="test-esm-sdk">测试ESM格式SDK</button>
+      <button id="test-esm-functionality">测试ESM功能</button>
     </div>
-    
+
     <div id="result">
-        <h3>控制台输出:</h3>
-        <p>请打开开发者工具查看监控SDK的输出信息</p>
+      <h3>控制台输出:</h3>
+      <p>请打开开发者工具查看监控SDK的输出信息</p>
     </div>
 
     <!-- 使用ES模块语法导入SDK -->
     <script type="module">
-        // 从ESM格式的bundle中导入
-        // 注意:由于我们的bundle没有导出默认对象,我们需要使用动态导入
-        console.log('开始测试ESM格式的监控SDK');
-        
-        // 动态导入ESM格式的bundle
-        import('../dist/bundle-esm.js').then(module => {
-            console.log('ESM格式的监控SDK已加载');
-            console.log('模块内容:', module);
-            
-            // 检查全局对象是否可用(我们的代码会在全局作用域创建实例)
-            if (window.MonitorSDK && window.monitorInstance) {
-                console.log('✅ ESM格式SDK成功初始化全局对象');
-                
-                // 绑定按钮事件
-                document.getElementById('test-esm-sdk').addEventListener('click', function() {
-                    console.log('测试ESM格式SDK功能');
-                    
-                    // 测试SDK实例
-                    if (window.monitorInstance) {
-                        console.log('SDK实例存在,版本信息:', window.monitorInstance.config);
-                        
-                        // 测试数据上报
-                        window.monitorInstance.reportData({
-                            type: 'esm_test_event',
-                            message: 'ESM格式SDK测试事件',
-                            timestamp: Date.now()
-                        });
-                    }
+      // 从ESM格式的bundle中导入
+      // 注意:由于我们的bundle没有导出默认对象,我们需要使用动态导入
+      console.log("开始测试ESM格式的监控SDK");
+
+      // 动态导入ESM格式的bundle
+      import("../dist/bundle-esm.js")
+        .then((module) => {
+          console.log("ESM格式的监控SDK已加载");
+          console.log("模块内容:", module);
+
+          // 检查全局对象是否可用(我们的代码会在全局作用域创建实例)
+          if (window.MonitorSDK && window.monitorInstance) {
+            console.log("✅ ESM格式SDK成功初始化全局对象");
+
+            // 绑定按钮事件
+            document.getElementById("test-esm-sdk").addEventListener("click", function () {
+              console.log("测试ESM格式SDK功能");
+
+              // 测试SDK实例
+              if (window.monitorInstance) {
+                console.log("SDK实例存在,版本信息:", window.monitorInstance.config);
+
+                // 测试数据上报
+                window.monitorInstance.reportData({
+                  type: "esm_test_event",
+                  message: "ESM格式SDK测试事件",
+                  timestamp: Date.now(),
                 });
-                
-                document.getElementById('test-esm-functionality').addEventListener('click', function() {
-                    console.log('测试ESM格式SDK各项功能');
-                    
-                    // 测试错误上报
-                    try {
-                        throw new Error('ESM格式SDK测试错误');
-                    } catch(e) {
-                        window.monitorInstance.reportError({
-                            type: 'esm_test_error',
-                            message: e.message,
-                            stack: e.stack,
-                            timestamp: Date.now()
-                        });
-                    }
-                    
-                    // 测试性能数据
-                    window.monitorInstance.reportData({
-                        type: 'esm_performance_test',
-                        loadTime: 100,
-                        timestamp: Date.now()
-                    });
+              }
+            });
+
+            document
+              .getElementById("test-esm-functionality")
+              .addEventListener("click", function () {
+                console.log("测试ESM格式SDK各项功能");
+
+                // 测试错误上报
+                try {
+                  throw new Error("ESM格式SDK测试错误");
+                } catch (e) {
+                  window.monitorInstance.reportError({
+                    type: "esm_test_error",
+                    message: e.message,
+                    stack: e.stack,
+                    timestamp: Date.now(),
+                  });
+                }
+
+                // 测试性能数据
+                window.monitorInstance.reportData({
+                  type: "esm_performance_test",
+                  loadTime: 100,
+                  timestamp: Date.now(),
                 });
-            } else {
-                console.error('❌ ESM格式SDK未正确初始化全局对象');
-            }
-        }).catch(error => {
-            console.error('❌ 加载ESM格式的bundle时出错:', error);
+              });
+          } else {
+            console.error("❌ ESM格式SDK未正确初始化全局对象");
+          }
+        })
+        .catch((error) => {
+          console.error("❌ 加载ESM格式的bundle时出错:", error);
         });
     </script>
-</body>
-</html>
+  </body>
+</html>

+ 2 - 2
tsconfig.json

@@ -24,11 +24,11 @@
     "baseUrl": "./",
     "paths": {
       "*": ["src/*", "node_modules/*"],
-      "@websee/*":["packages/*/src"]
+      "@websee/*": ["packages/*/src"]
     },
     "jsx": "react-jsx",
     "esModuleInterop": true,
     "skipLibCheck": true,
     "forceConsistentCasingInFileNames": true
   }
-}
+}