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

Feature/multi build #4659

Open
wants to merge 13 commits into
base: development
Choose a base branch
from
Open

Feature/multi build #4659

wants to merge 13 commits into from

Conversation

dsilhavy
Copy link
Collaborator

@dsilhavy dsilhavy commented Jan 8, 2025

This PR addresses #4622.

Description

As discussed in #4617 and #4619 developers have implemented different ways to include dash.js in their application. This PR applies changes to the Webpack configuration and the build process of dash.js to create two different bundles:

A legacy bundle setting ie: '11' as the target for Babel and a modern bundle that uses a .browserslistrc file with target set to defaults. defaults is a shortcut for is a shortcut for > 0.5%, last 2 versions, Firefox ESR, not dead.. For both builds, we create a UMD and a ESM version.

This PR contains multiple commits but the relevant one is this one: 15a2bf1. It includes:

  • Adds a .browserlistrc file to define the target browsers for the build
  • Moves all Webpack related configuration files to the build/webpack folder including subfolders for common configuration of the legacy and modern builds.
  • Most of the code that is shared between the builds can be found in the common folder to avoid code duplication
  • The final output files are now placed in subfolders within the dist folder. It contains a legacy folder and a modern folder with esm and umd subfolders for both.
  • In webpack.legacy.base.cjs the '@babel/preset-env target is set explicitly to ie:11. For unknown reasons, ignoreBrowserslistConfig was not working for me.
  • The package.json was adjusted to use the right files in exports. Moreover, npm run build now creates both the legacy and the modern build files. There are separate npm scripts to build only the legacy or the modern files.

The other commits in this PR adjust the path to the dist files accordingly and remove outdated samples.

Open Questions

I am looking for any feedback people have on these changes. For instance:

Open Todos

  • Adjust the Github action (CI/CD) to run the right build command

@dsilhavy dsilhavy added this to the 5.0.0 milestone Jan 8, 2025
@story75
Copy link

story75 commented Jan 8, 2025

Hi to chime in,

We are currently using dash.js almost exclusively on legacy hardware with targets down to Chrome 47 (roughly Tizen 3 (2017), WebOS 4), which is our lowest target, and a Chrome 63 breakpoint, which is roughly Tizen 5 (2020), WebOS 5.

We're currently in the process of optimizing our bundle outputs to approximate the targets:

  • Chrome 47
  • Chrome 63
  • Chrome 108

The reason for this is that most TVs or STBs target either Chromium or WebKit and from our experience in the German market these targets have a pretty good compatibility. We noticed that more and more new TVs are being used, so we decided to add Chrome 108 as our modern target, which fits well with our use of TVs and evergreen browsers.

In my experience, I prefer packages which provide the most modern npm distributions in ESM without corejs polyfills, since we have a dedicated pipeline for our transpilation needs anyway. We use esbuild + swc + corejs to build the bundles we need.

One pain point we currently have with dash.js v4, which will be fixed in v5, is the lack of an ESM bundle. For now, we need to patch sideEffects: false in dash.js because we want to remove dash.js from the final output via tree-shaking if the target does not need to play DASH content (if the content is progressive or HLS).

We only ever need a browser bundle for libraries that try to support runtimes other than the browser, which may introduce nodejs libs that need to be replaced, but that shouldn't be the case for dash.js anyway.

I hope this feedback helps a bit, and for what it's worth, I would welcome a modern esm build of dash.js.

EDIT:
A few notes on the polyfills, as I think this is important:
We block some core js polyfills, meaning we actively remove them from the bundle due to various issues (bundle bloat, undefined behavior during playout, or just broken bundles on some set top boxes).

For some features, we write our own small polyfills for common functions that we replace during the build process. Doing this on a modern bundle is usually much easier than doing it on already transpiled and polyfilled code.

For example, there are cases where some tools do not like for let of loops, which can either be written by hand or introduced by transpilers (esbuild, typescript, or similar), which then get transpiled incorrectly when targeting ES5 and then need to be changed either before or after in the bundle generation process.

Copy link
Contributor

@littlespex littlespex left a comment

Choose a reason for hiding this comment

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

I would love to hear other opinions, but I think this could just be two bundles/folders:

  • dist/umd: The ES5/UMD bundle that can be loaded via <script src="" /> on older platforms (TVs mostly).
  • dist/esm: The ESM bundle for modern browsers using <script type="module" /> and apps that use build tools to compile their JS.

Comment on lines 42 to 54
const esmConfig = merge(legacyConfig, {
experiments: {
outputModule: true
},
output: {
path: path.resolve(__dirname, '../../../dist/legacy/esm'),
publicPath: '/dist/legacy/esm/',
library: {
type: 'module',
},
libraryExport: 'default',
},
});
Copy link
Contributor

Choose a reason for hiding this comment

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

If legacy is essentially an ES5 build, how can there be an ESM version?

Comment on lines +29 to +37
const umdConfig = merge(modernConfig, {
output: {
path: path.resolve(__dirname, '../../../dist/modern/umd'),
publicPath: '/dist/modern/umd/',
library: 'dashjs',
libraryTarget: 'umd',
libraryExport: 'default'
},
});
Copy link
Contributor

Choose a reason for hiding this comment

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

The legacy version is already a UMD bundle. What is the advantage of having a modern non-ESM variant? I would think that anyone needing to include the library via script/src would use legacy+umd and anyone in a modern browser, or using a build system, would use modern+esm.

- integrate dash.js bundle in sample app output bundle
@bbert
Copy link
Contributor

bbert commented Jan 10, 2025

For information, the sample application network-interceptor provides an example of typescript application that can be used to validate importing of types and the modern+esm dash.js bundle.

@dsilhavy
Copy link
Collaborator Author

Hi all,
thank you for the feedback and the contributions. Based on your comments, I did the following changes:

  • Removed the ESM bundle from the legacy build
  • Removed the core.js polyfills from the modern builds
  • Fixed the npm run build script to not execute prebuild twice
  • Fixed the Github actions

That leaves us with the following builds:

  • UMD legacy: A UMD build targeting legacy platforms by specifying the babel target ie: '11'. In addition, core.js polyfills are enabled.
  • ESM modern: An ESM build using .browserslistrc as target, with target set to defaults. No core.js polyfills are enabled.
  • UMD modern: A UMD build targeting modern platforms using .browserslistrc as target, with target set to defaults. No core.js polyfills are enabled.

The UMD modern build is up for discussion. From @littlespex comment above, I conclude that this is not really needed. However, you also mentioned that in many cases you add the polyfills yourself. Does it make sense to provide this additional UMD build without any polyfills?

Please also let me know if you see any other issues with these changes.

@stschr
Copy link
Contributor

stschr commented Jan 13, 2025

No input from our side; all sounds reasonably here.
Well done!

@eirikbjornr
Copy link
Contributor

We'll likely continue pulling Dash.js' source files directly and building/bundling them ourself – just to remove a step in the chain of code transformations up to the build of our TV apps platform. We take a very similar approach to @story75 and share the same concerns as I describe in our previous discussion: #4617 (comment)

Our main concern is the polyfills needed to run Dash.js don't change drastically. Our tools will notify us if an unsupported polyfill is introduced so we're not flying blind here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

6 participants