javascript - React、Webpack 和 Tampermonkey : `cannot set property event of#<Object> which only has a getter`

标签 javascript reactjs webpack tampermonkey

编写一个 Tampermonkey 脚本,将表单内联注入(inject)到无法直接编辑的网页中。这些表单与单独的后端通信。

使用 jQuery 构建原型(prototype),但我希望使用 React 来支持更好的用户体验。为了使其与其他工作保持一致,我还想使用 webpack 和 jsx。

一次只做一件事,脚本很简单:

import React from 'react';
import ReactDOM from 'react-dom';

GM_addStyle(require(__dirname + '/styles/app.css'));

console.log("webpacked script is working!");

const Hello = () => <div>hello</div>

const graph = document.querySelector('a[href*="url_here"]');

console.log(graph);

ReactDOM.render(<Hello />, graph)

我尝试过 querySelectorAll、byTagName,以防万一它们有所不同。

但是,在多次调用后,生成的脚本会失败并显示“最大更新深度成功”:

console output

“webpacked 脚本正在运行!”打印到控制台,目标元素从 dom 中删除,但 <Hello /> div 未在其位置呈现。

该违规行已进行网络打包/转译,但未缩小,并以 fakeNode 开头,在这里:

     if ("undefined" != typeof window && "function" == typeof window.dispatchEvent && "undefined" != typeof document && "function" == typeof document.createEvent) {
        var fakeNode = document.createElement("react");
        invokeGuardedCallbackImpl = function(name, func, context, a, b, c, d, e, f) {
            "undefined" == typeof document && invariant(!1, "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.");
            var evt = document.createEvent("Event"), didError = !0, windowEvent = window.event, windowEventDescriptor = Object.getOwnPropertyDescriptor(window, "event"), funcArgs = Array.prototype.slice.call(arguments, 3);
            var error = void 0, didSetError = !1, isCrossOriginError = !1;
            function handleWindowError(event) {
                if (error = event.error, didSetError = !0, null === error && 0 === event.colno && 0 === event.lineno && (isCrossOriginError = !0), 
                event.defaultPrevented && null != error && "object" == typeof error) try {
                    error._suppressLogging = !0;
                } catch (inner) {}
            }
            var evtType = "react-" + (name || "invokeguardedcallback");
            window.addEventListener("error", handleWindowError), fakeNode.addEventListener(evtType, function callCallback() {
                fakeNode.removeEventListener(evtType, callCallback, !1), void 0 !== window.event && window.hasOwnProperty("event") && (window.event = windowEvent), 
                func.apply(context, funcArgs), didError = !1;
            }, !1), evt.initEvent(evtType, !1, !1), fakeNode.dispatchEvent(evt), windowEventDescriptor && Object.defineProperty(window, "event", windowEventDescriptor), 
            didError && (didSetError ? isCrossOriginError && (error = new Error("A cross-origin error was thrown. React doesn't have access to the actual error object in development. See ... for more information.")) : error = new Error("An error was thrown inside one of your components, but React doesn't know what it was. This is likely due to browser flakiness. React does its best to preserve the \"Pause on exceptions\" behavior of the DevTools, which requires some DEV-mode only tricks. It's possible that these don't work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue."), 
            this.onError(error)), window.removeEventListener("error", handleWindowError);
        };
    }

在我看来,ReactDOM 无法访问它期望的窗口对象,可能是由 Tampermonkey 代理的某处。

是这样吗,还是这是一个不同的问题?

有没有办法让 ReactDOM 在这个 Tampermonkey 脚本中正确渲染?

最佳答案

快速修复:tampermonkey 脚本顶部的 window = unsafeWindow,可以使用 webpack 的 BannerPlugin 轻松添加。

对于其他选项/背景:Why is window (and unsafeWindow) not the same from a userscript as from a <script> tag?

关于javascript - React、Webpack 和 Tampermonkey : `cannot set property event of#<Object> which only has a getter` ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54081088/

相关文章:

javascript - 缩放后 highchart/highstock 工具提示不调整

javascript - 如何在 react 中将日期/时间转换为人类可读的形式?

javascript - React 应用程序中 init 时触发按钮 onClick

webpack - 替代 Webpack@5 中的 `MainTemplate.hooks.beforeStartup`

javascript - React-Router@4 : Routes not switching normally with React-Hot-Loader@3. beta.6

javascript - JSX for...in 循环

javascript - 如何找到另一个数组中的数组长度

javascript - 属性(property)值(value)已改变但不受影响

javascript - 使用外部 react 组件缺少 react

javascript - 为什么 webpack 尝试解析我的依赖项路径中的每个文件?