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

import ReactPlayer from 'react-player/lazy' fails with vite #1443

Open
DouglasDev opened this issue Apr 22, 2022 · 16 comments · Fixed by #1537
Open

import ReactPlayer from 'react-player/lazy' fails with vite #1443

DouglasDev opened this issue Apr 22, 2022 · 16 comments · Fixed by #1537

Comments

@DouglasDev
Copy link
Contributor

DouglasDev commented Apr 22, 2022

Current Behavior

The app crashes with the following error:

Uncaught Error: Element type is invalid. Received a promise that resolves to: [object Object]. Lazy element type must resolve to a class or function.
at mountLazyComponent (react-dom_client.js?v=53134127:14671:17)
at beginWork (react-dom_client.js?v=53134127:15653:22)
at beginWork$1 (react-dom_client.js?v=53134127:18882:22)
at performUnitOfWork (react-dom_client.js?v=53134127:18358:20)
at workLoopSync (react-dom_client.js?v=53134127:18298:13)
at renderRootSync (react-dom_client.js?v=53134127:18277:15)
at recoverFromConcurrentError (react-dom_client.js?v=53134127:17900:28)
at performConcurrentWorkOnRoot (react-dom_client.js?v=53134127:17848:30)
at workLoop (react-dom_client.js?v=53134127:195:42)
at flushWork (react-dom_client.js?v=53134127:174:22)
mountLazyComponent @ react-dom_client.js?v=53134127:14671
beginWork @ react-dom_client.js?v=53134127:15653
beginWork$1 @ react-dom_client.js?v=53134127:18882
performUnitOfWork @ react-dom_client.js?v=53134127:18358
workLoopSync @ react-dom_client.js?v=53134127:18298
renderRootSync @ react-dom_client.js?v=53134127:18277
recoverFromConcurrentError @ react-dom_client.js?v=53134127:17900
performConcurrentWorkOnRoot @ react-dom_client.js?v=53134127:17848
workLoop @ react-dom_client.js?v=53134127:195
flushWork @ react-dom_client.js?v=53134127:174
performWorkUntilDeadline @ react-dom_client.js?v=53134127:382
Show 11 more frames

Expected Behavior

I expect the video to load

Steps to Reproduce

  1. Download my minimal example: https://github.com/DouglasDev/vite-react-player-bug
  2. run npm i
  3. run npm run dev
  4. The app will crash

Environment

  • URL attempting to play: any
  • Browser: chrome v 100
  • Operating system: mac
@cookpete
Copy link
Owner

cookpete commented May 3, 2022

It seems like my implementation of lazy loading players is prone to errors. I am open to better suggestions.

Would it be better to just have a component that accepts a players array and you just import anything that you need? eg:

import ReactPlayerCustom from 'react-player/custom'
import Youtube from 'react-player/youtube'
import Facebook from 'react-player/facebook'

<ReactPlayerCustom players={[Youtube, Facebook]} etc etc />

@DouglasDev
Copy link
Contributor Author

I think the current api is good. I have an app where a user can enter any video url so it would be good if react player could automatically figure out which player to load (like it's doing now) since I can't know in advance. If I have time today, maybe I can figure out what the actual cause of the error is and open a PR.

@cmaerz
Copy link

cmaerz commented May 10, 2022

@cookpete That looks great. We import everything cause of that problem, but only use file with hls at radio.net.
Also disableDeferredLoading should be documented. :)

@cookpete
Copy link
Owner

@cmaerz I have to ask… why not just use hls.js directly instead of importing this whole library?

@cmaerz
Copy link

cmaerz commented May 10, 2022

@cookpete We mostly play radio streams i guess that mostly uses either just the file player or the hls player. I had problems with just importing the file player, but tbh I don't really know why.

@DouglasDev
Copy link
Contributor Author

DouglasDev commented May 10, 2022

@cookpete Haven't had time to write a fix but I think the issue is that vite uses native ESM imports whereas ReactPlayer appears to use ESM in the source code but exports CommonJS in the npm package. So I think just adding an untransformed ESM version to the npm package would fix the bug.

@mpech
Copy link

mpech commented May 16, 2022

If it may help, problem stems from dynamic imports of players/index

var _default = [{
  key: "youtube",
  name: "YouTube",
  canPlay: _patterns.canPlay.youtube,
  lazyPlayer: (0, _react.lazy)(function() {
    return import(
      /* webpackChunkName: 'reactPlayerYouTube' */
      "./YouTube-PILJPAEI.js"
    ).then(m => {
      console.log('lazy vite')
      /*
        Here in vite, m is a module
        m.default contains { default: fn, __esModule: true }

        in wp, returning m is ok, in vite it is not
      */
      // below fix for vite
      return m.default
    });
  })
}

A workaround would be e.g to lazyPlayer: lazy(() => import(/* webpackChunkName: 'reactPlayerYouTube' */'./YouTube').then(m => m.default.default ? m.default : m))

pretty much what does

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { "default": obj };
}

This feels a lot intrusive in source code so I guess an esm export would be preferrable (as @DouglasDev suggested)?

@alexnault
Copy link

We are also facing the same issue with Vite in dev (esbuild). I think an ESM export would be the best way forward too.

@mutheusalmeida
Copy link

I'm getting the same error. Anyone with a solution?

@LWest001
Copy link

LWest001 commented Feb 7, 2023

I'm still having this issue using React Player in an app that builds with Vite. App crashes in dev but works in production using react-player/lazy. Is there a workaround for this?

@GabrielCousin
Copy link

Hi @cookpete! Do you think we could reopen this issue (at least for clarity sake)? Thank you so much!

@martavis
Copy link

I also have this issue. For now, we're not using lazy but we definitely experienced the crash after moving to Vite from CRA.

@cookpete cookpete reopened this Jul 19, 2023
@pedrosousa13
Copy link

Would using @loadable/component be interesting in this case instead of lazy? I tried locally and it seems to work.

@OciepaJakub
Copy link

Maybe it's a little bit too late but in my case the import of lazy component throw general error about not found the start template. I realizied the solution:

import { Suspense, lazy, useEffect, useState } from 'react' import { BaseReactPlayerProps } from 'react-player/base'
const Loader = () => { return ( <div className='w-10 h-10 border-[2px] bg-slate-500 rounded-full animate-spin'></div> ) }

const VideoPlayer = (props: BaseReactPlayerProps) => {
const [Component, setComponent] = useState<React.ComponentType<BaseReactPlayerProps> | null>(null);

useEffect(() => {
    setComponent(() => lazy(() => import('react-player/lazy')))
}, [])

if (!Component) {
    return <Loader />;
}

return (
    <Suspense fallback={<Loader />}>
        <Component {...props} />
    </Suspense>
)

}

export default VideoPlayer;

I've used node 20.x, vite 5.0, react 18.2, react-player 2.16.0, together with the Laravel / Inertia stack. Hope this would help someone.

@luwes
Copy link
Collaborator

luwes commented Apr 20, 2024

this should be fixed in v3.0.0-canary.3
https://www.npmjs.com/package/react-player/v/3.0.0-canary.3
https://codesandbox.io/p/devbox/react-player-vite-6n78q7

note that this version has only ESM builds for now, we are testing if CJS or IIFE is actually still needed.

@romankoho
Copy link

@luwes any idea why my import/linter shows an error after updating to v3.0.0-canary.3?

import ReactPlayer from 'react-player/lazy'

ESLint: Unable to resolve path to module 'react-player/ lazy'.(import/ no-unresolved)

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

Successfully merging a pull request may close this issue.