Skip to content

Commit

Permalink
Get it all somewhat working
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob committed Aug 2, 2017
1 parent d83a528 commit a35b2a3
Show file tree
Hide file tree
Showing 13 changed files with 337 additions and 235 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ addons:
packages:
- google-chrome-stable
script:
- npm run js_prod
- npm run build
- npm run test
- xvfb-run wct
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct --plugin sauce; fi
Expand Down
7 changes: 7 additions & 0 deletions gulp/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var path = require('path');

module.exports = {
static_dir: path.resolve(__dirname, '../..'),
polymer_dir: path.resolve(__dirname, '..'),
build_dir: path.resolve(__dirname, '../build'),
};
107 changes: 107 additions & 0 deletions gulp/tasks/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { gulp as cssSlam } from 'css-slam';
import gulp from 'gulp';
import babel from 'gulp-babel';
import filter from 'gulp-filter';
import htmlMinifier from 'gulp-html-minifier';
import gulpif from 'gulp-if';
import { PolymerProject, HtmlSplitter } from 'polymer-build';
import {
composeStrategies,
generateShellMergeStrategy,
} from 'polymer-bundler';
import mergeStream from 'merge-stream';
import rename from 'gulp-rename';

import polymerConfig from '../../polymer';

function minifyStream(stream) {
const sourcesHtmlSplitter = new HtmlSplitter();
return stream
.pipe(sourcesHtmlSplitter.split())
.pipe(gulpif(/\.js$/, babel({
presets: ['babili'], // 'es2015'
// plugins: ['external-helpers']
})))
.pipe(gulpif(/\.css$/, cssSlam()))
.pipe(gulpif(/\.html$/, cssSlam()))
.pipe(gulpif(/\.html$/, htmlMinifier({
collapseWhitespace: true,
removeComments: true
})))
.pipe(sourcesHtmlSplitter.rejoin());
}

function renamePanel(path) {
// Rename panels to be panels/* and not their subdir
if (path.basename.substr(0, 9) === 'ha-panel-' && path.extname === '.html') {
path.dirname = 'panels/';
}

// Rename frontend
if (path.dirname === 'src' && path.basename === 'home-assistant' &&
path.extname === '.html') {
path.dirname = '';
path.basename = 'frontend';
}
}

/**
* Polymer build strategy to strip imports, even if explictely imported
*/
function generateStripStrategy(urls) {
return (bundles) => {
for (const bundle of bundles) {
for (const url of urls) {
bundle.stripImports.add(url);
}
}
return bundles;
};
}

/**
* Polymer build strategy to strip everything but the entrypoints
* for bundles that match a specific entry point.
*/
function stripAllButEntrypoint(entryPoint) {
return (bundles) => {
for (const bundle of bundles) {
if (bundle.entrypoints.has(entryPoint)) {
for (const file of bundle.files) {
if (!bundle.entrypoints.has(file)) {
bundle.stripImports.add(file);
}
}
}
}
return bundles;
};
}


gulp.task('build', ['ru_all'], () => {
const strategy = composeStrategies([
generateShellMergeStrategy(polymerConfig.shell),
generateStripStrategy([
'bower_components/font-roboto/roboto.html',
'bower_components/paper-styles/color.html',
]),
stripAllButEntrypoint('panels/hassio/ha-panel-hassio.html')
]);
const project = new PolymerProject(polymerConfig);

return mergeStream(minifyStream(project.sources()),
minifyStream(project.dependencies()))
.pipe(project.bundler({
strategy,
strip: true,
sourcemaps: false,
stripComments: true,
inlineScripts: true,
inlineCss: true,
implicitStrip: true,
}))
.pipe(rename(renamePanel))
.pipe(filter(['**', '!src/entrypoint.html']))
.pipe(gulp.dest('build/'));
});
6 changes: 6 additions & 0 deletions gulp/tasks/clean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import del from 'del';
import gulp from 'gulp';

gulp.task('clean', () => {
return del(['build', 'build-temp']);
});
9 changes: 9 additions & 0 deletions gulp/tasks/default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import gulp from 'gulp';
import runSequence from 'run-sequence';

gulp.task('default', () => {
return runSequence.use(gulp)(
'clean',
'build',
);
});
109 changes: 109 additions & 0 deletions gulp/tasks/gen-service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
Generate a caching service worker for HA
Will be called as part of build_frontend.
Expects home-assistant-polymer repo as submodule of HA repo.
Creates a caching service worker based on the CURRENT content of HA repo.
Output service worker to build/service_worker.js
TODO:
- Use gulp streams
*/
var gulp = require('gulp');
var crypto = require('crypto');
var fs = require('fs');
var path = require('path');
var swPrecache = require('sw-precache');
var uglifyJS = require('uglify-js');

