Build a new Hass.io panel (#1271)

* Build a new Hass.io panel

* Use webcomponents-lite.js

* Compress new panel

* Lint
This commit is contained in:
Paulus Schoutsen 2018-06-08 15:26:48 -04:00 committed by GitHub
parent 92930a2b94
commit d243f2ead6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 112 additions and 101 deletions

View File

@ -2,7 +2,9 @@ const path = require('path');
module.exports = {
// Target directory for the build.
buildDir: path.resolve(__dirname, 'build-es5'),
buildDirLegacy: path.resolve(__dirname, 'build-es5'),
buildDir: path.resolve(__dirname, 'build'),
// Path where the Hass.io frontend will be publicly available.
publicPath: '/api/hassio/app-es5'
publicPath: '/api/hassio/app',
publicPathLegacy: '/api/hassio/app-es5',
}

View File

@ -26,7 +26,7 @@
'import' in document.createElement('link') &&
'content' in document.createElement('template'));
if (!webComponentsSupported) {
addScript('/static/webcomponents-bundle.js');
addScript('/static/webcomponents-lite.js');
}
</script>
<!--

View File

@ -6,11 +6,14 @@ set -e
cd "$(dirname "$0")/.."
OUTPUT_DIR=build
OUTPUT_DIR_ES5=build-es5
rm -rf $OUTPUT_DIR_ES5
rm -rf $OUTPUT_DIR $OUTPUT_DIR_ES5
node script/gen-icons.js
NODE_ENV=production ../node_modules/.bin/webpack -p
# LEGACY BUILD
NODE_ENV=production ../node_modules/.bin/webpack -p --config webpack.legacy.config.js
node script/gen-index-html.js
# Temporarily re-create old HTML import
@ -20,3 +23,6 @@ cat $OUTPUT_DIR_ES5/chunk.*.js >> $OUTPUT_DIR_ES5/hassio-app.html
echo "</script>" >> $OUTPUT_DIR_ES5/hassio-app.html
rm $OUTPUT_DIR_ES5/app.js*
rm $OUTPUT_DIR_ES5/chunk.*
# NEW BUILD
NODE_ENV=production ../node_modules/.bin/webpack -p --config webpack.config.js

View File

@ -4,10 +4,9 @@
# Stop on errors
set -e
OUTPUT_DIR_ES5=build-es5
OUTPUT_DIR=build
rm -rf $OUTPUT_DIR_ES5
mkdir $OUTPUT_DIR_ES5
node script/gen-index-html.js
rm -rf $OUTPUT_DIR
mkdir $OUTPUT_DIR
node script/gen-icons.js
../node_modules/.bin/webpack --watch --progress

View File

@ -15,4 +15,4 @@ for (item of toReplace) {
index = index.replace(item[0], item[1]);
}
fs.writeFileSync(`${config.buildDir}/index.html`, index);
fs.writeFileSync(`${config.buildDirLegacy}/index.html`, index);

5
hassio/src/entrypoint.js Normal file
View File

@ -0,0 +1,5 @@
window.loadES5Adapter().then(() => {
import(/* webpackChunkName: "hassio-icons" */ './resources/hassio-icons.js');
import(/* webpackChunkName: "hassio-main" */ './hassio-main.js');
});

View File

