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

Importing VideoJS as ES6 module not working properly. #2698

Closed
misteroneill opened this issue Oct 13, 2015 · 11 comments
Closed

Importing VideoJS as ES6 module not working properly. #2698

misteroneill opened this issue Oct 13, 2015 · 11 comments

Comments

@misteroneill
Copy link
Member

I noticed today that importing VideoJS and attempting to access properties on it (e.g., import videojs from 'video.js'; videojs.getComponent('Foo');) throws an undefined property error.

After investigating with @gkatsev, it appears this is caused by the way videojs is being exported in the video.js source file. Because videojs is the default export, accessing properties of it (as above) ultimately gets transpiled to something like _videoJs2['default'].getComponent('Foo').

The most direct solution is to have videojs['default'] = videojs;.

@nickygerritsen
Copy link
Contributor

Huh? We are doing exactly that already for quite some time and it still seems to work:

/**
 * @file related-content.js
 */

import videojs from 'video.js';
import * as utils from '../../utils.js';

const VjsComponent = videojs.getComponent('Component');

[...]

This works correctly for us. We use browserify + babelify (just like video.js) and we can succesfully compile and run this code.

@gkatsev
Copy link
Member

gkatsev commented Oct 14, 2015

The main issue comes with whether you import videojs directly or not. If you add videojs as a global and then try to import it via browserify-shim, it will fail because babel will either export things as es6-modules or commonjs but not both. I have some more detailed notes on this that I'll post later today.

@gkatsev
Copy link
Member

gkatsev commented Oct 14, 2015

See babel/babel#2047 and babel/babel#2212 and http://babeljs.io/docs/usage/modules/#interop
Basically, the issue is that if you export the module using es6, it'll get exported as an es6 module and you should be importing it as an es6 module directly. But if you are importing it using commonjs, may fail or require you to require('video.js').default it.
But we are also using videojs as a UMD build but we have some plugins that use babelify/browserify themselves but they import videojs via browserify-shim and assume it is available in the global scope. This will make videojs get imported as purely a commonjs dependency but babel will try to access properties through the default property which doesn't exist since it was a commonjs import and not a es6 import and so it fails.
Ultimately, they specifically chose to not allow this kind of interopability. The direct and easiest solution is to just have videojs export itself with a default property that points to itself. A more "correct" approach would be perhaps write a custom-module-formatter for babel that supports this automatically. I've looked and I don't think anyone has written something like that already.

@gkatsev
Copy link
Member

gkatsev commented Nov 5, 2015

Some background on babel's interop: https://stackoverflow.com/questions/33505992/babel-6-changes-how-it-exports-default/33506169#33506169
It is changed in babel 6.x slightly.

@gkatsev
Copy link
Member

gkatsev commented Nov 29, 2015

Check out https://www.npmjs.com/package/babel-plugin-add-module-exports when updating to babel 6.x.

@gkatsev
Copy link
Member

gkatsev commented Feb 8, 2016

I think what we probably should do is not use ES6 export at all for the main module export.
So, use import and export internally, but until the loader spec is finished, only export video.js itself with module.exports. This should mean that babel doesn't try to do any interop, doesn't set __esModule and so, it'll be able to get imported properly by commonjs and also by babel.

@gkatsev
Copy link
Member

gkatsev commented Feb 8, 2016

@gkatsev
Copy link
Member

gkatsev commented Apr 3, 2016

This also applies to projects like contrib-hls and all the other projects we're using browserify with.

@qknow-w
Copy link

qknow-w commented Dec 1, 2016

 import vjs from '../../node_modules/video.js/dist/video';

this is my code

@misteroneill
Copy link
Member Author

I believe this is fixed now and doing import videojs from 'video.js' should work.

@MarksCode
Copy link

I keep getting an error on this line

  // https://github.com/videojs/video.js/issues/2698
  videojs['default'] = videojs;

Uncaught TypeError: Cannot set property 'default' of undefined

Anybody know why this might be happening?

I'm importing it in my react component like this:

const videojs = require('public/jscripts/brightcove/index.js');

where the public/jscripts/brightcove/index.js is just the brightcove script here: https://players.brightcove.net/1752604059001/B1xXFuBodW_default/index.js

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants