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

Support isomorphic/SSR environments (Node.js) #1813

Closed
rezonant opened this issue Jul 2, 2018 · 14 comments
Closed

Support isomorphic/SSR environments (Node.js) #1813

rezonant opened this issue Jul 2, 2018 · 14 comments

Comments

@rezonant
Copy link

rezonant commented Jul 2, 2018

For isomorphic web apps which can be run on the server-side in Node.js, hls.js cannot be directly bundled into the application because of it's unguarded use of window and other browser-only APIs.

Ideally hls.js should detect this condition and prevent usage of browser APIs when running on the server.
The workaround for isomorphic applications is to load it separately from CDN and then utilize the Hls global.

@tjenkinson
Copy link
Member

Are you not able to skip loading the library when running in node? It seems strange that a library that is meant to be used in the web browser also has to partly work in node. There is a discussion about this here: #1642

@rezonant
Copy link
Author

rezonant commented Jul 2, 2018

Strange, yes. Unfortunate, yes. Needed for isomorphic? Also yes.
Not loading hls in server side mode would require a dynamic import which can cause it's own issues. I look forward to the PR landing!

@rezonant
Copy link
Author

rezonant commented Jul 2, 2018

Erm, wait it's merged, has this hit a release?

@tjenkinson
Copy link
Member

It was reverted because we decided it isn't really make sense and should be handled by the library you are using. It just adds extra overhead to hls.js which is not required for it to function in a browser. Please can you provide more information about your setup and the build system you are using?

@rezonant
Copy link
Author

rezonant commented Jul 2, 2018 via email

@friday
Copy link
Contributor

friday commented Jul 18, 2018

If you just want the require not to break (which isn't the only interpretation of "server side rendering"), this is quite easy to achieve. You just have to wrap your module declaration so the code inside never runs when there is no window. The module exported will default to an empty object, and you don't have to check the code in each place browser-specific API's are used.

You should be able to add this to all bundles using Webpack. I haven't tried, but adding it for Rollup was easy:
https://github.com/sampotts/plyr/pull/960/files

I haven't tested it for native es6 imports in Node.js (.mjs-files). (hls.js doesn't support this anyway, so this doesn't apply).

@rezonant
Copy link
Author

rezonant commented Jul 18, 2018

No the import isn't the problem, the unguarded use of window is, as I said. Node.js doesn't have a window object, so it's NameError on execution. I could polyfills window, but I was sloppy and used typeof window as a check for SSR instead of isPlatformServer which is the proper way. Protip for anyone doing Angular SSR: situations like these is why you should always use isPlatformServer.

I will eventually clean that up, polyfill window, and bundle hlsjs but for now I'm pulling it from cdn on demand which is a fine workaround for the time being.

Edit: And conditional checks are something to avoid when your build tool is statically analyzing your code, though it might still work if someone hits this and is braver than me, but I've been burnt in subtle and nonobvious ways doing that in the past with Angular CLI's builds

EDIT (way later): I simply misunderstood that the previous comment was targetted at an hls.js improvement as opposed to a workaround for users of hls.js

@friday
Copy link
Contributor

friday commented Jul 19, 2018

I guess you're right, and all these people are wrong then: sampotts/plyr#935 ;)

@rezonant
Copy link
Author

I believe those people agree with me actually?
The PR to plyr corrects the unguarded use of navigator.

Look I'm not declaring any right or wrong here, just pointing out that hls.js doesn't play nicely with SSR as well as it could, but I understand that it might be more work than it's worth to make that happen, and SSR folks will have to work around that, whether by not bundling hls.js and using CDN instead or by a (potentially risky) bypass of the static analysis systems of their build tools.

It's all good!

@friday
Copy link
Contributor

friday commented Jul 19, 2018

The PR to plyr corrects the unguarded use of navigator.

That's the same PR I linked to and described in the first post which you violently disagreed with.

Look I'm not declaring any right or wrong here,

Really? How about "No the import isn't the problem, the unguarded use of window is, as I said"

Addition:
Sorry for anyone else in here getting notifications or reading this. I just can't stand this sort of behaviour.

@rezonant
Copy link
Author

rezonant commented Jul 19, 2018

Oh I see, sorry you were offended by my tone, there was no malicious intention. It's just that these tools are ESM tools, and require() can really cause some headaches in my experience when the tools are speaking ESM. And you cannot conditionally import as others have noted. Sorry for seeming brash in my original comment.

Edit: yeah that PR is doing what this issue originally advocated for: fix the library to not assume environments, at least during load if not during execution.

@rezonant
Copy link
Author

Closing this as it's fairly clear it's already been addressed elsewhere.

@friday
Copy link
Contributor

friday commented Jul 19, 2018

It's just that these tools are ESM tools.

Hls.js is built to UMD:
https://github.com/video-dev/hls.js/tree/master/dist
https://github.com/video-dev/hls.js/blob/master/webpack.config.js#L167
https://github.com/video-dev/hls.js/blob/master/package.json#L15

So adding a "header" to the build such as my suggestion still seems feasible to me. And also wouldn't affect any static code analysis like you previously suggested unless you run them on the build output (which wouldn't be a great use for static code analysis).

The fact that the source code is ESM doesn't matter unless you're specifically importing it from 'hls.js/src/hls.js', and don't transpile your code, and also live in the future, since Node doesn't supports ESM without the .mjs-extension at this point.

require() can really cause some headaches in my experience when the tools are speaking ESM. And you cannot conditionally import as others have noted.

I know of it, which is why again I wanted to help and linked to + explained a feasible solution (Plyr also uses ESM internally but the distribution builds to UMD).

Closing this as it's fairly clear it's already been addressed elsewhere.

As has been mentioned, the previous PR was reverted because it tackled the solution in the wrong way, and didn't fully solve the problem. That's why I posted.

Edit:
Moderated out parts that can be perceived as inflammatory. Since the author has now reversed his position about the original post (see his edit), there's no longer any argument to be had, and those arguments or comments are no longer filling any purpose (but anyone can see the edit diff).

@rezonant
Copy link
Author

rezonant commented Jul 19, 2018

I don't think I'm the one being unreasonable about this.

It sounds like what you want to do is change hls.js to make this work better, and that's great, I'm all for it.

Edit: Feel free to refile, I'm unsubscribing on this.

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