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

React.createElement: type is invalid #193

Closed
jankarres opened this issue May 15, 2017 · 12 comments
Closed

React.createElement: type is invalid #193

jankarres opened this issue May 15, 2017 · 12 comments

Comments

@jankarres
Copy link

I would love to use your react-player package with its well documented API, but I get an issue by just using your example. I write my code in TypeScript 2.x compiled to ES5. So the code looks a little bit different to normal JavaScript, but you provide an index.d.ts, so I think it should work with Typescript, too.

Integration of your player (simplified):

import * as React from "react";
import { render } from "react-dom";
import "../public/css/main.css";

import ReactPlayer from "react-player";

render(
  (
    <ReactPlayer url="https://www.youtube.com/watch?v=ysz5S6PUM-U" />
  ),
  document.querySelector("#app")
);

Stacktrack:

warning.js:36 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.
printWarning @ warning.js:36
warning @ warning.js:60
createElement @ ReactElementValidator.js:190
(anonymous) @ index.tsx:7
__webpack_require__ @ bootstrap e2420a7…:555
fn @ bootstrap e2420a7…:86
(anonymous) @ bootstrap e2420a7…:578
__webpack_require__ @ bootstrap e2420a7…:555
(anonymous) @ bootstrap e2420a7…:578
(anonymous) @ bootstrap e2420a7…:578
invariant.js:44

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.
    at invariant (invariant.js:44)
    at ReactCompositeComponentWrapper.instantiateReactComponent [as _instantiateReactComponent] (instantiateReactComponent.js:74)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:367)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at mountComponentIntoNode (ReactMount.js:104)
    at ReactReconcileTransaction.perform (Transaction.js:140)
    at batchedMountComponentIntoNode (ReactMount.js:126)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:140)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)

Do you have any idea what is wrong here? Thanks!

@cookpete
Copy link
Owner

From the error it looks like something weird is going on when ReactPlayer is being imported. Have you tried logging out ReactPlayer to narrow it down?

import * as React from "react";
import { render } from "react-dom";
import "../public/css/main.css";

import ReactPlayer from "react-player";

console.log(ReactPlayer); // Does this log undefined?

render(
  (
    <ReactPlayer url="https://www.youtube.com/watch?v=ysz5S6PUM-U" />
  ),
  document.querySelector("#app")
);

Next thing I would do is check that ReactPlayer installed correctly, ie thatnode_modules/react-player/lib/ReactPlayer.js exists.

@jankarres
Copy link
Author

jankarres commented May 15, 2017

Thanks for your fast support.

I did not check against undefined earlier, because I was sure I had installed it correctly. And it is installed (correctly).

[...]
import ReactPlayer from "react-player";
console.log(ReactPlayer);

logs undefined

[...]
import * as ReactPlayer from "react-player";
console.log(ReactPlayer);

logs

