Chrome扩展MV3中scripting.executeScript无法执行React/TSX文件问题
问题根因
你遇到的问题核心是动态注入的React脚本没有把依赖打包到单文件,执行时缺少React、ReactDOM依赖直接静默失败,具体有以下几个常见原因:
- webpack配置仅排除了ExampleScript的splitChunks,但没有把React、ReactDOM、CSS样式等依赖全部内联到ExampleScript.js中,注入到页面后缺少依赖无法运行,因为页面环境没有这些依赖包
- publicPath配置为
/dist,style-loader注入样式时会用这个绝对路径请求资源,在第三方页面下路径错误触发静默失败 - 若使用React 18+,旧的
ReactDOM.renderAPI已被废弃,执行无效果 - 当前逻辑仅在Service Worker初始化时执行一次,扩展启动后新开的example.com标签不会触发注入
解决方案
1. 修正manifest配置
你当前manifest的matches字段缺少引号,会导致manifest加载失败:
// manifest.json 修正content_scripts部分 "content_scripts": [ { "matches": ["<all_urls>"], "js": ["contentScript.js"] } ]
2. 修改webpack配置
调整打包规则,让contentScript和ExampleScript这类需要注入到页面的脚本,把所有依赖打包到单文件,同时修正publicPath:
// webpack.common.config.js 修改以下部分,其余配置保持不变 module.exports = { // ...原有配置 output: { filename: '[name].js', publicPath: 'auto', // 替换原来的/dist,自动适配注入场景的路径 path: path.resolve('dist'), }, optimization: { splitChunks: { chunks(chunk) { // 注入类脚本不要抽离公共chunk,所有依赖内联到单文件 return !['contentScript', 'ExampleScript'].includes(chunk.name) }, }, } }
3. 修正React渲染API(适配React 18+)
如果你的项目使用React 18及以上版本,替换旧的render写法,同时给根元素加定位避免被页面原有元素遮挡:
// ExampleScript.tsx import React from 'react' import { createRoot } from 'react-dom/client' import './ExampleScript.css'; alert('EXAMPLE SCRIPT'); const ExampleScript = () => { console.log('Example Script working') return ( <div style={{ position: 'fixed', top: '10px', left: '10px', zIndex: 999999, background: '#fff', padding: '10px' }}> <h1>HELLO WORLD</h1> </div> ); } const rootContainer = document.createElement('div'); document.body.appendChild(rootContainer); const root = createRoot(rootContainer); root.render(<ExampleScript />);
4. 补全注入触发逻辑
新增标签更新监听,确保扩展启动后新开的example.com标签也能正常注入脚本:
// background.ts 新增监听逻辑,原有查询逻辑可保留 chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { if (changeInfo.status === 'complete' && tab.url?.includes('example')) { chrome.scripting.executeScript({ target: { tabId }, files: ['ExampleScript.js'] }) } })
5. 验证打包结果
打包完成后打开dist/ExampleScript.js,确认文件大小至少在100KB以上(包含React、ReactDOM依赖),你可以直接把该文件的全部代码复制到example.com的控制台执行,验证是否能正常弹出alert、插入DOM元素。
内容的提问来源于stack exchange,提问作者0pH
相关产品推荐
相关产品推荐

