In this series of blog posts, we will focus on dash.js. We will explain how certain features are implemented and how they can be used within applications. Today, we are taking a closer look at the underlying development ecosystem of the dash.js player. Our goal is to understand how the player is built, how code integrity is achieved, how the test coverage works and how a certain level of continuous integration is guaranteed.
Grunt – the taskrunner behind dash.js
grunt.registerTask('default', ['dist', 'test']); grunt.registerTask('dist', ['clean', 'jshint', 'jscs', 'browserify:mediaplayer', 'browserify:protection', 'browserify:reporting', 'browserify:mss', 'browserify:all', 'babel:es5', 'minimize', 'copy:dist']); grunt.registerTask('minimize', ['exorcise', 'githash', 'uglify']); grunt.registerTask('test', ['mocha_istanbul:test']); grunt.registerTask('watch', ['browserify:watch']); grunt.registerTask('watch-dev', ['browserify:watch_dev']); grunt.registerTask('release', ['default', 'jsdoc']); grunt.registerTask('debug', ['clean', 'browserify:all', 'exorcise:all', 'copy:dist']); grunt.registerTask('lint', ['jshint', 'jscs']); grunt.registerTask('prepublish', ['githooks', 'dist']); grunt.registerTask('dev', ['browserSync', 'watch-dev']); grunt.registerTask('deploy', ['string-replace', 'ftp_push']);
The Grunt task model
First thing we can see in the task definition is that a task can reference other tasks. For instance, the “default” task references the “dist” and the “test” tasks. If we visualize the task dependencies, we get a good understanding of how the overall structure of the tasks looks like (click to enlarge):
On the top level of the task model tree, we can see two tasks: “Release” and “Deploy”.
The Grunt Release Task
Testing the release
Creating the release
The process for creating the minified and bundled release (“Dist” task) is much more comprehensive than the “Test” task and includes several different tasks. First of all, the required temporary folders and final output folders are cleared if they already exist, or created if not yet existent. This step is done within the “Clean” task.
Afterwards, the code linting is performed. Two different libraries, “JSHint” and “JSCS”, check the code for potential programmatic and stylistic errors.
In the “Browserify” task, the Node.js-based module dependencies of the dash.js player are compiled to a browser-compliant version. Browserify essentially allows us to use the resources of the NPM ecosystem on the client side.
The “Babel” task converts the ES2015 parts of the code into ES5-compatible code. That way, the advantages of the latest ECMAScript standard can be used within the code without excluding older browsers or platforms.
In the last step of the “Dist” task chain, the target files are copied to the dist folder, from which we can grab and include in our application (“Copy” task).
The Grunt Deploy task
Ideally, not only do we want to create a release bundle of the dash.js player, but we also want to deploy the new files to a server. This is exactly what happens in the “Deploy” task, which consists of two subtasks: “String-Replace” and “FTP_Push”. In the “String-Replace” task, the latest version number of the dash.js player is added to the index.html of the sample page, while the “FTP_Push” task uploads the bundled and minified files (as well as the samples folder) to the release server.
Additional Grunt tasks
In addition to the already introduced tasks for creating a release and deployment on the server, additional helper tasks also exist and are mainly used for development purposes. The “Watch” and “Watch-Dev” tasks watch the code for changes and automatically create a new code bundle. A sample output of the watch tasks is shown below. In this case, we updated the RepresentationController , which triggers a rebuild of the dash.all.debug.js bundle.
Running "browserify:watch" (browserify) task >> Bundle build/temp/dash.mss.debug.js created. Watchifying... >> Bundle build/temp/dash.all.debug.js created. Watchifying... >> src/dash/controllers/RepresentationController.js changed, updating bundle. >> Bundle build/temp/dash.all.debug.js created. Watchifying...
In this blog post, we examined the development ecosystem of the dash.js player. It is based on Grunt as a task runner, and consists of various steps for testing the code, guaranteeing code consistency, creating bundled and minified releases of the player, and deploying the player to a server. If you are using dash.js in your application or are planning to contribute to the player code in the future, the Gruntfile.js task definition file is definitely worth taking a look. If you have any question regarding our DASH activities or dash.js in particular, feel free to check out our website.