const config = require('../config');

const DEV = !!JSON.parse(process.env.BUILD_DEV || 'true');

var rootDir = config.static_dir;
var panelDir = path.resolve(rootDir, 'panels');

var dynamicUrlToDependencies = {
'/': [
rootDir + '/frontend.html',
rootDir + '/core.js',
rootDir + '/compatibility.js',
],
};

var staticFingerprinted = [
'frontend.html',
'mdi.html',
'core.js',
'compatibility.js',
];

// These panels will always be registered inside HA and thus can
// be safely assumed to be able to preload.
var panelsFingerprinted = [
'map', 'dev-event', 'dev-info', 'dev-service', 'dev-state', 'dev-template',
'dev-mqtt',
];

function md5(filename) {
return crypto.createHash('md5')
.update(fs.readFileSync(filename)).digest('hex');
}

gulp.task('gen-service-worker', () => {
// Create fingerprinted versions of our dependencies.
staticFingerprinted.forEach(fn => {
var parts = path.parse(fn);
var hash = md5(rootDir + '/' + parts.name + parts.ext);
var url = '/static/' + parts.name + '-' + hash + parts.ext;
var fpath = rootDir + '/' + parts.name + parts.ext;
dynamicUrlToDependencies[url] = [fpath];
});

panelsFingerprinted.forEach(panel => {
var fpath = panelDir + '/ha-panel-' + panel + '.html';
var hash = md5(fpath);
var url = '/frontend/panels/' + panel + '-' + hash + '.html';
dynamicUrlToDependencies[url] = [fpath];
});

var 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',
],
stripPrefix: '..',
replacePrefix: 'static',
verbose: true,
};

var devBase = 'console.warn("Service worker caching disabled in development")';

var swHass = fs.readFileSync(path.resolve(__dirname, 'service-worker.js.tmpl'), 'UTF-8');

var genPromise = DEV ? Promise.resolve(devBase) : swPrecache.generate(options);

genPromise = genPromise.then(swString => swString + '\n' + swHass);

// Fix this
// if (!DEV) {
// genPromise = genPromise.then(
// swString => uglifyJS.minify(swString, { fromString: true }).code);
// }

genPromise.then(swString => {
fs.writeFileSync(path.resolve(config.build_dir, 'service_worker.js'), swString);
});

return genPromise;
});
30 changes: 17 additions & 13 deletions script/hassio-panel.js → gulp/tasks/hassio-panel.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#!/usr/bin/env node

/*
TODO:
- Use gulp streams
- Use polymer bundler to vulcanize
*/
var gulp = require('gulp');
var Vulcanize = require('vulcanize');
var minify = require('html-minifier');
var fs = require('fs');

if (!fs.existsSync('build')) {
fs.mkdirSync('build');
}
if (!fs.existsSync('build/panels')) {
fs.mkdirSync('build/panels');
}

function minifyHTML(html) {
return minify.minify(html, {
customAttrAssign: [/\$=/],
Expand Down Expand Up @@ -68,7 +65,14 @@ function vulcanizeEntry(entry) {
});
}

toProcess.reduce(
(p, entry) => p.then(() => vulcanizeEntry(entry)),
Promise.resolve())
.catch(err => console.error('Something went wrong!', err));
gulp.task('hassio-panel', () => {
if (!fs.existsSync('build-temp')) {
fs.mkdirSync('build-temp');
}

toProcess.reduce(
(p, entry) => p.then(() => vulcanizeEntry(entry)),
Promise.resolve());

return toProcess;
});
29 changes: 29 additions & 0 deletions gulp/tasks/rollup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import gulp from 'gulp';
import rollupEach from 'gulp-rollup-each';
import rollupConfig from '../../rollup.config';

gulp.task('run_rollup', () => {
return gulp.src([
'js/core.js',
'js/compatibility.js',
'js/editor/editor.js',
'demo_data/demo_data.js',
])
.pipe(rollupEach(rollupConfig))
.pipe(gulp.dest('build-temp'));
});

gulp.task('ru_all', ['run_rollup'], () => {
gulp.src([
'build-temp/core.js',
'build-temp/compatibility.js',
])
.pipe(gulp.dest('build/'));
});

gulp.task('watch_ru_all', ['ru_all'], () => {
gulp.watch([
'js/**/*.js',
'demo_data/**/*.js'
], ['ru_all']);
});
File renamed without changes.

0 comments on commit a35b2a3

Please sign in to comment.