带有 React 的 Chrome 扩展 v3 - 通过带有 React 组件的内容脚本将 html 添加到网站

问题描述 投票:0回答:1

我尝试使用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)})();
reactjs webpack google-chrome-extension
1个回答
0
投票

content.js 需要自己的 DOM,因为它有自己的 .html 文件,因此必须从 webpack 中排除该文件才能包含该文件。因此,在 webpack 配置部分“optimization”而不是 chunks:“all” 中,必须有一个排除内容块的条件 return chunk.name !== "content";.

© www.soinside.com 2019 - 2024. All rights reserved.