我尝试使用react和webpack实现chrome扩展(manifest v3)。 我想简单地向网站添加一个“Hello World”进行测试,但内容脚本不运行。连console.log都没有显示出来。
当我从 content.js 中删除完整代码并仅添加 console.log 时,会显示此日志。所以清单应该是正确的。
测试.jsx
import React from "react";
function Test() {
return <div>Hello World</div>;
}
export default Test;
index.jsx
import React from "react";
import { createRoot } from "react-dom/client";
import Test from "./test";
function init() {
console.log("I am from react test content script.");
const appContainer = document.createElement("div");
appContainer.id = "react-root";
document.body.insertBefore(appContainer, document.body.firstChild);
if (!appContainer) {
throw new Error("Cannot find appContainer");
}
const root = createRoot(appContainer);
console.log(appContainer);
root.render(<Test />);
}
init();
manifest.json
"content_scripts": [
{
"matches": ["https://www.google.com/"],
"js": ["content.js"],
"run_at": "document_end"
}
],
编辑:文件index.jsx和test.jsx位于文件夹“content”中。 webpack 配置:
module.exports = {
entry: {
popup: path.resolve("./src/popup/index.jsx"),
content: path.resolve("./src/content/index.jsx"),
options: path.resolve("./src/options/index.jsx"),
background: path.resolve("./src/background/background.jsx"),
},
resolve: {
extensions: ["", ".js", ".jsx", ".tsx"],
},
output: {
path: path.resolve(__dirname, "dist"),
publicPath: "",
filename: "[name].js",
clean: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: { presets: ["@babel/preset-env", "@babel/preset-react"] },
},
},
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
ident: "postcss",
plugins: [tailwindcss, autoprefixer],
},
},
},
],
},
],
},
optimization: {
splitChunks: {
chunks(chunk) {
// exclude `chunk`
return chunk.name !== "content";
},
},
},
内容.js
(()=>{"use strict";var e,r={892:(e,r,t)=>{var o=t(294),n=t(745);const a=function(){return o.createElement("div",null,"Hello World")};!function(){console.log("I am from react test content script.");var e=document.createElement("div");if(e.id="react-root",document.body.insertBefore(e,document.body.firstChild),!e)throw new Error("Cannot find appContainer");var r=(0,n.s)(e);console.log(e),r.render(o.createElement(a,null))}()}},t={};function o(e){var n=t[e];if(void 0!==n)return n.exports;var a=t[e]={exports:{}};return r[e](a,a.exports,o),a.exports}o.m=r,e=[],o.O=(r,t,n,a)=>{if(!t){var l=1/0;for(f=0;f<e.length;f++){for(var[t,n,a]=e[f],i=!0,c=0;c<t.length;c++)(!1&a||l>=a)&&Object.keys(o.O).every((e=>o.O[e](t[c])))?t.splice(c--,1):(i=!1,a<l&&(l=a));if(i){e.splice(f--,1);var s=n();void 0!==s&&(r=s)}}return r}a=a||0;for(var f=e.length;f>0&&e[f-1][2]>a;f--)e[f]=e[f-1];e[f]=[t,n,a]},o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e={904:0};o.O.j=r=>0===e[r];var r=(r,t)=>{var n,a,[l,i,c]=t,s=0;if(l.some((r=>0!==e[r]))){for(n in i)o.o(i,n)&&(o.m[n]=i[n]);if(c)var f=c(o)}for(r&&r(t);s<l.length;s++)a=l[s],o.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return o.O(f)},t=self.webpackChunkreact_test=self.webpackChunkreact_test||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var n=o.O(void 0,[745],(()=>o(892)));n=o.O(n)})();
content.js 需要自己的 DOM,因为它有自己的 .html 文件,因此必须从 webpack 中排除该文件才能包含该文件。因此,在 webpack 配置部分“optimization”而不是 chunks:“all” 中,必须有一个排除内容块的条件 return chunk.name !== "content";.