feat: 重构录制逻辑,添加错误处理,更新消息常量,使用 terser 进行构建压缩
This commit is contained in:
@@ -19,11 +19,15 @@ export default defineBackground(() => {
|
||||
}
|
||||
|
||||
// 注入 content script
|
||||
const res = browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ['/content-scripts/content.js'],
|
||||
});
|
||||
console.log('Content script injected on installed/updated:', res);
|
||||
try {
|
||||
const res = await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ['/content-scripts/content.js'],
|
||||
});
|
||||
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 });
|
||||
})
|
||||
.catch(() => {
|
||||
console.error('Failed to check status in content script');
|
||||
sendResponse({ ok: false });
|
||||
});
|
||||
return true;
|
||||
@@ -49,6 +54,7 @@ export default defineBackground(() => {
|
||||
sendResponse({ ok: true });
|
||||
})
|
||||
.catch(() => {
|
||||
console.error('Failed to start recording in content script');
|
||||
sendResponse({ ok: false });
|
||||
});
|
||||
}
|
||||
@@ -68,6 +74,14 @@ export default defineBackground(() => {
|
||||
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: {
|
||||
type: string;
|
||||
data?: unknown;
|
||||
@@ -80,6 +94,11 @@ export default defineBackground(() => {
|
||||
});
|
||||
const activeTab = activeTabs[0];
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import '../.wxt/types/imports.d.ts';
|
||||
import { createRecorder } from '@/utils/useRecorder';
|
||||
|
||||
export default defineContentScript({
|
||||
// matches: ['*://*.google.com/*'],
|
||||
matches: ['<all_urls>'],
|
||||
runAt: 'document_start',
|
||||
main() {
|
||||
const recorder = createRecorder();
|
||||
|
||||
// 监听来自 background script 的消息
|
||||
chrome.runtime.onMessage.addListener((msg: { type: string }, _sender, sendResponse) => {
|
||||
if (msg.type === messages.content.checkStatus) {
|
||||
@@ -16,12 +19,14 @@ export default defineContentScript({
|
||||
if (msg.type === messages.content.to.startRecording) {
|
||||
// 开始录制的处理逻辑
|
||||
console.log('[content] startRecording received');
|
||||
recorder.startRecord(messages.content.from.saveTrackeEvents);
|
||||
sendResponse({ ok: true });
|
||||
}
|
||||
|
||||
|
||||
if (msg.type === messages.content.to.stopRecording) {
|
||||
// 停止录制的处理逻辑
|
||||
console.log('[content] stopRecording received');
|
||||
recorder.stopRecord();
|
||||
sendResponse({ ok: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
Generated
+38
@@ -44,6 +44,7 @@
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^16.2.7",
|
||||
"prettier": "^3.8.1",
|
||||
"terser": "^5.46.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.54.0",
|
||||
"wxt": "^0.20.6"
|
||||
@@ -1254,6 +1255,17 @@
|
||||
"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": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
@@ -9581,6 +9593,32 @@
|
||||
"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": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/thread-stream/-/thread-stream-3.1.0.tgz",
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^16.2.7",
|
||||
"prettier": "^3.8.1",
|
||||
"terser": "^5.46.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.54.0",
|
||||
"wxt": "^0.20.6"
|
||||
|
||||
+3
-1
@@ -12,7 +12,9 @@ export const messages = {
|
||||
ready: 'popup:ready',
|
||||
},
|
||||
content: {
|
||||
from: {},
|
||||
from: {
|
||||
saveTrackeEvents: 'content:save-tracke-events',
|
||||
},
|
||||
to: {
|
||||
startRecording: 'content:start-recording',
|
||||
stopRecording: 'content:stop-recording',
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
@@ -31,4 +31,18 @@ export default defineConfig({
|
||||
128: 'favicon.ico',
|
||||
},
|
||||
},
|
||||
vite: () => ({
|
||||
build: {
|
||||
// 1. 切换压缩器为 terser
|
||||
minify: 'terser',
|
||||
|
||||
// 2. 配置 terser 强制转义所有非 ASCII 字符
|
||||
terserOptions: {
|
||||
format: {
|
||||
ascii_only: true,
|
||||
comments: false, // 去掉注释,防止注释里有乱码
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user