diff --git a/.babelrc b/.babelrc
index 9a8be8c392..4104471e0a 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,4 +1,8 @@
{
- "presets": [ "es3", ["es2015", {"loose": true}] ],
- "plugins": ["inline-json"]
+ "presets": [
+ "es3",
+ ["es2015", {
+ "loose": true
+ }]
+ ]
}
diff --git a/.travis.yml b/.travis.yml
index be3db58d1a..fddf1c1368 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,10 @@ before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
+after_failure:
+ - npm ls --depth=1
+after_success:
+ - npm run assets
notifications:
irc:
channels:
diff --git a/build/assets.js b/build/assets.js
new file mode 100644
index 0000000000..77f3653367
--- /dev/null
+++ b/build/assets.js
@@ -0,0 +1,65 @@
+const fs = require('fs');
+const zlib = require('zlib');
+const Promise = require('bluebird');
+const klawSync = require('klaw-sync');
+const filesize = require('filesize');
+const Table = require('cli-table');
+
+const files = klawSync('dist/', {
+ ignore: ['examples', 'lang', 'font', 'ie8', '*.zip', '*.gz'],
+ nodir: true
+});
+
+Promise.all(files.map(gzipAndStat))
+.then(mapFiles)
+.then(function(files) {
+ logTable(files);
+
+ return files;
+})
+.then(cleanup)
+.catch(function(err) {
+ console.error(err.stack);
+});
+
+function cleanup(files) {
+ files.forEach(function(file) {
+ fs.unlinkSync('dist/' + file[0] + '.gz');
+ });
+}
+
+function mapFiles(files) {
+ return files.map(function(file) {
+ const path = file[0].path;
+ const fileStat = file[0].stats;
+ const gzStat = file[1];
+ return [file[0].path.split('dist/')[1], filesize(fileStat.size), filesize(gzStat.size)];
+ });
+}
+
+function gzipAndStat(file) {
+ return new Promise(function(resolve, reject) {
+ const readStream = fs.createReadStream(file.path);
+ const writeStream = fs.createWriteStream(file.path + '.gz');
+ const gzip = zlib.createGzip();
+ readStream.pipe(gzip).pipe(writeStream).on('close', function() {
+ const gzStat = fs.statSync(file.path + '.gz');
+
+ resolve([file, gzStat]);
+ })
+ .on('error', reject);
+ });
+}
+
+function logTable(files) {
+ const table = new Table({
+ head: ['filename', 'size', 'gzipped'],
+ colAligns: ['left', 'right', 'right'],
+ style: {
+ border: ['white']
+ }
+ });
+
+ table.push.apply(table, files);
+ console.log(table.toString());
+}
diff --git a/build/grunt.js b/build/grunt.js
index cbb37c494a..4be8444e5c 100644
--- a/build/grunt.js
+++ b/build/grunt.js
@@ -408,8 +408,7 @@ module.exports = function(grunt) {
],
dev: [
'shell:babel',
- 'browserify:watch',
- 'browserify:watchnovtt',
+ 'shell:rollupwatch',
'browserify:tests',
'watch:skin',
'watch:lang',
@@ -448,6 +447,24 @@ module.exports = function(grunt) {
}
},
shell: {
+ rollup: {
+ command: 'npm run rollup',
+ options: {
+ preferLocal: true
+ }
+ },
+ rollupall: {
+ command: 'npm run rollup -- --no-progress && npm run rollup-minify -- --no-progress',
+ options: {
+ preferLocal: true
+ }
+ },
+ rollupwatch: {
+ command: 'npm run rollup-dev',
+ optoins: {
+ preferLocal: true
+ }
+ },
babel: {
command: 'npm run babel -- --watch',
options: {
@@ -509,12 +526,7 @@ module.exports = function(grunt) {
'shell:lint',
'clean:build',
- 'babel:es5',
- 'browserify:build',
- 'browserify:buildnovtt',
- 'usebanner:novtt',
- 'usebanner:vtt',
- 'uglify',
+ 'shell:rollupall',
'skin',
'version:css',
diff --git a/build/rollup.js b/build/rollup.js
new file mode 100644
index 0000000000..883b24818e
--- /dev/null
+++ b/build/rollup.js
@@ -0,0 +1,205 @@
+import { rollup } from 'rollup';
+import duration from 'humanize-duration';
+import watch from 'rollup-watch';
+import babel from 'rollup-plugin-babel';
+import resolve from 'rollup-plugin-node-resolve';
+import commonjs from 'rollup-plugin-commonjs';
+import json from 'rollup-plugin-json';
+import filesize from 'rollup-plugin-filesize';
+import progress from 'rollup-plugin-progress';
+import ignore from 'rollup-plugin-ignore';
+import uglify from 'rollup-plugin-uglify';
+import minimist from 'minimist';
+import _ from 'lodash';
+import pkg from '../package.json';
+import fs from 'fs';
+
+const args = minimist(process.argv.slice(2), {
+ boolean: ['watch', 'minify', 'progress'],
+ default: {
+ progress: true
+ },
+ alias: {
+ w: 'watch',
+ m: 'minify',
+ p: 'progress'
+ }
+});
+
+const compiledLicense = _.template(fs.readFileSync('./build/license-header.txt', 'utf8'));
+const bannerData = _.pick(pkg, ['version', 'copyright']);
+
+const primedResolve = resolve({
+ jsnext: true,
+ main: true,
+ browser: true
+});
+const primedCjs = commonjs({
+ sourceMap: false
+});
+const primedBabel = babel({
+ babelrc: false,
+ exclude: 'node_modules/**',
+ presets: [
+ 'es3',
+ ['es2015', {
+ loose: true,
+ modules: false
+ }]
+ ],
+ plugins: ['external-helpers']
+});
+
+const es = {
+ options: {
+ entry: 'src/js/video.js',
+ plugins: [
+ json(),
+ primedBabel,
+ args.progress ? progress() : {},
+ filesize()
+ ],
+ onwarn(warning) {
+ if (warning.code === 'UNUSED_EXTERNAL_IMPORT' ||
+ warning.code === 'UNRESOLVED_IMPORT') {
+ return;
+ }
+
+ // eslint-disable-next-line no-console
+ console.warn(warning.message);
+ },
+ legacy: true
+ },
+ banner: compiledLicense(Object.assign({includesVtt: true}, bannerData)),
+ format: 'es',
+ dest: 'dist/video.es.js'
+};
+
+const cjs = Object.assign({}, es, {
+ format: 'cjs',
+ dest: 'dist/video.cjs.js'
+});
+
+const umd = {
+ options: {
+ entry: 'src/js/video.js',
+ plugins: [
+ primedResolve,
+ json(),
+ primedCjs,
+ primedBabel,
+ args.progress ? progress() : {},
+ filesize()
+ ],
+ legacy: true
+ },
+ banner: compiledLicense(Object.assign({includesVtt: true}, bannerData)),
+ format: 'umd',
+ dest: 'dist/video.js'
+};
+
+const minifiedUmd = Object.assign({}, _.cloneDeep(umd), {
+ dest: 'dist/video.min.js'
+});
+
+minifiedUmd.options.plugins.splice(4, 0, uglify({
+ preserveComments: 'some',
+ screwIE8: false,
+ mangle: true,
+ compress: {
+ /* eslint-disable camelcase */
+ sequences: true,
+ dead_code: true,
+ conditionals: true,
+ booleans: true,
+ unused: true,
+ if_return: true,
+ join_vars: true,
+ drop_console: true
+ /* eslint-enable camelcase */
+ }
+}));
+
+const novttUmd = Object.assign({}, _.cloneDeep(umd), {
+ banner: compiledLicense(Object.assign({includesVtt: false}, bannerData)),
+ dest: 'dist/alt/video.novtt.js'
+});
+
+novttUmd.options.plugins.unshift(ignore(['videojs-vtt.js']));
+
+const minifiedNovttUmd = Object.assign({}, _.cloneDeep(minifiedUmd), {
+ banner: compiledLicense(Object.assign({includesVtt: false}, bannerData)),
+ dest: 'dist/alt/video.novtt.min.js'
+});
+
+minifiedNovttUmd.options.plugins.unshift(ignore(['videojs-vtt.js']));
+
+function runRollup({options, format, dest, banner}) {
+ rollup(options)
+ .then(function(bundle) {
+ bundle.write({
+ format,
+ dest,
+ banner,
+ moduleName: 'videojs',
+ sourceMap: false
+ });
+ }, function(err) {
+ // eslint-disable-next-line no-console
+ console.error(err);
+ });
+}
+
+if (!args.watch) {
+ if (args.minify) {
+ runRollup(minifiedUmd);
+ runRollup(minifiedNovttUmd);
+ } else {
+ runRollup(es);
+ runRollup(cjs);
+ runRollup(umd);
+ runRollup(novttUmd);
+ }
+} else {
+ const props = ['format', 'dest', 'banner'];
+ const watchers = [
+ ['es', watch({rollup},
+ Object.assign({},
+ es.options,
+ _.pick(es, props)))],
+ ['cjs', watch({rollup},
+ Object.assign({},
+ cjs.options,
+ _.pick(cjs, props)))],
+ ['umd', watch({rollup},
+ Object.assign({moduleName: 'videojs'},
+ umd.options,
+ _.pick(umd, props)))],
+ ['novtt', watch({rollup},
+ Object.assign({moduleName: 'videojs'},
+ novttUmd.options,
+ _.pick(novttUmd, props)))]
+ ];
+
+ watchers.forEach(function([type, watcher]) {
+ watcher.on('event', (details) => {
+ if (details.code === 'BUILD_START') {
+ // eslint-disable-next-line no-console
+ console.log(`Bundling ${type}...`);
+ return;
+ }
+
+ if (details.code === 'BUILD_END') {
+ // eslint-disable-next-line no-console
+ console.log(`Bundled ${type} in %s`, duration(details.duration));
+ return;
+ }
+
+ if (details.code === 'ERROR') {
+ // eslint-disable-next-line no-console
+ console.error(details.error.toString());
+ return;
+ }
+ });
+ });
+}
diff --git a/package.json b/package.json
index 28b45a1fa5..8836597eed 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,8 @@
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "6.1.0",
- "main": "./es5/video.js",
+ "main": "./dist/video.cjs.js",
+ "module": "./dist/video.es.js",
"style": "./dist/video-js.css",
"copyright": "Copyright Brightcove, Inc. ",
"license": "Apache-2.0",
@@ -18,6 +19,11 @@
"scripts": {
"changelog": "conventional-changelog -p videojs -i CHANGELOG.md -s",
"build": "grunt dist",
+ "rollup-all": "npm run rollup && npm run rollup-minify",
+ "rollup": "babel-node build/rollup.js",
+ "rollup-minify": "babel-node build/rollup.js --minify",
+ "rollup-dev": "babel-node build/rollup.js --watch",
+ "assets": "node build/assets.js",
"change": "grunt chg-add",
"clean": "grunt clean",
"grunt": "grunt",
@@ -47,28 +53,31 @@
"tsml": "1.0.1",
"videojs-font": "2.0.0",
"videojs-ie8": "1.1.2",
- "videojs-vtt.js": "0.12.3",
+ "videojs-vtt.js": "0.12.4",
"xhr": "2.4.0"
},
"devDependencies": {
"aliasify": "^2.1.0",
"babel-cli": "^6.11.4",
- "babel-plugin-inline-json": "^1.1.1",
+ "babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-preset-es2015": "^6.14.0",
"babel-preset-es3": "^1.0.1",
"babel-register": "^6.9.0",
"babelify": "^7.3.0",
"blanket": "^1.1.6",
+ "bluebird": "^3.5.0",
"browserify-derequire": "^0.9.4",
"browserify-istanbul": "^2.0.0",
"browserify-versionify": "^1.0.4",
"bundle-collapser": "^1.2.1",
"chg": "^0.3.2",
+ "cli-table": "^0.3.1",
"conventional-changelog-cli": "^1.2.0",
"conventional-changelog-videojs": "^3.0.0",
"es5-shim": "^4.1.3",
"es6-shim": "^0.35.1",
+ "filesize": "^3.5.6",
"grunt": "^0.4.5",
"grunt-accessibility": "^5.0.0",
"grunt-babel": "^6.0.0",
@@ -92,6 +101,7 @@
"grunt-version": "~1.1.1",
"grunt-videojs-languages": "0.0.4",
"grunt-zip": "0.17.1",
+ "humanize-duration": "^3.10.0",
"husky": "^0.13.1",
"in-publish": "^2.0.0",
"istanbul": "^0.4.5",
@@ -108,9 +118,11 @@
"karma-qunit": "^1.2.0",
"karma-safari-launcher": "^1.0.0",
"karma-sinon": "^1.0.5",
+ "klaw-sync": "^1.1.2",
"load-grunt-tasks": "^3.1.0",
"lodash": "^4.16.6",
"markdown-table": "^1.0.0",
+ "minimist": "^1.2.0",
"npm-run": "^4.1.0",
"npm-run-all": "^4.0.2",
"proxyquireify": "^3.0.0",
@@ -120,6 +132,16 @@
"remark-toc": "^4.0.0",
"remark-validate-links": "^6.0.0",
"replace": "^0.3.0",
+ "rollup": "^0.41.6",
+ "rollup-plugin-babel": "^2.7.1",
+ "rollup-plugin-commonjs": "^8.0.2",
+ "rollup-plugin-filesize": "^1.2.1",
+ "rollup-plugin-ignore": "^1.0.3",
+ "rollup-plugin-json": "^2.1.1",
+ "rollup-plugin-node-resolve": "^3.0.0",
+ "rollup-plugin-progress": "^0.2.1",
+ "rollup-plugin-uglify": "^1.0.2",
+ "rollup-watch": "^3.2.2",
"shelljs": "^0.7.5",
"sinon": "^1.16.1",
"time-grunt": "^1.1.1",
@@ -128,13 +150,14 @@
"videojs-doc-generator": "0.0.1",
"videojs-flash": "^2.0.0",
"videojs-standard": "^6.0.1",
- "webpack": "^2.3.0"
+ "webpack": "^1.15.0"
},
"vjsstandard": {
"ignore": [
"**/Gruntfile.js",
"**/es5/**",
"**/build/**",
+ "!build/rollup.js",
"**/dist/**",
"**/docs/**",
"**/lang/**",
diff --git a/sandbox/index.html.example b/sandbox/index.html.example
index 60c20d56f2..289284932c 100644
--- a/sandbox/index.html.example
+++ b/sandbox/index.html.example
@@ -9,7 +9,7 @@
-
+
diff --git a/src/js/player.js b/src/js/player.js
index af8f42fe9a..67c6c01a1c 100644
--- a/src/js/player.js
+++ b/src/js/player.js
@@ -4,6 +4,7 @@
// Subclasses Component
import Component from './component.js';
+import {version} from '../../package.json';
import document from 'global/document';
import window from 'global/window';
import tsml from 'tsml';
@@ -443,7 +444,7 @@ class Player extends Component {
Player.players[this.id_] = this;
// Add a major version class to aid css in plugins
- const majorVersion = require('../../package.json').version.split('.')[0];
+ const majorVersion = version.split('.')[0];
this.addClass(`vjs-v${majorVersion}`);
diff --git a/src/js/tech/tech.js b/src/js/tech/tech.js
index 5a04a8e1c1..c0501af6bb 100644
--- a/src/js/tech/tech.js
+++ b/src/js/tech/tech.js
@@ -14,6 +14,7 @@ import document from 'global/document';
import {isPlain} from '../utils/obj';
import * as TRACK_TYPES from '../tracks/track-types';
import toTitleCase from '../utils/to-title-case';
+import vtt from 'videojs-vtt.js';
/**
* An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
@@ -516,7 +517,6 @@ class Tech extends Component {
// signals that the Tech is ready at which point Tech.el_ is part of the DOM
// before inserting the WebVTT script
if (document.body.contains(this.el())) {
- const vtt = require('videojs-vtt.js');
// load via require if available and vtt.js script location was not passed in
// as an option. novtt builds will turn the above require call into an empty object
@@ -530,7 +530,7 @@ class Tech extends Component {
// passed in
const script = document.createElement('script');
- script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.12.3/vtt.min.js';
+ script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.12.4/vtt.min.js';
script.onload = () => {
/**
* Fired when vtt.js is loaded.
diff --git a/src/js/video.js b/src/js/video.js
index beafff30e0..5507895a6f 100644
--- a/src/js/video.js
+++ b/src/js/video.js
@@ -2,6 +2,7 @@
* @file video.js
* @module videojs
*/
+import {version} from '../../package.json';
import window from 'global/window';
import document from 'global/document';
import * as setup from './setup';
@@ -225,7 +226,7 @@ setup.autoSetupTimeout(1, videojs);
*
* @type {string}
*/
-videojs.VERSION = require('../../package.json').version;
+videojs.VERSION = version;
/**
* The global options object. These are the settings that take effect
@@ -722,7 +723,5 @@ videojs.dom = Dom;
*/
videojs.url = Url;
-// We use Node-style module.exports here instead of ES6 because it is more
-// compatible with different module systems.
-module.exports = videojs;
+export default videojs;
diff --git a/test/karma.conf.js b/test/karma.conf.js
index 3422d2761b..161f974703 100644
--- a/test/karma.conf.js
+++ b/test/karma.conf.js
@@ -10,7 +10,7 @@ module.exports = function(config) {
// Compling tests here
files: [
'../build/temp/video-js.css',
- '../build/temp/ie8/videojs-ie8.min.js',
+ '../build/temp/ie8/videojs-ie8.js',
'../test/globals-shim.js',
'../test/unit/**/*.js',
'../build/temp/browserify.js',