function ReactPlayer() {
	    var _ref;

	    var _temp, _this, _ret;

	    _classCallCheck(this, ReactPlayer);

	    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
	  …

If I try to create a new instance of the player with JSX (e.g. <ReactPlayer url="https://www.youtube.com/watch?v=ysz5S6PUM-U" />). The second variant have thrown the error:

[ts] JSX element type 'ReactPlayer' does not have any construct or call signatures.

I took a look at the typings there (line 42) is not constructor (nor in your JavaScript code). In TypeScript specification at 8.3, you can read a constructor is optional.

export default class ReactPlayer extends React.Component<ReactPlayerProps, any>{
  seekTo(fraction: number): void;
}

So... I am not sure if this could be an entry points for further thoughts? I am new in React development, so I am sorry, that investigation of stacks like this are still hard for me.

@cookpete
Copy link
Owner

Hey @jankarres, I've had a quick look around and it might be worth trying the allowSyntheticDefaultImports compiler option.

I think the problem is related to the fact that ReactPlayer gets compiled into ES5 in lib, but the typings file for ReactPlayer is written as if the compiled files use ES6 classes.

@jankarres
Copy link
Author

@cookpete Thanks for your investigation. It tinkered with it, but this was not the solution. Anyway, it was a good point to look for a reference to the issue.

The issue seems to be discussed at ES6 Modules default exports interop with CommonJS #2719. It seems to be a ES6 backwards compatibility issue. You can read the issue for details.

If figured out a solution, which works, but I am not sure if this is an appropriate solution for your Babel workflow, because this lines of code are generated by Babel.

lib/ReactPlayer.js end of file (line 227)

module.exports = exports['default'];

replace with

module.exports = _extends(exports['default'], exports);

The function _extends (wraps the export intro an es_modules definition) is a function of the ES6 classes standard, which is supported by all modern browsers except of IE 11 (see caniuse.com). But, this incompatibility with IE 11 should also not an issue, because with React you use packaging bundler like webpack. These bundler compress the code and stick it intro one file, which should follow in replacing export statements.

Do you see a possibility to replace this line of code in the project or configure Babel to solve this issues?

Attachment: Demo projects in TypeScript and JavaScript with replaced line. Run npm install after download. demo_projects.zip

@cookpete
Copy link
Owner

Ok, a bit more digging and it looks like the problem is that we use the add-module-exports babel plugin:

Using babel-plugin-add-module-exports appends module.exports setting line ... which disables exports.default and causes problems when using transpilers (like TypeScript) that does not have same interop rules to Babel.

From mui/material-ui#3594

It's worth building without that plugin and seeing if it helps?

The plugin was added when I added support for a bower build, so we may be able to remove it from the babel config file and just use the plugin for the bower build only.

@jankarres
Copy link
Author

Yes, I think it would be worth, because using React Player with TypeScript is currently not possible at all.

Removing lib/ReactPlayer.js end of file (line 227), as described, works for me.

module.exports = exports['default'];

I have tried to remove the plugin at my own to contribute a pull request (see commit), but if I fetch via npm I do not get a lib/ folder (nor an error). So I would be pleased if you could try to remove the plugin. Thanks a lot for your time!

@cookpete
Copy link
Owner

I have tried to remove the plugin at my own to contribute a pull request (see commit), but if I fetch via npm I do not get a lib/ folder (nor an error).

Do you mean fetch via git?

You will need to either manually run npm run build:compile in the react-player module folder to generate the lib files, or add it to your branch by removing lib from the .gitignore file, then compiling and adding/committing the lib files in git.

@jankarres
Copy link
Author

jankarres commented May 18, 2017

I mean via npm (as package manager) fetching the git repo. (not frpm npmjs). Anyway, it tested it and it works. Thanks for your support! It should works for both JavaScript and TypeScript. I would be pleased, if you would accept the pull request.

@octocat01
Copy link

@cookpete @jankarres I'm also facing this issue, can you please tell me what the workaround?

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: symbol.

Check the render method of ReactPlayer.

@JamesPHoughton
Copy link

Same issue as @octocat01, the code:

import React from "react";
import ReactPlayer from 'react-player';

export default class myComponent extends React.Component {

  render() {
    return (
      <ReactPlayer url='https://www.youtube.com/watch?v=ysz5S6PUM-U' />
    )
  }
}

Gives message:

modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:1362 Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: symbol.

Check the render method of `ReactPlayer`.
    at invariant (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:1362:15)
    at createFiberFromElement (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:11273:11)
    at reconcileSingleElement (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14229:23)
    at reconcileChildFibers (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14286:35)
    at reconcileChildren (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14690:28)
    at updateHostComponent (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14969:3)
    at beginWork (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:15411:14)
    at performUnitOfWork (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:17723:12)
    at workLoop (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:17761:24)
    at HTMLUnknownElement.callCallback (http://localhost:3000/packages/modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:1452:14)
invariant @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:1362
createFiberFromElement @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:11273
reconcileSingleElement @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14229
reconcileChildFibers @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14286
reconcileChildren @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14690
updateHostComponent @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:14969
beginWork @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:15411
performUnitOfWork @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:17723
workLoop @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:17761
callCallback @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:1452
invokeGuardedCallbackDev @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:1502
invokeGuardedCallback @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:1555
replayUnitOfWork @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:17052
renderRoot @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:17855
performWorkOnRoot @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:18694
performWork @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:18602
performSyncWork @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:18574
requestWork @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:18462
scheduleWork @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:18256
enqueueForceUpdate @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:12967
Component.forceUpdate @ modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:20137
(anonymous) @ ReactMeteorData.jsx:79
_compute @ tracker.js:308
_recompute @ tracker.js:324
Tracker._runFlush @ tracker.js:495
onGlobalMessage @ meteor.js?hash=857dafb4b9dff17e29ed8498a22ea5b1a3d6b41d:515
postMessage (async)
setImmediate @ meteor.js?hash=857dafb4b9dff17e29ed8498a22ea5b1a3d6b41d:535
requireFlush @ tracker.js:129
invalidate @ tracker.js:264
changed @ tracker.js:422
(anonymous) @ livedata_connection.js:1381
(anonymous) @ livedata_connection.js:1227
_runAfterUpdateCallbacks @ livedata_connection.js:1226
_performWrites @ livedata_connection.js:1216
_flushBufferedWrites @ livedata_connection.js:1167
_livedata_data @ livedata_connection.js:1133
onMessage @ livedata_connection.js:1663
(anonymous) @ browser.js:186
forEachCallback @ common.js:30
socket.onmessage @ browser.js:185
REventTarget.dispatchEvent @ sockjs-0.3.4.js:87
SockJS._dispatchMessage @ sockjs-0.3.4.js:1072
SockJS._didMessage @ sockjs-0.3.4.js:1130
that.ws.onmessage @ sockjs-0.3.4.js:1277
modules.js?hash=e25837b8e1be1864591085b1b56305f6910b53b7:15857 

The above error occurred in the <div> component:
    in div (created by ReactPlayer)
    in ReactPlayer (created by Message)

This is on:

node v14.13.1
meteor v1.11.1
react@16.13.1
react-player@2.6.2

@JamesPHoughton
Copy link

@cookpete - should I open the above as a new issue, or better to leave it here?

@cookpete
Copy link
Owner

Open a new issue, perhaps with an example repo? It's hard to debug an issue I can't reproduce.

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