Closed hanfeisun closed 6 years ago
I think this was the issue behind https://github.com/videojs/mux.js/pull/53. That was fixed in mux.js >= 2.0.1, which you should use if you build this project yourself (and in our next release when that happens). Do you see the same error if you build contrib-hls yourself?
+1
Going to try building contrib-hls myself now.
Eh - no luck... @hanfeisun did you find a solution?
@samward1985 No, it doesn't work under Webpack now.. So I am still using videojs-contrib-hls 1.3.11
..
Hello all!)
You can set alias for hls in webpack config. It works for me:
resolve: { alias: { 'videojs-contrib-hls': __dirname + '/node_modules/videojs-contrib-hls/dist/videojs-contrib-hls' } }
videojs-contrib-hls v2.2.0
I think contrib-hls 2.2.0 won't require any aliases anymore. Though, unfortunately, that version also requires videojs 5.10.1 and up.
@gkatsev i have videojs v5.10.2, but webworkify breaks webpack build because of no fallbacks for arguments
If webworkify is the only problem, we should consider swapping it out for another module with similar functionality that works in both webpack and browserify.
There seems to be a webworkify-webpack module which may work for webpack but it doesnt work for browserify. Someone should write a module that works for both.
After some thought and some discussion in babel's chatroom, it seems like the correct solution is to not rely on a packer transform or loader to the web worker inline but rather do it as a separate source transform. I saw https://github.com/mohayonao/inline-worker which may help but also maybe there's some babel plugin that allows us to do this. Unfortunately, this is a low priority for us because there's more pressing specific issues and it can be worked around by using the dist file or maybe running webworkify-webpack over the code. If anyone is willing to submit a PR to fix this issue we'll definitely take a look and work with you to land it. Thanks!
I was having the same issue with webpack and contrib-hls. I was able to get it working by aliasing webworkify to webworkify-webpack in my webpack config like so:
// ...
resolve: {
alias: {
webworkify$: 'webworkify-webpack'
}
},
// ...
The strange caveat is that I need point to version 1.0.6 in my package.json instead of the current version (which is 1.1ish). Got that little tidbit from a separate issue here
Hope this helps anyone!
I am facing the same and added below code too.
resolve: { alias: { 'videojs-contrib-hls': **dirname + '/node_modules/videojs-contrib-hls/dist/videojs-contrib-hls', webworkify$: 'webworkify-webpack' } }, and getting this error 19:31:03.939 TypeError: _videoJs2.default is undefined [72]</<() bundle.js%20line%205005%20%3E%20eval:8312 [72]<() bundle.js%20line%205005%20%3E%20eval:7848 s() bundle.js%20line%205005%20%3E%20eval:7 s/<() bundle.js%20line%205005%20%3E%20eval:7 [71]</<() bundle.js%20line%205005%20%3E%20eval:7668 [71]<() bundle.js%20line%205005%20%3E%20eval:7640 s() bundle.js%20line%205005%20%3E%20eval:7 s/<() bundle.js%20line%205005%20%3E%20eval:7 [76]</<() bundle.js%20line%205005%20%3E%20eval:8886 [76]<() bundle.js%20line%205005%20%3E%20eval:8870 s() bundle.js%20line%205005%20%3E%20eval:7 s/<() bundle.js%20line%205005%20%3E%20eval:7 [94]</<() bundle.js%20line%205005%20%3E%20eval:14668 [94]<() bundle.js%20line%205005%20%3E%20eval:14627 s() bundle.js%20line%205005%20%3E%20eval:7 e() bundle.js%20line%205005%20%3E%20eval:7
this is giving the error of webworkify-webpack: Could not locate module containing worker function! Make sure you aren't using eval sourcemaps and that you pass named functions to webworkify-webpack!
If anyone else encounters this issue again (or a similar one) and wants to use videojs-contrib-hls with Webpack:
webworkify-webpack
shims window to {}, which causes global/window
to return the wrong context in a web worker, which in turn causes things to fail. I've created a fork of webworkify-webpack
that's compatible with the original webworkify
and works with videojs-contrib-hls!
Just add webworkify-webpack-dropin@^1.1.9
to your dependencies and add the following alias to your Webpack config:
resolve: {
alias: {
webworkify: 'webworkify-webpack-dropin',
},
}
It's been tested on videojs-contrib-hls v3.7.0-beta3 and video.js 5.12.6.
Anyone know of a babel webworkify plugin? If we can inline the webworker at that point, we can easily support both webpack and browserify without extra work on the user's part
@Ambroos also, thanks for making the dropin replacement package, seems like it'll make things a lot simpler in the meantime.
@Ambroos I've tried your solution and I'm getting an error thrown here in webworkify-webpack-dropin:
if (typeof key === 'undefined') {
throw new Error('webworkify-webpack: Could not locate module containing worker function! Make sure you aren\'t using eval sourcemaps and that you pass named functions to webworkify-webpack!');
}
I've made sure that I'm not using eval sourcemaps.
I've upgraded my versions of videojs-contrib-hls and video.js to v3.7.0-beta3 and 5.12.6, respectively. The only difference is my project is a react app using nwb, if that makes any difference. Any ideas?
@vpowers Could you show me your webpack config? I can't really think of any reason for this error to appear.
@Ambroos Here is my nwb.config.js. Webpack configuration is passed in:
module.exports = {
...
webpack: {
devtool: 'cheap-source-map',
html: {
favicon: 'vendors/favicon.ico'
},
extra: {
resolve: {
alias: {
webworkify: 'webworkify-webpack-dropin'
}
}
}
}
}
Here is the line in virtual-source-buffer.js (es5) from videojs-contrib-media-sources that executes webworkify-webpack-dropin:
// append muxed segments to their respective native buffers as
// soon as they are available
this.transmuxer_ = (0, _webworkify2['default'])(_transmuxerWorker2['default']);
I've attempted to isolate the issue by creating a small app using videojs-contrib-hls and bundling with webpack and @Ambroos 's solution does work. I had been testing this within a larger react app that uses nwb so somethings going on there. I'll provide an update if I can figure out the issue.
@Ambroos's solution worked for me, but I had to turn off eval for source maps in my large react app, @vpowers. (edit: I see now that you're using cheap-source-map, so that probably won't help you)
@dbryand My react app is using nwb for bundling instead of plain webpack. (nwb uses webpack under the hood). This seems to be the difference. Are you just using webpack?
Yes, a home-rolled webpack config.
I've created two small applications. One using webpack and video.js with hls plugin and a react app using nwb (https://github.com/insin/nwb) and video.js with hls plugin. Both of them are swapping out the webworkify module with @Ambroos's webworkify-webpack-dropin module. The webpack app is working with this solution but the react app using nwb is not. If anyone has any experience with nwb or is feeling helpful, take a look at these projects. Any help would be appreciated!
https://github.com/vpowers/simple-react-app https://github.com/vpowers/simple-webpack-app
In case someone comes along and needs to support videojs-contrib-hls in a react app using nwb, I have forked @Ambroos webworkify-webpack-dropin
to support how nwb bundles code:
https://github.com/vpowers/webworkify-nwb
Follow the instructions in this comment but use the module above instead.
I wonder if we can turn webworkify into a babel plugin. Then we could just run it at build time and users of contrib-hls won't need to bother with configuring their bundlers.
Hi, guys, could please someone explain how to use this inside SPA? I tried @vpowers solution, but I still get webworkify-webpack: Could not locate module containing worker function! Make sure...
I'm using vuejs
Thank you in advance.
Running into this issue here as well, same error as @oleynikd is reporting - any updates since last month on this? Also using vuejs and importing as es6 module, compiling with webpack. Tried the webworkify-webpack-dropin plugin but no dice.
So Basically here is the setup you need to get this up and running.
I am using node 7.4 and a boiler from create-react-app.
This is my webpack config:
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We read `NODE_PATH` environment variable in `paths.js` and pass paths here.
// We use `fallback` instead of `root` because we want `node_modules` to "win"
// if there any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
fallback: paths.nodePaths,
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx', ''],
alias: {
'videojs-contrib-hls':paths.appNodeModules+'/videojs-contrib-hls/dist/videojs-contrib-hls.min.js'
}
}
I am also using this plugin to set videojs globally on my scope:
new webpack.ProvidePlugin({
videojs: "video.js",
"window.videojs": "video.js"
}),
Additionally on my video component JS I use the following:
import 'videojs-contrib-hls';
let video;
Later on my component did mount:
componentDidMount(){
const options = {
height: "100%",
width: "100%",
hls: {
withCredentials: true
}
};
video = window.videojs("video-player", options);
}
finally you need to set your src m3u8 file and type using Javascript if not this will not work:
video.src({
src:'https://master.m3u8',
type: 'application/x-mpegURL'
});
video.play();
render(){
return(
<video id="video-player" controls preload className="video-js" poster="videoposter.jpg"/>
);
}
Finally got my video to play hope this helps!
You will need to use the same plugin and change the alias in your production configuration so the library can run properly:
USE THE ES5 VERSION
'videojs-contrib-hls':paths.appNodeModules+'/videojs-contrib-hls/es5/videojs-contrib-hls.js'
ADD THE WEBWORKIFY DROPIN
'webworkify$': 'webworkify-webpack-dropin',
NPM Modules used:
"video.js": "^5.12.6",
"videojs-contrib-hls": "^3.7.0-beta3",
"webworkify-webpack-dropin": "^1.1.9"
Thanks for this @lionxcr, I was able to set it up following your guide. Is there no other way to integrate it more seamlessly without additional Webpack config? Thanks!
@icetronics You are so welcome! As far as I know contrib-hls is not supported in webpack just yet so by far this is the best hack to get m3u8 videos to work properly in react.
The reason why is because we use browserify to build out the pre-build standalone file. To do that we use the webworkify module that you're replacing with the dropin one for webpack. What would need to happen is to switch to either a babel plugin or something external to the bundler to do the webworker inlining.
Thanks @gkatsev! Would you be able to provide an example or some further pointers so I could try setting it up?
In case there are people having the same problems as I did:
I have been trying to make this work with webpack 2.2.1, video.js 5.18.4 and videojs-contrib-hls 5.3.3. I was able to get webworkify-webpack-dropin
to work with a small change: https://github.com/Ambroos/webworkify-webpack-dropin/pull/1/files . I am hoping @Ambroos will merge the PR and release the version to NPM soon.Change in plans. I am trying to release a fix as a separate npm package, yet still trying to figure out how to make it work with uglify-js atm. Gave up :(
@cansin and anyone else who's using webpack's UglifyJsPlugin
. I found that if I set compress
to false
and mangle
to true
, like so:
plugins: [
...
new webpack.optimize.UglifyJsPlugin({
compress: false, // leave false for now. This breaks the videojs-contrib-hls package
mangle: true,
sourceMap: true
}),
...
],
This will uglify it without breaking the videojs-contrib-hls
package. For me, it was like less than 40KB difference between compress
being true
vs false
.
I'm also importing the package like so: import 'videojs-contrib-hls/dist/videojs-contrib-hls.min.js'
This is a nice workaround for me until videojs-contrib-hls
is compliant with the compression tool
I actually couldn't figure out how to make webworkify-webpack-dropin
work with my case. Instead I ended up separating videojs-contrib-hls through:
require.ensure(['videojs-contrib-hls/dist/videojs-contrib-hls.min'], require => {
require('videojs-contrib-hls/dist/videojs-contrib-hls.min');
}, 'package-videojs-contrib-hls');
and then disabled UglifyJS for this separate bundle via:
new webpack.optimize.UglifyJsPlugin({
sourceMap: false,
compress: {
warnings: false,
},
exclude: /package-videojs-contrib-hls/,
})
I know this is less than ideal, yet it works for now. Could be an alternative to what you did @everett1989 .
@cansin I'll try it out, thanks for the example
hi all, does anyone know if this webpack fix works when deploying to heroku? I am currently trying to deploy to heroku and I am getting an 'Uncaught SyntaxError: Unexpected token {'
EDIT: With the help of zshenker on Slack I followed @Ambroos but that required me to turn off my source maps. This got me over the error referenced above, but then it ultimately fails to load because I get a simple syntax error "Uncaught SyntaxError: Unexpected token {". Is their really no way to turn on source map with webworkify?
EDIT2: So the syntax error problem appears to be occurring because of the common UglifyJs plugin in my webpack.config. When I get rid of it, the error goes away, but unfortunately that leaves me with a file that went from 1.04MB to 2.86MB. Ideas on how to fix those syntax errors and still use Uglify?
EDIT3: It appears to be a problem with the version of uglify that is bundled with the latest Webpack v1 (1.14.0). I installed uglifyjs globally and ran the bundle.js file through the command line manually, with no syntax error. It also maintains roughly the same as listed above. So I guess I'll try to update to Webpack 2 soon and verify if the error exists there.
it's not UglifyJs's bug it's bug in this code https://github.com/Ambroos/webworkify-webpack-dropin/blob/master-v1/index.js#L92
it appears when code is minimized and unused function names are removed
moduleWrapperStrings[moduleId] = wrapperFuncString.substring(0, wrapperFuncString.length - 1)
+ '\n' + fnString.match(/function\s?(.+?)\s?\(.*/)[1] + '();\n}';
this regex is matching function name but if there is none it will match some weird shit
and syntax error will appear after compilation in webworker code generated at runtime in browser
@thecotne Thanks. I had suspected that because for debugging purposes I also moved to Webpack 2, and that didn't fix the issue (has more up to date Uglifyjs) I temporarily solved it by running uglify as part of my "npm build" script outside of webpack. Looks like he just needs to pull from where he forked from because they claim to have a fix that works with Uglify. I'll look at that today.
When I try to compress the js bundle using webpack and uglify, in the browser console, I get this error
Uncaught ReferenceError: e is not defined
@serv Yep. As was discussed in my posts above, there is a very strict regex function in the current version of webworkify-webpack-dropin. Uglify gains one of its shrinkage abilities by deleting functions that it determines are unused, but webworkify is still looking for them. For now, just turn off uglify in webpack, or you can make a npm script that builds your webpack and then runs uglify, which I did with success. I will be trying to get @Ambroos to update his fork here soon, given that I suggested that people use it in the webpack docs.
Ok... So webworkify-webpack worked for a few weeks to months, then webworkify-webpack-dropin worked for a few more. Now I am on the latest of everything (contrib-hls: 5.4.1, video.js: 5.19.2 as of this writing) and everything is working! Here is how I did it:
Alias videojs-contrib-hls per @lionxcr's suggestion:
// webpack.config.js
var path = require('path');
// ...
resolve: {
alias: {
'videojs-contrib-hls': path.join(
__dirname,
'node_modules',
'videojs-contrib-hls',
'dist',
// You can use the unminified version and let the minifier minify!
'videojs-contrib-hls.js'
),
}
}
// ...
Make videojs
global (also per @lionxcr's suggesiont):
// webpack.config.js
// ...
plugins: [
new webpack.ProvidePlugin({
videojs: "video.js",
"window.videojs": "video.js"
})
]
// ...
After all of that, I was getting the same error as @serv. After some digging, I found the DefinePlugin. It turns out uglify was doing strange things with global
, so I aliased typeof global
to "undefined"
so that the minifier would remove it!
// webpack.config.js
// ...
plugins: [
new webpack.DefinePlugin({
'typeof global': JSON.stringify('undefined')
})
]
// ...
Also, if at some point had you aliased webworkify
, un-alias it!
// webpack.config.js
// ...
resolve: {
alias: {
// webworkify$: 'webworkify-webpack',
// webworkify$: 'webworkify-webpack-dropin',
}
}
// ...
Phew! That works for now... Hope this helps!
So far I can create development bundle without a problem and plugin works perfectly, but when I build production I get this error in run-time:
Uncaught ReferenceError: n is not defined blob:http://localhost/659f9283-bbc2-4836-ae79-ebb3cd70a83a:1
I solve this issue passing:
devtool: (isProd ? '#eval' : '#source-map')
my original set up is
devtool: (isProd ? false : '#source-map')
The problem is that my bundle pass from 1.3MB to 4.3MB when I set eval to devtool. has anyone solve this issue completely?
The solution by @ScottLNorvell worked for me, but this part led to some very tricky to debug issues with another library (GSAP) in my app.
new webpack.DefinePlugin({
'typeof global': JSON.stringify('undefined')
}),
In retrospect it seems obvious that other libs may rely on the typeof global
and this could blow things up.
EDIT: In removing this I don't see any impact to video.js / hls.
?? Decided to visit this again today because I got the classic error 'fs is not defined' in Safari (but not Chrome). But I still can't get webpack to run uglify from the config file. It passes, but then gives like above, 't is not defined in blob' when the page is opened. So I'm going back to my method of just running webpack, and then using uglify after the fact. Somehow that doesn't cause any problems.
Now have confirmed that I'm getting the dreaded 't is not defined', too, when I package and ship to s3.
EDIT: I turned off uglification in the app and it works.
@dbryand same here "t is not defined"
. Did you find any solution?
Yes, I dropped videojs and just went with html5 + hls.js. Sorry I can't be more helpful :)
In the version of 1.x videojs-contrib-hls, I can shim the package like this:
However, in 2.0.1 videojs-contrib-hls, this method doesn't work.
A dependency called
webworkify
will throw an errorWill videojs-contrib-hls plan to support webpack in the future?