feat: 重构录制逻辑,添加错误处理,更新消息常量,使用 terser 进行构建压缩

This commit is contained in:
雨霖铃
2026-02-03 23:42:28 +08:00
parent 37f8ef9c2b
commit e6f41032c8
8 changed files with 123 additions and 49 deletions
+25 -6
View File
@@ -19,11 +19,15 @@ export default defineBackground(() => {
} }
// 注入 content script // 注入 content script
const res = browser.scripting.executeScript({ try {
target: { tabId: tab.id }, const res = await browser.scripting.executeScript({
files: ['/content-scripts/content.js'], target: { tabId: tab.id },
}); files: ['/content-scripts/content.js'],
console.log('Content script injected on installed/updated:', res); });
console.log('Content script injected on installed/updated:', res);
} catch (error) {
console.error('Failed to inject content script:', error);
}
} }
}); });
@@ -36,6 +40,7 @@ export default defineBackground(() => {
sendResponse({ ok: true }); sendResponse({ ok: true });
}) })
.catch(() => { .catch(() => {
console.error('Failed to check status in content script');
sendResponse({ ok: false }); sendResponse({ ok: false });
}); });
return true; return true;
@@ -49,6 +54,7 @@ export default defineBackground(() => {
sendResponse({ ok: true }); sendResponse({ ok: true });
}) })
.catch(() => { .catch(() => {
console.error('Failed to start recording in content script');
sendResponse({ ok: false }); sendResponse({ ok: false });
}); });
} }
@@ -68,6 +74,14 @@ export default defineBackground(() => {
return true; return true;
}); });
// 监听来自 content script 的消息
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
if (msg.type === messages.content.from.saveTrackeEvents) {
console.log('[bg] saveTrackeEvents received:', msg.payload);
sendResponse({ ok: true });
}
});
async function sendToActiveTab(message: { async function sendToActiveTab(message: {
type: string; type: string;
data?: unknown; data?: unknown;
@@ -80,6 +94,11 @@ export default defineBackground(() => {
}); });
const activeTab = activeTabs[0]; const activeTab = activeTabs[0];
const sendTo = message.activeTabId || activeTab.id; const sendTo = message.activeTabId || activeTab.id;
await chrome.tabs.sendMessage(sendTo!, message); try {
await chrome.tabs.sendMessage(sendTo!, message);
} catch (error) {
console.error('Error sending message to active tab:', error);
throw error;
}
} }
}); });
+6 -1
View File
@@ -1,10 +1,13 @@
import '../.wxt/types/imports.d.ts'; import '../.wxt/types/imports.d.ts';
import { createRecorder } from '@/utils/useRecorder';
export default defineContentScript({ export default defineContentScript({
// matches: ['*://*.google.com/*'], // matches: ['*://*.google.com/*'],
matches: ['<all_urls>'], matches: ['<all_urls>'],
runAt: 'document_start', runAt: 'document_start',
main() { main() {
const recorder = createRecorder();
// 监听来自 background script 的消息 // 监听来自 background script 的消息
chrome.runtime.onMessage.addListener((msg: { type: string }, _sender, sendResponse) => { chrome.runtime.onMessage.addListener((msg: { type: string }, _sender, sendResponse) => {
if (msg.type === messages.content.checkStatus) { if (msg.type === messages.content.checkStatus) {
@@ -16,12 +19,14 @@ export default defineContentScript({
if (msg.type === messages.content.to.startRecording) { if (msg.type === messages.content.to.startRecording) {
// 开始录制的处理逻辑 // 开始录制的处理逻辑
console.log('[content] startRecording received'); console.log('[content] startRecording received');
recorder.startRecord(messages.content.from.saveTrackeEvents);
sendResponse({ ok: true }); sendResponse({ ok: true });
} }
if (msg.type === messages.content.to.stopRecording) { if (msg.type === messages.content.to.stopRecording) {
// 停止录制的处理逻辑 // 停止录制的处理逻辑
console.log('[content] stopRecording received'); console.log('[content] stopRecording received');
recorder.stopRecord();
sendResponse({ ok: true }); sendResponse({ ok: true });
} }
-41
View File
@@ -1,41 +0,0 @@
import { useRef, useState, useCallback } from 'react';
export const useRecorder = () => {
// 存储停止录制函数
const stopFnRef = useRef<(() => void) | null>(null);
const [isRecording, setIsRecording] = useState(false);
const startRecord = useCallback(async () => {
if (isRecording) return;
try {
// await chrome.runtime.sendMessage({ type: 'CREATE_OFFSCREEN' });
setIsRecording(true);
console.log('[content] rrweb started');
} catch (error) {
console.error('Failed to start recording:', error);
setIsRecording(false);
}
}, [isRecording]);
const stopRecord = () => {
if (!isRecording) return;
setIsRecording(false);
// 停止录制
if (stopFnRef.current) {
chrome.runtime.sendMessage({ type: 'SAVE_EVENTS' });
stopFnRef.current?.();
console.log('[content] rrweb stopped');
}
};
return {
startRecord,
stopRecord,
isRecording,
};
};
+38
View File
@@ -44,6 +44,7 @@
"husky": "^9.1.7", "husky": "^9.1.7",
"lint-staged": "^16.2.7", "lint-staged": "^16.2.7",
"prettier": "^3.8.1", "prettier": "^3.8.1",
"terser": "^5.46.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.54.0", "typescript-eslint": "^8.54.0",
"wxt": "^0.20.6" "wxt": "^0.20.6"
@@ -1254,6 +1255,17 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@jridgewell/source-map": {
"version": "0.3.11",
"resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz",
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": { "node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5", "version": "1.5.5",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
@@ -9581,6 +9593,32 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/terser": {
"version": "5.46.0",
"resolved": "https://registry.npmmirror.com/terser/-/terser-5.46.0.tgz",
"integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT"
},
"node_modules/thread-stream": { "node_modules/thread-stream": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmmirror.com/thread-stream/-/thread-stream-3.1.0.tgz", "resolved": "https://registry.npmmirror.com/thread-stream/-/thread-stream-3.1.0.tgz",
+1
View File
@@ -52,6 +52,7 @@
"husky": "^9.1.7", "husky": "^9.1.7",
"lint-staged": "^16.2.7", "lint-staged": "^16.2.7",
"prettier": "^3.8.1", "prettier": "^3.8.1",
"terser": "^5.46.0",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.54.0", "typescript-eslint": "^8.54.0",
"wxt": "^0.20.6" "wxt": "^0.20.6"
+3 -1
View File
@@ -12,7 +12,9 @@ export const messages = {
ready: 'popup:ready', ready: 'popup:ready',
}, },
content: { content: {
from: {}, from: {
saveTrackeEvents: 'content:save-tracke-events',
},
to: { to: {
startRecording: 'content:start-recording', startRecording: 'content:start-recording',
stopRecording: 'content:stop-recording', stopRecording: 'content:stop-recording',
+36
View File
@@ -0,0 +1,36 @@
import * as rrweb from 'rrweb';
import { listenerHandler } from '@rrweb/types';
export const createRecorder = () => {
let stopFn: listenerHandler | null = null;
const startRecord = async (msg: string) => {
try {
// const handler = null;
const handler = rrweb.record({
emit(event) {
chrome.runtime.sendMessage({
type: msg,
payload: event,
});
},
});
stopFn = handler || null;
console.log('[content] rrweb started');
} catch (error) {
console.error('Failed to start recording:', error);
}
};
const stopRecord = () => {
if (stopFn) {
stopFn();
stopFn = null;
console.log('[content] rrweb stopped');
}
};
return { startRecord, stopRecord };
};
+14
View File
@@ -31,4 +31,18 @@ export default defineConfig({
128: 'favicon.ico', 128: 'favicon.ico',
}, },
}, },
vite: () => ({
build: {
// 1. 切换压缩器为 terser
minify: 'terser',
// 2. 配置 terser 强制转义所有非 ASCII 字符
terserOptions: {
format: {
ascii_only: true,
comments: false, // 去掉注释,防止注释里有乱码
},
},
},
}),
}); });