plasmo icon indicating copy to clipboard operation
plasmo copied to clipboard

[BUG] Uncaught TypeError: $RefreshSig$ is not a function

Open DanielRuf opened this issue 1 year ago • 6 comments

What happened?

Getting an error when yarn dev is used and we have a HOC function component with hooks

...
        "@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js": "d37mJ"
    }],
    "jU5yN": [function(require, module, exports) {
        var $parcel$ReactRefreshHelpers$efaa = require("@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js");
        var prevRefreshReg = window.$RefreshReg$;
        var prevRefreshSig = window.$RefreshSig$;
        $parcel$ReactRefreshHelpers$efaa.prelude(module);

        try {
            var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
            parcelHelpers.defineInteropFlag(exports);
            parcelHelpers.export(exports, "ComponentNew", ()=>ComponentNew);
            var _react = require("react");
            var _reactDefault = parcelHelpers.interopDefault(_react);
            var _hook = require("@plasmohq/storage/hook");
            ...
            var _logger = require("~loggers/Logger");
            var _helpers = require("~util/helpers");
            var _s = $RefreshSig$();
            const ComponentNew = (props)=>{
                _s();
                var _s1 = $RefreshSig$() <=== here it throws
                  , _s2 = $RefreshSig$()
                  , _s3 = $RefreshSig$();

In the browser console:

content.ffb82774.js:54859 Uncaught TypeError: $RefreshSig$ is not a function
    at ComponentNew (content.ffb82774.js:54859:15)
    at renderWithHooks (content.ffb82774.js:15519:24)
    at mountIndeterminateComponent (content.ffb82774.js:18381:17)
    at beginWork (content.ffb82774.js:19411:24)

Version

Latest

What OS are you seeing the problem on?

Linux

What browsers are you seeing the problem on?

Chrome

Relevant log output

No response

(OPTIONAL) Contribution

  • [ ] I would like to fix this BUG via a PR

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct
  • [X] I checked the current issues for duplicate problems.

DanielRuf avatar Jul 31 '23 23:07 DanielRuf

The component is created like this:

grafik

DanielRuf avatar Aug 01 '23 07:08 DanielRuf

I have the same problem.

Chester-Chen avatar Aug 08 '23 07:08 Chester-Chen

This is a tricky case, might be related: https://github.com/FredKSchott/snowpack/discussions/1458

Based on the compiled code you attached and the fact that $RefreshSig$ is undefined, I think the core issue is that the context of that code being executed is somehow not the original Windows context (or not the correct global context where we'd inject the react refresh runtime).

Another is the use of React.* - try import just cloneElement from react instead, and see if that help. That's something I'd try, long story short it might be related to the resolver that messed with the react runtime :d...

What's interesting is that:

            var _s = $RefreshSig$();
            const ComponentNew = (props)=>{
                _s();
                var _s1 = $RefreshSig$() <=== here it throws
                  , _s2 = $RefreshSig$()
                  , _s3 = $RefreshSig$();

_s is RefreshSig as well, why didn't THAT throw, but throw below? That function context is likely lost somehow (?)... And where does this ComponentNew comes from? The Parcel js runtime?

louisgv avatar Aug 11 '23 05:08 louisgv

_s is RefreshSig as well, why didn't THAT throw, but throw below? That function context is likely lost somehow (?)... And where does this ComponentNew comes from? The Parcel js runtime?

ComponentNew is the name of the rendered component in our case. Tried the recommended solution with the import of cloneElement. Unfortunately it does not resolve the problem. The component itself is rendered normally, just the children are rendered via cloneElement.

The ComponentNew component heavily relies on hooks (lifecycle mount / unmount, ...).

DanielRuf avatar Aug 11 '23 07:08 DanielRuf

Some webpack plugins have documented some workarounds and solutions: https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#usage-with-indirection-like-workers-and-js-templates

DanielRuf avatar Nov 29 '23 11:11 DanielRuf

I had the same problem. I was rendering a component from within a CSUI component. The solution was, inside the rendered component, change a function declaration that was returning a hook to a function expression.

From:

function SomeComponent({ prop1, prop2 }) {
  ...
  function foo(val: string) {
    return useSomeDebouncingHook((val: string) => {
      ...
    }, 1000)
  }
  ...
}

To:

function SomeComponent({ prop1, prop2 }) {
  ...
  const foo = useSomeDebouncingHook((val: string) => {
     ...
  }, 1000)
  ...
}

The "sloppy" solution described in the doc linked to by @DanielRuf also worked, but didn't need to use it after changing function types.

robertsamarji avatar Nov 30 '23 01:11 robertsamarji