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

Migrate to Rollup with new ESM target and UMD Worker injection #5299

Merged
merged 18 commits into from Mar 27, 2023

Conversation

robwalch
Copy link
Collaborator

@robwalch robwalch commented Mar 15, 2023

This PR will...

Migrate from Webpack to Rollup, and improve build output and worker options.

  • Adds new config option workerPath (defaults to null)
    • Adds output "hls.worker.js" as an (optional) alternative path to worker setup for developers not using the UMD library by pointing workerPath to this script
  • Adds ES Module output "hls.mjs"
  • Payload size is reduced (hls.min.js is roughly 369K vs 409K with webpack and new features in v1.4.0)
  • UMD builds are transpiled to ES5 with CI checks

Why is this Pull Request needed?

Webpack 5 boilerplate was not getting transpiled to ES5 (#5288). Rollout payload is smaller, and presents an opportunity to address several library output issues such as worker injection (#5107) and es module output (#2910).

Are there any points in the code the reviewer needs to double check?

  • Karma runner issues:
    • Manual multi-entry for tests is not ideal and there could be issues with unit test watching.
    • rollup pre-processor outputs temp files and if not given a file name and dir can overwrite the input file(s)

Resolves issues:

@tjenkinson
Copy link
Member

This is awesome. Will have a proper look tomorrow

@robwalch
Copy link
Collaborator Author

robwalch commented Mar 16, 2023

@cloudflare-pages
Copy link

cloudflare-pages bot commented Mar 17, 2023

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0097653
Status: ✅  Deploy successful!
Preview URL: https://aeee2168.hls-js-e5a.pages.dev
Branch Preview URL: https://task-rollup-esm-and-worker.hls-js-e5a.pages.dev

View logs

Copy link
Member

@tjenkinson tjenkinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope you don't mind that I pushed a few commits? Look ok?

This looks great though I prefer rollup a lot more than webpack

Will look into getting the es-check bit passing now

package.json Outdated
"files": [
"demo/**/*",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to include the demo in the package? Not sure if it's useful?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed we're also including the demo build in dist/ in the package. If we don't do this, we probably shouldn't do that either

package.json Show resolved Hide resolved
import transmuxerWorker from './transmuxer-worker';

if (hasUMDWorker() && typeof __IN_WORKER__ !== 'undefined' && __IN_WORKER__) {
transmuxerWorker(self);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made some changes in here. Still look ok?

Previously this was assigned to a variable that was unused, and hasUMDWorker was checking if transmuxerWorker was defined, and I think it always would be?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could take out hasUMDWorker() from the check above. It's really only needed in transmuxer-interface for injection.

@@ -1,3 +1,45 @@
import 'promise-polyfill/src/polyfill';
const testsContext = require.context('./unit', true);
testsContext.keys().forEach(testsContext);
import './unit/hls';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to dynamically generate this file with a plugin. Will probably look into that but this looks good for now

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@itsjamie
Copy link
Collaborator

The output from the esm build doesn't look like I would expect.

It still is wrapped in a commonjs output tree.

I would expect to see export keyword used. Right now, a user will still need to use something that converts the commonjs export into valid ES module format.

Switching to rollup, and the change from webpack definitely resolves a lot of issues, and I don't think this should block that.

But I'm not sure this resolves #2910 as is right now.

@tjenkinson
Copy link
Member

The output from the esm build doesn't look like I would expect.

It still is wrapped in a commonjs output tree.

I this may be something I broke, checking

@tjenkinson
Copy link
Member

@itsjamie yep I broke it 🤦

Look better now?

@tjenkinson
Copy link
Member

rollup pre-processor outputs temp files and if not given a file name and dir can overwrite the input file(s)

This might still be a problem, and another one I made worse with my commits. Will check

@itsjamie
Copy link
Collaborator

The ESM build looks like I expect!

The implementation of injectWorker and hasUMDWorker and the code in the transmuxer means that an ESM user has no mechanism to actually use HLS.js with a Worker. I think the comment that #2910 isn't closed is still true. However, we're so much closer and it solves a plethora of problems with the other various bundlers that couldn't handle the webpack module code.

💯

@robwalch
Copy link
Collaborator Author

The implementation of injectWorker and hasUMDWorker and the code in the transmuxer means that an ESM user has no mechanism to actually use HLS.js with a Worker. I think the comment that #2910 isn't closed is still true. However, we're so much closer and it solves a plethora of problems with the other various bundlers that couldn't handle the webpack module code.

It would help if we had a page that demoed the ESM output. Do we expect developers to use the esm module at runtime or to import and bundle themselves? both?

I'd like to get it to where hasUMDWorker() is only used in UMD builds. For an ESM build if we can detect the context (window vs worker) the library running in a worker should always kick off transmuxer-worker. In the main event loop we would want either has an iife that could be used with injectWorker or an option to specify the URL of the library for loading in a worker.

@gkatsev
Copy link
Member

gkatsev commented Mar 17, 2023

It would help if we had a page that demoed the ESM output. Do we expect developers to use the esm module at runtime or to import and bundle themselves? both?

I think it's reasonable for this PR to only target bundle users rather than native ESM.

@gkatsev
Copy link
Member

gkatsev commented Mar 17, 2023

Did a quick filesize check and seems to have improved slightly:

In master

Filename Filesize Gzipped
hls.js 1.1M 246K
hls.min.js 396K 112K

In this PR

Filename Filesize Gzipped
hls.js 970K 218K
hls.min.js 358K 106K

Copy link
Member

@gkatsev gkatsev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing it out locally, and when loading in the new esm build, it seems to work fine in a pure-client-side app, but in a nextjs app it fails to build with an error about self not being available as part of self.WebKitDataCue || self.VTTCue || self.TextTrackCue. I'm still investigating whether it's an hls.js issue or an us issue, but thought I'd post here in the meantime as well.

package.json Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
@robwalch robwalch force-pushed the task/rollup-esm-and-worker branch 2 times, most recently from 915594a to 9eb09ee Compare March 17, 2023 20:35
@robwalch
Copy link
Collaborator Author

rebased against latest

@tjenkinson
Copy link
Member

It's blatted the commits I added. I'll bring them back on another branch

@tjenkinson
Copy link
Member

Brought them back here #5309

@tjenkinson
Copy link
Member

in a nextjs app it fails to build with an error about self not being available as part of self.WebKitDataCue || self.VTTCue || self.TextTrackCue.

8b84d44 should fix that

@robwalch
Copy link
Collaborator Author

We replaced all reference to window with self at some point to prevent issues in the worker context. Is there another alternative that would work in @gkatsev's test case with nextjs? (We've also had issues where self is undefined or overwritten. Not sure if the rollup out formats can do something with global/globalThis/this or something like import global from 'global' which I've seen in rollup repo)

@gkatsev
Copy link
Member

gkatsev commented Mar 17, 2023

Can confirm that 8b84d44 fixes it.

@robwalch
Copy link
Collaborator Author

robwalch commented Mar 17, 2023

Just so I understand, this is when HLS.js is run in nodejs, presumably as part of unit tests?

Could we add a build step that tests this?

@robwalch
Copy link
Collaborator Author

Looking for approval to merge and feedback on 39682b6:

Add "workerPath": "../dist/hls.worker.js" to PR preview.

Did some in browser testing of hls.mjs and looks OK to me. If ESM usage, demo, and testing are important to you please contribute the changes you would like to see or need.

@tjenkinson
Copy link
Member

LGTM!

Just made a couple more tweaks in #5340

@tjenkinson
Copy link
Member

Actually the cloudflare pages demo isn't working?

https://1f937422.hls-js-4zn.pages.dev/demo/

@tjenkinson
Copy link
Member

The worker was not being included in the bundle. I fixed it in #5340

...basePlugins,
replace(buildConstants(type)),
...(!shouldBundleWorker(format)
? [alias({ entries: { './transmuxer-worker': '../empty.js' } })]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tjenkinson,

Is it worth removing this from the esm build? Is there a way we could leave this to tree-shaking?

Would anyone want to set IN_WORKER and HLS_WORKER_BUNDLE themselves with the esm output?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we’d need to export the worker function and then import that function in inject-worker, and then make sure it’s referenced inside an if statement in a way that would cause rollup to not tree shake it away, which is a bit messy

Also not sure what the benefit of it being in there would be, as it would never actually run?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not sure what the benefit of it being in there would be, as it would never actually run?

I was thinking someone could use the module to produce a single output that could be used in both contexts as this project does. That's more complicated than it needs to be however.

tjenkinson
tjenkinson previously approved these changes Mar 27, 2023
robwalch and others added 18 commits March 27, 2023 09:51
Add an es module target (#2910)
UMD build worker injection (#5107)
Add ES5 syntax check for UMD builds (#5301, #5288)
remove unused `workerInstance` variable

refactor rollup config

deduped some of the config and configured rollup to bail on any warning

Also renamed the command line arg to `configType` as rollup reserved `config*` for custom configs, and won't throw a warning that an unknown property was passed with that

downgrade rollup config to cjs and split into 2 files

so we can share the config with karma

use same rollup config definition for tests and actual build

bring the dev script back

do not use `const` in `umdBanner`

leave test streams file as commonjs but allow it to be imported
which happens in nodejs. The check that makes sure the dist file can be required in node and not throw was failing because of this.

Probably only an issue now due to how rollup hoists things
Disable sourcemap in tests
Optimize babel settings
Rename __HLS_WORKER_BUNDLE__ worker iffe wrapper and remove __HLS_UMD_WORKER__
Don't null config on destroy as it violates public API type defintion
@robwalch robwalch merged commit 8e6efb1 into master Mar 27, 2023
15 of 16 checks passed
@robwalch robwalch deleted the task/rollup-esm-and-worker branch March 27, 2023 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants