Support serving ES6 JS to clients (#596)

* Support serving ES6 JS to clients

* Make es6 default dir and es5 a special dir

* Fix package building

* Fix build_frontend script
This commit is contained in:
Andrey 2017-11-10 19:05:37 +02:00 committed by Paulus Schoutsen
parent 86128d54b4
commit 583abedd34
19 changed files with 295 additions and 121 deletions

3
.gitignore vendored
View File

@ -1,10 +1,13 @@
build/*
build-temp/*
build-es5/*
build-translations/*
node_modules/*
bower_components/*
npm-debug.log
.DS_Store
hass_frontend/*
hass_frontend_es5/*
# Python stuff
*.py[cod]

View File

@ -1,4 +1,5 @@
include README.md
include LICENSE.md
graft hass_frontend
graft hass_frontend_es5
recursive-exclude * *.py[co]

View File

@ -1,27 +1,33 @@
const gulpif = require('gulp-if');
const uglifyjs = require('uglify-js');
const uglifyes = require('uglify-es');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
const composer = require('gulp-uglify/composer');
const { gulp: cssSlam } = require('css-slam');
const htmlMinifier = require('gulp-html-minifier');
const { HtmlSplitter } = require('polymer-build');
const pump = require('pump');
module.exports.minifyStream = function (stream) {
module.exports.minifyStream = function (stream, es6) {
const sourcesHtmlSplitter = new HtmlSplitter();
return stream
.pipe(sourcesHtmlSplitter.split())
.pipe(gulpif(/[^app]\.js$/, babel({
return pump([
stream,
sourcesHtmlSplitter.split(),
gulpif(!es6, gulpif(/[^app]\.js$/, babel({
sourceType: 'script',
presets: [
['es2015', { modules: false }]
]
})))
.pipe(gulpif(/\.js$/, uglify({ sourceMap: false })))
.pipe(gulpif(/\.css$/, cssSlam()))
.pipe(gulpif(/\.html$/, cssSlam()))
.pipe(gulpif(/\.html$/, htmlMinifier({
}))),
gulpif(/\.js$/, composer(es6 ? uglifyes : uglifyjs, console)({ sourceMap: false })),
gulpif(/\.css$/, cssSlam()),
gulpif(/\.html$/, cssSlam()),
gulpif(/\.html$/, htmlMinifier({
collapseWhitespace: true,
removeComments: true
})))
.pipe(sourcesHtmlSplitter.rejoin());
})),
sourcesHtmlSplitter.rejoin(),
], (error) => {
if (error) console.log(error);
});
};

View File

@ -0,0 +1,8 @@
console.warn('Service worker caching disabled in development');
self.addEventListener('install', function(event) {
self.skipWaiting();
});
self.addEventListener('activate', function(event) {
self.clients.claim();
});

View File

@ -30,7 +30,7 @@ function renamePanel(path) {
}
}
gulp.task('build', ['ru_all', 'build-translations'], () => {
function build(es6) {
const strategy = composeStrategies([
generateShellMergeStrategy(polymerConfig.shell),
stripImportsStrategy([
@ -41,8 +41,8 @@ gulp.task('build', ['ru_all', 'build-translations'], () => {
]);
const project = new PolymerProject(polymerConfig);
return mergeStream(minifyStream(project.sources()),
minifyStream(project.dependencies()))
return mergeStream(minifyStream(project.sources(), es6),
minifyStream(project.dependencies(), es6))
.pipe(project.bundler({
strategy,
strip: true,
@ -54,5 +54,7 @@ gulp.task('build', ['ru_all', 'build-translations'], () => {
}))
.pipe(rename(renamePanel))
.pipe(filter(['**', '!src/entrypoint.html']))
.pipe(gulp.dest('build/'));
});
.pipe(gulp.dest(es6 ? 'build' : 'build-es5'));
}
gulp.task('build_es5', ['ru_all_es5', 'build-translations'], () => build(/* es6= */ false));
gulp.task('build', ['ru_all', 'build-translations'], () => build(/* es6= */ true));

View File

@ -2,5 +2,5 @@ const del = require('del');
const gulp = require('gulp');
gulp.task('clean', () => {
return del(['build', 'build-temp']);
return del(['build-es5', 'build', 'build-temp', 'build-translations']);
});

View File

@ -4,6 +4,7 @@ const runSequence = require('run-sequence');
gulp.task('default', () => {
return runSequence.use(gulp)(
'clean',
'build'
'build_es5',
'build',
);
});

View File

@ -3,41 +3,44 @@ Generate a caching service worker for HA
Will be called as part of build_frontend.
Creates a caching service worker based on the built content of the repo in hass_frontend.
Output service worker to build/service_worker.js
Creates a caching service worker based on the built content of the repo in
{hass_frontend, hass_frontend_es6}.
Output service worker to {build, build-es6}/service_worker.js
TODO:
- Use gulp streams
- Fix minifying the stream
*/
var gulp = require('gulp');
var crypto = require('crypto');
var file = require('gulp-file');
var fs = require('fs');
var path = require('path');
var swPrecache = require('sw-precache');
var uglifyJS = require('uglify-js');
const config = require('../config');
const gulp = require('gulp');
const crypto = require('crypto');
const file = require('gulp-file');
const fs = require('fs');
const path = require('path');
const swPrecache = require('sw-precache');
const DEV = !!JSON.parse(process.env.BUILD_DEV || 'true');
var rootDir = 'hass_frontend';
var panelDir = path.resolve(rootDir, 'panels');
const dynamicUrlToDependencies = {};
var dynamicUrlToDependencies = {};
var staticFingerprinted = [
'frontend.html',
const staticFingerprinted = [
'mdi.html',
'core.js',
'compatibility.js',
'translations/en.json',
];
const staticFingerprintedEs6 = [
'core.js',
'frontend.html',
];
const staticFingerprintedEs5 = [
'compatibility.js',
'core.js',
'frontend.html',
];
// These panels will always be registered inside HA and thus can
// be safely assumed to be able to preload.
var panelsFingerprinted = [
const panelsFingerprinted = [
'dev-event', 'dev-info', 'dev-service', 'dev-state', 'dev-template',
'dev-mqtt', 'kiosk',
];
@ -47,43 +50,51 @@ function md5(filename) {
.update(fs.readFileSync(filename)).digest('hex');
}
gulp.task('gen-service-worker', () => {
var genPromise = null;
function processStatic(fn, rootDir) {
const parts = path.parse(fn);
const base = parts.dir.length > 0 ? parts.dir + '/' + parts.name : parts.name;
const hash = md5(rootDir + '/' + base + parts.ext);
const url = '/static/' + base + '-' + hash + parts.ext;
const fpath = rootDir + '/' + base + parts.ext;
dynamicUrlToDependencies[url] = [fpath];
}
function generateServiceWorker(es6) {
let genPromise = null;
const baseRootDir = 'hass_frontend';
const rootDir = es6 ? baseRootDir : 'hass_frontend_es5';
const panelDir = path.resolve(rootDir, 'panels');
if (DEV) {
var devBase = 'console.warn("Service worker caching disabled in development")';
genPromise = Promise.resolve(devBase);
genPromise = Promise.resolve(
fs.readFileSync(path.resolve(__dirname, '../service-worker-dev.js.tmpl'), 'UTF-8'));
} else {
// Create fingerprinted versions of our dependencies.
staticFingerprinted.forEach(fn => {
var parts = path.parse(fn);
var base = parts.dir.length > 0 ? parts.dir + '/' + parts.name : parts.name;
var hash = md5(rootDir + '/' + base + parts.ext);
var url = '/static/' + base + '-' + hash + parts.ext;
var fpath = rootDir + '/' + base + parts.ext;
(es6 ? staticFingerprintedEs6 : staticFingerprintedEs5).forEach(
fn => processStatic(fn, rootDir));
staticFingerprinted.forEach(fn => processStatic(fn, baseRootDir));
panelsFingerprinted.forEach((panel) => {
const fpath = panelDir + '/ha-panel-' + panel + '.html';
const hash = md5(fpath);
const url = '/frontend/panels/ha-panel-' + panel + '-' + hash + '.html';
dynamicUrlToDependencies[url] = [fpath];
});
panelsFingerprinted.forEach(panel => {
var fpath = panelDir + '/ha-panel-' + panel + '.html';
var hash = md5(fpath);
var url = '/static/panels/ha-panel-' + panel + '-' + hash + '.html';
dynamicUrlToDependencies[url] = [fpath];
});
var options = {
const options = {
navigateFallback: '/',
navigateFallbackWhitelist:
[/^(?:(?!(?:static|api|local|service_worker.js|manifest.json)).)*$/],
dynamicUrlToDependencies: dynamicUrlToDependencies,
staticFileGlobs: [
rootDir + '/icons/favicon.ico',
rootDir + '/icons/favicon-192x192.png',
rootDir + '/webcomponents-lite.min.js',
rootDir + '/fonts/roboto/Roboto-Light.ttf',
rootDir + '/fonts/roboto/Roboto-Medium.ttf',
rootDir + '/fonts/roboto/Roboto-Regular.ttf',
rootDir + '/fonts/roboto/Roboto-Bold.ttf',
rootDir + '/images/card_media_player_bg.png',
baseRootDir + '/icons/favicon.ico',
baseRootDir + '/icons/favicon-192x192.png',
baseRootDir + '/webcomponents-lite.min.js',
baseRootDir + '/fonts/roboto/Roboto-Light.ttf',
baseRootDir + '/fonts/roboto/Roboto-Medium.ttf',
baseRootDir + '/fonts/roboto/Roboto-Regular.ttf',
baseRootDir + '/fonts/roboto/Roboto-Bold.ttf',
baseRootDir + '/images/card_media_player_bg.png',
],
// Rules are proceeded in order and negative per-domain rules are not supported.
runtimeCaching: [
@ -107,7 +118,7 @@ gulp.task('gen-service-worker', () => {
handler: 'fastest',
}
],
stripPrefix: 'hass_frontend',
stripPrefix: baseRootDir,
replacePrefix: 'static',
verbose: true,
// Allow our users to refresh to get latest version.
@ -117,7 +128,7 @@ gulp.task('gen-service-worker', () => {
genPromise = swPrecache.generate(options);
}
var swHass = fs.readFileSync(path.resolve(__dirname, '../service-worker.js.tmpl'), 'UTF-8');
const swHass = fs.readFileSync(path.resolve(__dirname, '../service-worker.js.tmpl'), 'UTF-8');
// Fix this
// if (!DEV) {
@ -125,7 +136,10 @@ gulp.task('gen-service-worker', () => {
// swString => uglifyJS.minify(swString, { fromString: true }).code);
// }
return genPromise.then(swString => swString + '\n' + swHass)
return genPromise.then(swString => swString + '\n' + swHass + '\n' + (es6 ? '//es6' : '//es5'))
.then(swString => file('service_worker.js', swString)
.pipe(gulp.dest(config.build_dir)));
});
.pipe(gulp.dest(es6 ? 'build' : 'build-es5')));
}
gulp.task('gen-service-worker-es5', generateServiceWorker.bind(null, /* es6= */ false));
gulp.task('gen-service-worker', generateServiceWorker.bind(null, /* es6= */ true));

View File

@ -1,4 +1,4 @@
var gulp = require('gulp');
const gulp = require('gulp');
const rename = require('gulp-rename');
const {
@ -21,27 +21,27 @@ const DEPS_TO_STRIP_RECURSIVELY = [
'bower_components/polymer/polymer.html',
];
gulp.task(
'hassio-panel',
async () => {
const toStrip = [...DEPS_TO_STRIP];
async function buildHassioPanel(es6) {
const toStrip = [...DEPS_TO_STRIP];
for (let dep of DEPS_TO_STRIP_RECURSIVELY) {
toStrip.push(dep);
const deps = await findDependencies(polymer_dir, dep);
for (const importUrl of deps) {
toStrip.push(importUrl);
}
for (const dep of DEPS_TO_STRIP_RECURSIVELY) {
toStrip.push(dep);
const deps = await findDependencies(polymer_dir, dep);
for (const importUrl of deps) {
toStrip.push(importUrl);
}
const stream = await bundledStreamFromHTML(
'panels/hassio/hassio-main.html', {
strategy: stripImportsStrategy(toStrip)
}
);
return minifyStream(stream)
.pipe(rename('hassio-main.html'))
.pipe(gulp.dest('build-temp/'));
}
);
const stream = await bundledStreamFromHTML(
'panels/hassio/hassio-main.html', {
strategy: stripImportsStrategy(toStrip)
}
);
return minifyStream(stream, es6)
.pipe(rename('hassio-main.html'))
.pipe(gulp.dest('build-temp'));
}
gulp.task('hassio-panel-es5', buildHassioPanel.bind(null, /* es6= */ false));
gulp.task('hassio-panel', buildHassioPanel.bind(null, /* es6= */ true));

View File

@ -1,8 +1,9 @@
const gulp = require('gulp');
const rollupEach = require('gulp-rollup-each');
const rollupConfig = require('../../rollup.config');
const rollupConfigEs6 = require('../../rollup.config-es6');
gulp.task('run_rollup', () => {
gulp.task('run_rollup_es5', () => {
return gulp.src([
'js/core.js',
'js/compatibility.js',
@ -14,11 +15,29 @@ gulp.task('run_rollup', () => {
.pipe(gulp.dest('build-temp'));
});
gulp.task('ru_all', ['run_rollup'], () => {
gulp.task('run_rollup', () => {
return gulp.src([
'js/core.js',
'js/automation-editor/automation-editor.js',
'js/script-editor/script-editor.js',
'demo_data/demo_data.js',
])
.pipe(rollupEach(rollupConfigEs6, rollupConfigEs6))
.pipe(gulp.dest('build-temp'));
});
gulp.task('ru_all_es5', ['run_rollup_es5'], () => {
gulp.src([
'build-temp/core.js',
'build-temp/compatibility.js',
])
.pipe(gulp.dest('build-es5/'));
});
gulp.task('ru_all', ['run_rollup'], () => {
gulp.src([
'build-temp/core.js',
])
.pipe(gulp.dest('build/'));
});
@ -28,3 +47,10 @@ gulp.task('watch_ru_all', ['ru_all'], () => {
'demo_data/**/*.js'
], ['ru_all']);
});
gulp.task('watch_ru_all_es5', ['ru_all_es5'], () => {
gulp.watch([
'js/**/*.js',
'demo_data/**/*.js'
], ['ru_all_es5']);
});

View File

@ -8,8 +8,8 @@ const minify = require('gulp-jsonminify');
const rename = require('gulp-rename');
const transform = require('gulp-json-transform');
const inDir = 'translations'
const outDir = 'build/translations';
const inDir = 'translations';
const outDir = 'build-translations';
const tasks = [];
@ -22,7 +22,7 @@ function recursive_flatten (prefix, data) {
output[prefix + key] = data[key];
}
});
return output
return output;
}
function flatten (data) {
@ -39,7 +39,7 @@ gulp.task(taskName, function () {
const tr = path.basename(file.history[0], '.json');
const subtags = tr.split('-');
const src = [inDir + '/en.json']; // Start with en as a fallback for missing translations
for (i = 1; i <= subtags.length; i++) {
for (let i = 1; i <= subtags.length; i++) {
const lang = subtags.slice(0, i).join('-');
src.push(inDir + '/' + lang + '.json');
}
@ -67,7 +67,7 @@ tasks.push(taskName);
var taskName = 'build-translation-fingerprints';
gulp.task(taskName, ['build-merged-translations'], function() {
return gulp.src(outDir + '/*.json')
return gulp.src(outDir + '/!(translationFingerprints).json')
.pipe(rename({
extname: "",
}))
@ -83,7 +83,7 @@ gulp.task(taskName, ['build-merged-translations'], function() {
});
return data;
}))
.pipe(gulp.dest('build-temp'));
.pipe(gulp.dest(outDir));
});
tasks.push(taskName);
@ -91,7 +91,7 @@ var taskName = 'build-translations';
gulp.task(taskName, ['build-translation-fingerprints'], function() {
return gulp.src([
'src/translations/translationMetadata.json',
'build-temp/translationFingerprints.json',
outDir + '/translationFingerprints.json',
])
.pipe(merge({}))
.pipe(transform(function(data, file) {
@ -109,7 +109,7 @@ gulp.task(taskName, ['build-translation-fingerprints'], function() {
}))
.pipe(insert.wrap('<script>\nwindow.translationMetadata = ', ';\n</script>'))
.pipe(rename('translationMetadata.html'))
.pipe(gulp.dest('build-temp'));
.pipe(gulp.dest(outDir));
});
tasks.push(taskName);

View File

@ -6,7 +6,7 @@ window.HASS_DEV = __DEV__;
const init = window.createHassConnection = function (password) {
const proto = window.location.protocol === 'https:' ? 'wss' : 'ws';
const url = `${proto}://${window.location.host}/api/websocket`;
const url = `${proto}://${window.location.host}/api/websocket${window.location.search}`;
const options = {
setupRetry: 10,
};
@ -29,9 +29,3 @@ if (window.noAuth) {
} else {
window.hassConnection = null;
}
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/service_worker.js');
});
}

View File

@ -7,12 +7,14 @@
"url": "https://github.com/home-assistant/home-assistant-polymer"
},
"scripts": {
"clean": "rm -rf build/* build-temp/*",
"clean": "rm -rf build/* build-temp/* build-es5/* build-translations/*",
"gulp": "gulp",
"build": "BUILD_DEV=0 gulp",
"build_demo": "BUILD_DEV=0 BUILD_DEMO=1 gulp",
"dev": "npm run gulp ru_all gen-service-worker",
"dev-watch": "npm run gulp watch_ru_all gen-service-worker",
"dev-es5": "npm run gulp ru_all_es5 gen-service-worker-es5",
"dev-watch-es5": "npm run gulp watch_ru_all_es5 gen-service-worker-es5",
"lint_js": "eslint src panels js --ext js,html",
"lint_html": "ls -1 src/home-assistant.html panels/**/ha-panel-*.html | xargs polymer lint --input",
"test": "npm run lint_js && npm run lint_html"
@ -26,6 +28,7 @@
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-babili": "^0.1.4",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2016": "^6.24.1",
"bower": "^1.8.2",
"css-slam": "^2.0.2",
"del": "^3.0.0",
@ -60,6 +63,7 @@
"polymer-bundler": "^3.1.0",
"polymer-cli": "^1.5.6",
"preact": "^8.2.5",
"pump": "^1.0.2",
"require-dir": "^0.3.2",
"rollup": "^0.50.0",
"rollup-plugin-babel": "^3.0.2",
@ -70,6 +74,7 @@
"rollup-watch": "^4.3.1",
"run-sequence": "^2.2.0",
"sw-precache": "^5.2.0",
"uglify-es": "^3.1.6",
"uglify-js": "^3.1.3",
"vulcanize": "^1.16.0"
},

47
rollup.config-es6.js Normal file
View File

@ -0,0 +1,47 @@
const nodeResolve = require('rollup-plugin-node-resolve');
const replace = require('rollup-plugin-replace');
const babel = require('rollup-plugin-babel');
const uglify = require('rollup-plugin-uglify');
const { minify } = require('uglify-es');
const DEV = !!JSON.parse(process.env.BUILD_DEV || 'true');
const DEMO = !!JSON.parse(process.env.BUILD_DEMO || 'false');
const plugins = [
babel({
babelrc: false,
plugins: [
'external-helpers',
'transform-object-rest-spread',
[
'transform-react-jsx',
{
pragma: 'h'
}
],
]
}),
nodeResolve({
jsnext: true,
main: true,
}),
replace({
values: {
__DEV__: JSON.stringify(DEV),
__DEMO__: JSON.stringify(DEMO),
},
}),
];
if (!DEV) {
plugins.push(uglify({}, minify));
}
module.exports = {
format: 'iife',
exports: 'none',
treeshake: true,
plugins,
};

View File

@ -7,30 +7,36 @@ set -e
cd "$(dirname "$0")/.."
OUTPUT_DIR=hass_frontend
OUTPUT_DIR_ES5=hass_frontend_es5
rm -rf $OUTPUT_DIR
rm -rf $OUTPUT_DIR $OUTPUT_DIR_ES5
cp -r public $OUTPUT_DIR
mkdir $OUTPUT_DIR_ES5
cp -r public/__init__.py $OUTPUT_DIR_ES5/
# Build frontend
BUILD_DEV=0 ./node_modules/.bin/gulp
# Entry points
cp build/*.js build/*.html $OUTPUT_DIR
cp build-es5/*.js build-es5/*.html $OUTPUT_DIR_ES5
# Panels
mkdir $OUTPUT_DIR/panels
cp build/panels/*.html $OUTPUT_DIR/panels
mkdir $OUTPUT_DIR_ES5/panels
cp build-es5/panels/*.html $OUTPUT_DIR_ES5/panels
# Panels
# Translations
mkdir $OUTPUT_DIR/translations
cp build/translations/*.json $OUTPUT_DIR/translations
cp build-translations/*.json $OUTPUT_DIR/translations
# Local Roboto
cp -r bower_components/font-roboto-local/fonts $OUTPUT_DIR
# Polyfill web components
cp bower_components/webcomponentsjs/webcomponents-lite.js $OUTPUT_DIR
cp bower_components/webcomponentsjs/custom-elements-es5-adapter.js $OUTPUT_DIR
cp bower_components/webcomponentsjs/custom-elements-es5-adapter.js $OUTPUT_DIR_ES5
# Icons
script/update_mdi.py
@ -41,6 +47,8 @@ cp bower_components/leaflet/dist/leaflet.css $OUTPUT_DIR/images/leaflet
cp -r bower_components/leaflet/dist/images $OUTPUT_DIR/images/leaflet/
# Generate service worker
BUILD_DEV=0 ./node_modules/.bin/gulp gen-service-worker-es5
cp build-es5/service_worker.js $OUTPUT_DIR_ES5
BUILD_DEV=0 ./node_modules/.bin/gulp gen-service-worker
cp build/service_worker.js $OUTPUT_DIR
@ -55,10 +63,19 @@ gzip -f -n -k -9 \
./fonts/roboto/*.ttf \
./fonts/robotomono/*.ttf
cd ..
cd $OUTPUT_DIR_ES5
gzip -f -n -k -9 \
*.html \
*.js \
./panels/*.html
cd ..
# Generate the __init__ file
echo "VERSION = '`git rev-parse HEAD`'" >> $OUTPUT_DIR/__init__.py
echo "CREATED_AT = `date +%s`" >> $OUTPUT_DIR/__init__.py
echo "VERSION = '`git rev-parse HEAD`'" >> $OUTPUT_DIR_ES5/__init__.py
echo "CREATED_AT = `date +%s`" >> $OUTPUT_DIR_ES5/__init__.py
# Generate the MD5 hash of the new frontend
script/fingerprint_frontend.py
script/fingerprint_frontend.py --base_dir $OUTPUT_DIR
script/fingerprint_frontend.py --base_dir $OUTPUT_DIR_ES5

View File

@ -5,9 +5,14 @@ from collections import OrderedDict
import glob
import hashlib
import json
import argparse
from os import path
fingerprint_file = './hass_frontend/__init__.py'
base_dir = 'hass_frontend/'
parser = argparse.ArgumentParser(description='Generate fingerprints of frontend files.')
parser.add_argument('--base_dir', type=str, help='Base dir to look for files.', default='hass_frontend')
args = parser.parse_args()
base_dir = args.base_dir + '/'
fingerprint_file = path.join(base_dir, '__init__.py')
def fingerprint():

View File

@ -7,6 +7,6 @@ setup(name='home-assistant-frontend',
author='Paulus Schoutsen',
author_email='Paulus@PaulusSchoutsen.nl',
license='Apache License 2.0',
packages=find_packages(include=['hass_frontend', 'hass_frontend.*']),
packages=find_packages(include=['hass_frontend', 'hass_frontend_es5', 'hass_frontend.*', 'hass_frontend_es5.*']),
include_package_data=True,
zip_safe=False)

View File

@ -1,4 +1,4 @@
<link rel='import' href='../../build-temp/translationMetadata.html' />
<link rel='import' href='../../build-translations/translationMetadata.html' />
<script>
function getActiveTranslation() {

View File

@ -836,6 +836,14 @@ babel-generator@^6.26.0:
source-map "^0.5.6"
trim-right "^1.0.1"
babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
dependencies:
babel-helper-explode-assignable-expression "^6.24.1"
babel-runtime "^6.22.0"
babel-types "^6.24.1"
babel-helper-builder-react-jsx@^6.24.1:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0"
@ -870,6 +878,14 @@ babel-helper-evaluate-path@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz#0bb2eb01996c0cef53c5e8405e999fe4a0244c08"
babel-helper-explode-assignable-expression@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa"
dependencies:
babel-runtime "^6.22.0"
babel-traverse "^6.24.1"
babel-types "^6.24.1"
babel-helper-flip-expressions@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.1.2.tgz#77f6652f9de9c42401d827bd46ebd2109e3ef18a"
@ -1118,6 +1134,10 @@ babel-plugin-minify-type-constructors@^0.2.0:
dependencies:
babel-helper-is-void-0 "^0.2.0"
babel-plugin-syntax-exponentiation-operator@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
babel-plugin-syntax-jsx@^6.8.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
@ -1294,6 +1314,14 @@ babel-plugin-transform-es2015-unicode-regex@^6.11.0, babel-plugin-transform-es20
babel-runtime "^6.22.0"
regexpu-core "^2.0.0"
babel-plugin-transform-exponentiation-operator@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
dependencies:
babel-helper-builder-binary-assignment-operator-visitor "^6.24.1"
babel-plugin-syntax-exponentiation-operator "^6.8.0"
babel-runtime "^6.22.0"
babel-plugin-transform-inline-consecutive-adds@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.1.2.tgz#5442e9f1c19c78a7899f8a4dee6fd481f61001f5"
@ -1447,6 +1475,12 @@ babel-preset-es2015@^6.18.0, babel-preset-es2015@^6.24.1:
babel-plugin-transform-es2015-unicode-regex "^6.24.1"
babel-plugin-transform-regenerator "^6.24.1"
babel-preset-es2016@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-es2016/-/babel-preset-es2016-6.24.1.tgz#f900bf93e2ebc0d276df9b8ab59724ebfd959f8b"
dependencies:
babel-plugin-transform-exponentiation-operator "^6.24.1"
babel-preset-minify@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz#006566552d9b83834472273f306c0131062a0acc"
@ -6169,7 +6203,7 @@ pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
pump@^1.0.0:
pump@^1.0.0, pump@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51"
dependencies:
@ -7014,6 +7048,10 @@ source-map@~0.2.0:
dependencies:
amdefine ">=0.0.4"
source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
sparkles@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3"
@ -7558,6 +7596,13 @@ ua-parser-js@^0.7.14, ua-parser-js@^0.7.9:
version "0.7.14"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca"
uglify-es@^3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.6.tgz#b0f818c055a7e9538abc2286e70c743f2938311f"
dependencies:
commander "~2.11.0"
source-map "~0.6.1"
uglify-js@2.6.x:
version "2.6.4"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.6.4.tgz#65ea2fb3059c9394692f15fed87c2b36c16b9adf"