Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught TypeError: Class extends value [object Object] is not a constructor or null in React Remix #2009

Open
mason-t3h opened this issue Jul 7, 2023 · 3 comments
Assignees

Comments

@mason-t3h
Copy link

Hi, I am getting the below error when I try to use twilio-video in my React Remix app, as far as I know the error shows when it is running imports, how can I fix this?

Uncaught TypeError: Class extends value [object Object] is not a constructor or null
at mediasignaling.js:1:1
at mediasignaling.js:7:30
at node_modules/twilio-video/es5/signaling/v2/mediasignaling.js (mediasignaling.js:76:1)
at __require2 (chunk-WX2OHN6X.js:18:50)
at node_modules/twilio-video/es5/signaling/v2/dominantspeakersignaling.js (dominantspeakersignaling.js:3:24)
at __require2 (chunk-WX2OHN6X.js:18:50)
at node_modules/twilio-video/es5/signaling/v2/room.js (room.js:4:34)
at __require2 (chunk-WX2OHN6X.js:18:50)
at node_modules/twilio-video/es5/signaling/v2/cancelableroomsignalingpromise.js (cancelableroomsignalingpromise.js:5:23)
at __require2 (chunk-WX2OHN6X.js:18:50)

I used
const Video = require('twilio-video')
and
import * as Video from 'twilio-video' both are not working

Here is my tsconfig.json

"compilerOptions": { "lib": [ "DOM", "DOM.Iterable", "ES2019" ], "isolatedModules": true, "esModuleInterop": true, "jsx": "react-jsx", "moduleResolution": "node", "resolveJsonModule": true, "target": "ES2019", "strict": true, "allowJs": true, "forceConsistentCasingInFileNames": true, "baseUrl": ".",

@idreaminteractive
Copy link

I ran into the same issue, but was unable to fix it via imports or config. I ended up instead importing the CDN version during page load and ensuring it only ran in client side.

So, on the routes I want to use Twilio, I added:

export const handle = {
    scripts: () => [
        {
            src: "//sdk.twilio.com/js/video/releases/2.27.0/twilio-video.min.js",
        },
    ],
};

Then, in my root.tsx file, I use the <ExternalScripts /> component from remix-utils which looks into the handle for each route.

In the components themselves, I ended up wrapping any video components in the <ClientOnly> component from the same remix-utils package to ensure it's browser side only. Like this:

<ClientOnly fallback={<Text>Please wait....</Text>}>
    {() => (
        <MyVideoComponent />
    )}
</ClientOnly>

Lastly - to get type defs, I wrote a super hacky, function like this:

/* eslint-disable @typescript-eslint/consistent-type-imports */
export function getBrowserTwilio() {
    if (typeof document === "undefined") {
        // Server should just not do anything. Wrapping all the stuff in <ClientOnly> should ensure that
        return {} as typeof import("twilio-video");
    }
    return (window as any).Twilio.Video as typeof import("twilio-video");
}

When I call getBrowserTwilio - I get an object which returns the Twilio.Video object on the window. It works, but certainly not ideal. If we end up continuing with Twilio, we'll likely dig deeper and hopefully find a cleaner option.

@manjeshbhargav
Copy link
Collaborator

@mason-t3h ,

Thanks for writing in. Can I have access to your repository so that I can try a few things on my local dev machine?

@manjeshbhargav manjeshbhargav self-assigned this Jul 25, 2023
@yemi
Copy link

yemi commented Aug 2, 2023

Also having this issue, running @remix-run/dev 1.19.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants