Build a new Hass.io panel (#1271)
* Build a new Hass.io panel * Use webcomponents-lite.js * Compress new panel * Lintpull/1273/head
parent
92930a2b94
commit
d243f2ead6
|
@ -2,7 +2,9 @@ const path = require('path');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Target directory for the build.
|
// 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.
|
// Path where the Hass.io frontend will be publicly available.
|
||||||
publicPath: '/api/hassio/app-es5'
|
publicPath: '/api/hassio/app',
|
||||||
|
publicPathLegacy: '/api/hassio/app-es5',
|
||||||
}
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
'import' in document.createElement('link') &&
|
'import' in document.createElement('link') &&
|
||||||
'content' in document.createElement('template'));
|
'content' in document.createElement('template'));
|
||||||
if (!webComponentsSupported) {
|
if (!webComponentsSupported) {
|
||||||
addScript('/static/webcomponents-bundle.js');
|
addScript('/static/webcomponents-lite.js');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -6,11 +6,14 @@ set -e
|
||||||
|
|
||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
OUTPUT_DIR=build
|
||||||
OUTPUT_DIR_ES5=build-es5
|
OUTPUT_DIR_ES5=build-es5
|
||||||
|
|
||||||
rm -rf $OUTPUT_DIR_ES5
|
rm -rf $OUTPUT_DIR $OUTPUT_DIR_ES5
|
||||||
node script/gen-icons.js
|
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
|
node script/gen-index-html.js
|
||||||
|
|
||||||
# Temporarily re-create old HTML import
|
# 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
|
echo "</script>" >> $OUTPUT_DIR_ES5/hassio-app.html
|
||||||
rm $OUTPUT_DIR_ES5/app.js*
|
rm $OUTPUT_DIR_ES5/app.js*
|
||||||
rm $OUTPUT_DIR_ES5/chunk.*
|
rm $OUTPUT_DIR_ES5/chunk.*
|
||||||
|
|
||||||
|
# NEW BUILD
|
||||||
|
NODE_ENV=production ../node_modules/.bin/webpack -p --config webpack.config.js
|
||||||
|
|
|
@ -4,10 +4,9 @@
|
||||||
# Stop on errors
|
# Stop on errors
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
OUTPUT_DIR_ES5=build-es5
|
OUTPUT_DIR=build
|
||||||
|
|
||||||
rm -rf $OUTPUT_DIR_ES5
|
rm -rf $OUTPUT_DIR
|
||||||
mkdir $OUTPUT_DIR_ES5
|
mkdir $OUTPUT_DIR
|
||||||
node script/gen-index-html.js
|
|
||||||
node script/gen-icons.js
|
node script/gen-icons.js
|
||||||
../node_modules/.bin/webpack --watch --progress
|
../node_modules/.bin/webpack --watch --progress
|
||||||
|
|
|
@ -15,4 +15,4 @@ for (item of toReplace) {
|
||||||
index = index.replace(item[0], item[1]);
|
index = index.replace(item[0], item[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(`${config.buildDir}/index.html`, index);
|
fs.writeFileSync(`${config.buildDirLegacy}/index.html`, index);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
window.loadES5Adapter().then(() => {
|
||||||
|
import(/* webpackChunkName: "hassio-icons" */ './resources/hassio-icons.js');
|
||||||
|
import(/* webpackChunkName: "hassio-main" */ './hassio-main.js');
|
||||||
|
});
|
||||||
|
|
|
@ -2,6 +2,7 @@ const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||||
|
const CompressionPlugin = require("compression-webpack-plugin");
|
||||||
const config = require('./config.js');
|
const config = require('./config.js');
|
||||||
|
|
||||||
const version = fs.readFileSync('../setup.py', 'utf8').match(/\d{8}[^']*/);
|
const version = fs.readFileSync('../setup.py', 'utf8').match(/\d{8}[^']*/);
|
||||||
|
@ -29,6 +30,15 @@ if (isProdBuild) {
|
||||||
mangle: false,
|
mangle: false,
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
plugins.push(new CompressionPlugin({
|
||||||
|
cache: true,
|
||||||
|
exclude: [
|
||||||
|
/\.js\.map$/,
|
||||||
|
/\.LICENSE$/,
|
||||||
|
/\.py$/,
|
||||||
|
/\.txt$/,
|
||||||
|
]
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -37,7 +47,7 @@ module.exports = {
|
||||||
// Was source-map
|
// Was source-map
|
||||||
devtool: isProdBuild ? 'none' : 'inline-source-map',
|
devtool: isProdBuild ? 'none' : 'inline-source-map',
|
||||||
entry: {
|
entry: {
|
||||||
app: './src/hassio-app.js',
|
entrypoint: './src/entrypoint.js',
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
|
|
@ -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}/`,
|
||||||
|
}
|
||||||
|
};
|
|
@ -9,7 +9,6 @@
|
||||||
"src/panels/dev-service/ha-panel-dev-service.js",
|
"src/panels/dev-service/ha-panel-dev-service.js",
|
||||||
"src/panels/dev-state/ha-panel-dev-state.js",
|
"src/panels/dev-state/ha-panel-dev-state.js",
|
||||||
"src/panels/dev-template/ha-panel-dev-template.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/history/ha-panel-history.js",
|
||||||
"src/panels/iframe/ha-panel-iframe.js",
|
"src/panels/iframe/ha-panel-iframe.js",
|
||||||
"src/panels/kiosk/ha-panel-kiosk.js",
|
"src/panels/kiosk/ha-panel-kiosk.js",
|
||||||
|
@ -17,7 +16,7 @@
|
||||||
"src/panels/map/ha-panel-map.js",
|
"src/panels/map/ha-panel-map.js",
|
||||||
"src/panels/shopping-list/ha-panel-shopping-list.js",
|
"src/panels/shopping-list/ha-panel-shopping-list.js",
|
||||||
"src/panels/mailbox/ha-panel-mailbox.js",
|
"src/panels/mailbox/ha-panel-mailbox.js",
|
||||||
"hassio/src/hassio-app.js"
|
"hassio/src/entrypoint.js"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"src/**/*",
|
"src/**/*",
|
||||||
|
|
|
@ -49,10 +49,6 @@ function ensureLoaded(panel) {
|
||||||
imported = import(/* webpackChunkName: "panel-dev-template" */ '../panels/dev-template/ha-panel-dev-template.js');
|
imported = import(/* webpackChunkName: "panel-dev-template" */ '../panels/dev-template/ha-panel-dev-template.js');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'hassio':
|
|
||||||
imported = import(/* webpackChunkName: "panel-hassio" */ '../panels/hassio/ha-panel-hassio.js');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'history':
|
case 'history':
|
||||||
imported = import(/* webpackChunkName: "panel-history" */ '../panels/history/ha-panel-history.js');
|
imported = import(/* webpackChunkName: "panel-history" */ '../panels/history/ha-panel-history.js');
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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);
|
|
Loading…
Reference in New Issue