@ -2,6 +2,7 @@ const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionPlugin = require("compression-webpack-plugin");
const config = require('./config.js');
const version = fs.readFileSync('../setup.py', 'utf8').match(/\d{8}[^']*/);
@ -29,6 +30,15 @@ if (isProdBuild) {
mangle: false,
}
}));
plugins.push(new CompressionPlugin({
cache: true,
exclude: [
/\.js\.map$/,
/\.LICENSE$/,
/\.py$/,
/\.txt$/,
]
}));
}
module.exports = {
@ -37,7 +47,7 @@ module.exports = {
// Was source-map
devtool: isProdBuild ? 'none' : 'inline-source-map',
entry: {
app: './src/hassio-app.js',
entrypoint: './src/entrypoint.js',
},
module: {
rules: [

View File

@ -0,0 +1,78 @@
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const config = require('./config.js');
const version = fs.readFileSync('../setup.py', 'utf8').match(/\d{8}[^']*/);
if (!version) {
throw Error('Version not found');
}
const VERSION = version[0];
const isProdBuild = process.env.NODE_ENV === 'production'
const chunkFilename = isProdBuild ?
'chunk.[chunkhash].js' : '[name].chunk.js';
const plugins = [
new webpack.DefinePlugin({
__DEV__: JSON.stringify(!isProdBuild),
__VERSION__: JSON.stringify(VERSION),
})
];
if (isProdBuild) {
plugins.push(new UglifyJsPlugin({
extractComments: true,
sourceMap: true,
uglifyOptions: {
// Disabling because it broke output
mangle: false,
}
}));
}
module.exports = {
mode: isProdBuild ? 'production' : 'development',
// Disabled in prod while we make Home Assistant able to serve the right files.
// Was source-map
devtool: isProdBuild ? 'none' : 'inline-source-map',
entry: {
app: './src/hassio-app.js',
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['es2015', { modules: false }]
],
plugins: [
// Only support the syntax, Webpack will handle it.
"syntax-dynamic-import",
],
},
},
},
{
test: /\.(html)$/,
use: {
loader: 'html-loader',
options: {
exportAsEs6Default: true,
}
}
}
]
},
plugins,
output: {
filename: '[name].js',
chunkFilename: chunkFilename,
path: config.buildDirLegacy,
publicPath: `${config.publicPathLegacy}/`,
}
};

View File

@ -9,7 +9,6 @@
"src/panels/dev-service/ha-panel-dev-service.js",
"src/panels/dev-state/ha-panel-dev-state.js",
"src/panels/dev-template/ha-panel-dev-template.js",
"src/panels/hassio/ha-panel-hassio.js",
"src/panels/history/ha-panel-history.js",
"src/panels/iframe/ha-panel-iframe.js",
"src/panels/kiosk/ha-panel-kiosk.js",
@ -17,7 +16,7 @@
"src/panels/map/ha-panel-map.js",
"src/panels/shopping-list/ha-panel-shopping-list.js",
"src/panels/mailbox/ha-panel-mailbox.js",
"hassio/src/hassio-app.js"
"hassio/src/entrypoint.js"
],
"sources": [
"src/**/*",

View File

@ -49,10 +49,6 @@ function ensureLoaded(panel) {
imported = import(/* webpackChunkName: "panel-dev-template" */ '../panels/dev-template/ha-panel-dev-template.js');
break;
case 'hassio':
imported = import(/* webpackChunkName: "panel-hassio" */ '../panels/hassio/ha-panel-hassio.js');
break;
case 'history':
imported = import(/* webpackChunkName: "panel-history" */ '../panels/history/ha-panel-history.js');
break;

View File

@ -1,84 +0,0 @@
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
import config from '../../../hassio/config.js';
import EventsMixin from '../../mixins/events-mixin.js';
import NavigateMixin from '../../mixins/navigate-mixin.js';
/*
* Mixins are used by ifram to communicate with main frontend.
* @appliesMixin EventsMixin
* @appliesMixin NavigateMixin
*/
class HaPanelHassio extends NavigateMixin(EventsMixin(PolymerElement)) {
static get template() {
return html`
<style>
iframe {
border: 0;
width: 100%;
height: 100%;
display: block;
}
</style>
<iframe
id='iframe'
src="[[iframeUrl]]"
></iframe>
`;
}
static get properties() {
return {
hass: Object,
narrow: Boolean,
showMenu: Boolean,
route: Object,
iframeUrl: {
type: String,
value: `${config.publicPath}/index.html`
}
};
}
static get observers() {
return [
'_dataChanged(hass, narrow, showMenu, route)'
];
}
ready() {
super.ready();
// Make it available for the iframe to interact
window.hassioPanel = this;
}
_dataChanged(hass, narrow, showMenu, route) {
this._updateProperties({ hass, narrow, showMenu, route });
}
_updateProperties(data) {
const setProperties = this.$.iframe.contentWindow && this.$.iframe.contentWindow.setProperties;
// Delay calling setProperties until iframe loaded
if (!setProperties) {
// Check if we already have a setTimeout scheduled
const needTimeout = !this._dataToSet;
this._dataToSet = data;
if (needTimeout) {
setTimeout(() => {
const dataToSet = this._dataToSet;
this._dataToSet = null;
this._updateProperties(dataToSet);
}, 100);
}
return;
}
setProperties(data);
}
}
customElements.define('ha-panel-hassio', HaPanelHassio);