diff --git a/.travis.yml b/.travis.yml
index 4b357440b7..24433d2e24 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,19 +8,20 @@ install: yarn install
script:
- npm run build
- hassio/script/build_hassio
+ # Because else eslint fails because hassio has cleaned that build
+ - ./node_modules/.bin/gulp gen-icons-app
- npm run test
# - xvfb-run wct --module-resolution=node --npm
# - 'if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct --module-resolution=node --npm --plugin sauce; fi'
services:
- docker
before_deploy:
- - 'docker pull lokalise/lokalise-cli@sha256:2198814ebddfda56ee041a4b427521757dd57f75415ea9693696a64c550cef21'
+ - "docker pull lokalise/lokalise-cli@sha256:2198814ebddfda56ee041a4b427521757dd57f75415ea9693696a64c550cef21"
deploy:
provider: script
script: script/travis_deploy
- 'on':
+ "on":
branch: master
dist: trusty
addons:
sauce_connect: true
-
diff --git a/build-scripts/env.js b/build-scripts/env.js
new file mode 100644
index 0000000000..101858a367
--- /dev/null
+++ b/build-scripts/env.js
@@ -0,0 +1,6 @@
+module.exports = {
+ isProdBuild: process.env.NODE_ENV === "production",
+ isStatsBuild: process.env.STATS === "1",
+ isTravis: process.env.TRAVIS === "true",
+ isNetlify: process.env.NETLIFY === "true",
+};
diff --git a/build-scripts/gulp/app.js b/build-scripts/gulp/app.js
index a86e68b527..985067c71f 100644
--- a/build-scripts/gulp/app.js
+++ b/build-scripts/gulp/app.js
@@ -1,6 +1,8 @@
// Run HA develop mode
const gulp = require("gulp");
+const envVars = require("../env");
+
require("./clean.js");
require("./translations.js");
require("./gen-icons.js");
@@ -19,7 +21,7 @@ gulp.task(
"clean",
gulp.parallel(
"gen-service-worker-dev",
- "gen-icons",
+ gulp.parallel("gen-icons-app", "gen-icons-mdi"),
"gen-pages-dev",
"gen-index-app-dev",
gulp.series("create-test-translation", "build-translations")
@@ -36,10 +38,11 @@ gulp.task(
process.env.NODE_ENV = "production";
},
"clean",
- gulp.parallel("gen-icons", "build-translations"),
+ gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"),
"copy-static",
"webpack-prod-app",
- ...(process.env.CI === "true" ? [] : ["compress-app"]),
+ ...// Don't compress running tests
+ (envVars.isTravis ? [] : ["compress-app"]),
gulp.parallel(
"gen-pages-prod",
"gen-index-app-prod",
diff --git a/build-scripts/gulp/cast.js b/build-scripts/gulp/cast.js
index 974d2c29cf..34fcbb67a4 100644
--- a/build-scripts/gulp/cast.js
+++ b/build-scripts/gulp/cast.js
@@ -1,4 +1,3 @@
-// Run cast develop mode
const gulp = require("gulp");
require("./clean.js");
@@ -16,7 +15,12 @@ gulp.task(
process.env.NODE_ENV = "development";
},
"clean-cast",
- gulp.parallel("gen-icons", "gen-index-cast-dev", "build-translations"),
+ gulp.parallel(
+ "gen-icons-app",
+ "gen-icons-mdi",
+ "gen-index-cast-dev",
+ "build-translations"
+ ),
"copy-static-cast",
"webpack-dev-server-cast"
)
@@ -29,7 +33,7 @@ gulp.task(
process.env.NODE_ENV = "production";
},
"clean-cast",
- gulp.parallel("gen-icons", "build-translations"),
+ gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"),
"copy-static-cast",
"webpack-prod-cast",
"gen-index-cast-prod"
diff --git a/build-scripts/gulp/clean.js b/build-scripts/gulp/clean.js
index f81728fcb3..41fec51e69 100644
--- a/build-scripts/gulp/clean.js
+++ b/build-scripts/gulp/clean.js
@@ -9,15 +9,31 @@ gulp.task(
return del([config.root, config.build_dir]);
})
);
+
gulp.task(
"clean-demo",
gulp.parallel("clean-translations", function cleanOutputAndBuildDir() {
return del([config.demo_root, config.build_dir]);
})
);
+
gulp.task(
"clean-cast",
gulp.parallel("clean-translations", function cleanOutputAndBuildDir() {
return del([config.cast_root, config.build_dir]);
})
);
+
+gulp.task(
+ "clean-hassio",
+ gulp.parallel("clean-translations", function cleanOutputAndBuildDir() {
+ return del([config.hassio_root, config.build_dir]);
+ })
+);
+
+gulp.task(
+ "clean-gallery",
+ gulp.parallel("clean-translations", function cleanOutputAndBuildDir() {
+ return del([config.gallery_root, config.build_dir]);
+ })
+);
diff --git a/build-scripts/gulp/compress.js b/build-scripts/gulp/compress.js
index f41122c55c..de604f7fa3 100644
--- a/build-scripts/gulp/compress.js
+++ b/build-scripts/gulp/compress.js
@@ -29,3 +29,10 @@ gulp.task("compress-app", function compressApp() {
return merge(jsLatest, jsEs5, polyfills, translations);
});
+
+gulp.task("compress-hassio", function compressApp() {
+ return gulp
+ .src(path.resolve(paths.hassio_root, "**/*.js"))
+ .pipe(zopfli())
+ .pipe(gulp.dest(paths.hassio_root));
+});
diff --git a/build-scripts/gulp/demo.js b/build-scripts/gulp/demo.js
index 2c8070962d..de51760281 100644
--- a/build-scripts/gulp/demo.js
+++ b/build-scripts/gulp/demo.js
@@ -17,7 +17,8 @@ gulp.task(
},
"clean-demo",
gulp.parallel(
- "gen-icons",
+ "gen-icons-app",
+ "gen-icons-mdi",
"gen-icons-demo",
"gen-index-demo-dev",
"build-translations"
@@ -34,7 +35,12 @@ gulp.task(
process.env.NODE_ENV = "production";
},
"clean-demo",
- gulp.parallel("gen-icons", "gen-icons-demo", "build-translations"),
+ gulp.parallel(
+ "gen-icons-app",
+ "gen-icons-mdi",
+ "gen-icons-demo",
+ "build-translations"
+ ),
"copy-static-demo",
"webpack-prod-demo",
"gen-index-demo-prod"
diff --git a/build-scripts/gulp/entry-html.js b/build-scripts/gulp/entry-html.js
index 33abdff712..e8ad05e8b4 100644
--- a/build-scripts/gulp/entry-html.js
+++ b/build-scripts/gulp/entry-html.js
@@ -11,12 +11,6 @@ const config = require("../paths.js");
const templatePath = (tpl) =>
path.resolve(config.polymer_dir, "src/html/", `${tpl}.html.template`);
-const demoTemplatePath = (tpl) =>
- path.resolve(config.demo_dir, "src/html/", `${tpl}.html.template`);
-
-const castTemplatePath = (tpl) =>
- path.resolve(config.cast_dir, "src/html/", `${tpl}.html.template`);
-
const readFile = (pth) => fs.readFileSync(pth).toString();
const renderTemplate = (pth, data = {}, pathFunc = templatePath) => {
@@ -25,10 +19,19 @@ const renderTemplate = (pth, data = {}, pathFunc = templatePath) => {
};
const renderDemoTemplate = (pth, data = {}) =>
- renderTemplate(pth, data, demoTemplatePath);
+ renderTemplate(pth, data, (tpl) =>
+ path.resolve(config.demo_dir, "src/html/", `${tpl}.html.template`)
+ );
const renderCastTemplate = (pth, data = {}) =>
- renderTemplate(pth, data, castTemplatePath);
+ renderTemplate(pth, data, (tpl) =>
+ path.resolve(config.cast_dir, "src/html/", `${tpl}.html.template`)
+ );
+
+const renderGalleryTemplate = (pth, data = {}) =>
+ renderTemplate(pth, data, (tpl) =>
+ path.resolve(config.gallery_dir, "src/html/", `${tpl}.html.template`)
+ );
const minifyHtml = (content) =>
minify(content, {
@@ -209,8 +212,33 @@ gulp.task("gen-index-demo-prod", (done) => {
es5Compatibility: es5Manifest["compatibility.js"],
es5DemoJS: es5Manifest["main.js"],
});
- const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}");
+ const minified = minifyHtml(content);
fs.outputFileSync(path.resolve(config.demo_root, "index.html"), minified);
done();
});
+
+gulp.task("gen-index-gallery-dev", (done) => {
+ // In dev mode we don't mangle names, so we hardcode urls. That way we can
+ // run webpack as last in watch mode, which blocks output.
+ const content = renderGalleryTemplate("index", {
+ latestGalleryJS: "./entrypoint.js",
+ });
+
+ fs.outputFileSync(path.resolve(config.gallery_root, "index.html"), content);
+ done();
+});
+
+gulp.task("gen-index-gallery-prod", (done) => {
+ const latestManifest = require(path.resolve(
+ config.gallery_output,
+ "manifest.json"
+ ));
+ const content = renderGalleryTemplate("index", {
+ latestGalleryJS: latestManifest["entrypoint.js"],
+ });
+ const minified = minifyHtml(content);
+
+ fs.outputFileSync(path.resolve(config.gallery_root, "index.html"), minified);
+ done();
+});
diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js
new file mode 100644
index 0000000000..a46c6c1939
--- /dev/null
+++ b/build-scripts/gulp/gallery.js
@@ -0,0 +1,38 @@
+// Run demo develop mode
+const gulp = require("gulp");
+
+require("./clean.js");
+require("./translations.js");
+require("./gen-icons.js");
+require("./gather-static.js");
+require("./webpack.js");
+require("./service-worker.js");
+require("./entry-html.js");
+
+gulp.task(
+ "develop-gallery",
+ gulp.series(
+ async function setEnv() {
+ process.env.NODE_ENV = "development";
+ },
+ "clean-gallery",
+ gulp.parallel("gen-icons-app", "gen-icons-app", "build-translations"),
+ "copy-static-gallery",
+ "gen-index-gallery-dev",
+ "webpack-dev-server-gallery"
+ )
+);
+
+gulp.task(
+ "build-gallery",
+ gulp.series(
+ async function setEnv() {
+ process.env.NODE_ENV = "production";
+ },
+ "clean-gallery",
+ gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"),
+ "copy-static-gallery",
+ "webpack-prod-gallery",
+ "gen-index-gallery-prod"
+ )
+);
diff --git a/build-scripts/gulp/gather-static.js b/build-scripts/gulp/gather-static.js
index 7b3b9300be..17a1a87ae8 100644
--- a/build-scripts/gulp/gather-static.js
+++ b/build-scripts/gulp/gather-static.js
@@ -111,3 +111,15 @@ gulp.task("copy-static-cast", (done) => {
copyTranslations(paths.cast_static);
done();
});
+
+gulp.task("copy-static-gallery", (done) => {
+ // Copy app static files
+ fs.copySync(polyPath("public/static"), paths.gallery_static);
+ // Copy gallery static files
+ fs.copySync(path.resolve(paths.gallery_dir, "public"), paths.gallery_root);
+
+ copyMapPanel(paths.gallery_static);
+ copyFonts(paths.gallery_static);
+ copyTranslations(paths.gallery_static);
+ done();
+});
diff --git a/build-scripts/gulp/gen-icons.js b/build-scripts/gulp/gen-icons.js
index 11548794c4..b116b8abea 100644
--- a/build-scripts/gulp/gen-icons.js
+++ b/build-scripts/gulp/gen-icons.js
@@ -57,18 +57,6 @@ function generateIconset(iconsetName, iconNames) {
return ``;
}
-// Generate the full MDI iconset
-function genMDIIcons() {
- const meta = JSON.parse(
- fs.readFileSync(path.resolve(ICON_PACKAGE_PATH, META_PATH), "UTF-8")
- );
- const iconNames = meta.map((iconInfo) => iconInfo.name);
- if (!fs.existsSync(OUTPUT_DIR)) {
- fs.mkdirSync(OUTPUT_DIR);
- }
- fs.writeFileSync(MDI_OUTPUT_PATH, generateIconset("mdi", iconNames));
-}
-
// Helper function to map recursively over files in a folder and it's subfolders
function mapFiles(startPath, filter, mapFunc) {
const files = fs.readdirSync(startPath);
@@ -101,24 +89,27 @@ function findIcons(searchPath, iconsetName) {
return icons;
}
-function genHassIcons() {
+gulp.task("gen-icons-mdi", (done) => {
+ const meta = JSON.parse(
+ fs.readFileSync(path.resolve(ICON_PACKAGE_PATH, META_PATH), "UTF-8")
+ );
+ const iconNames = meta.map((iconInfo) => iconInfo.name);
+ if (!fs.existsSync(OUTPUT_DIR)) {
+ fs.mkdirSync(OUTPUT_DIR);
+ }
+ fs.writeFileSync(MDI_OUTPUT_PATH, generateIconset("mdi", iconNames));
+ done();
+});
+
+gulp.task("gen-icons-app", (done) => {
const iconNames = findIcons("./src", "hass");
BUILT_IN_PANEL_ICONS.forEach((name) => iconNames.add(name));
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR);
}
fs.writeFileSync(HASS_OUTPUT_PATH, generateIconset("hass", iconNames));
-}
-
-gulp.task("gen-icons-mdi", (done) => {
- genMDIIcons();
done();
});
-gulp.task("gen-icons-hass", (done) => {
- genHassIcons();
- done();
-});
-gulp.task("gen-icons", gulp.series("gen-icons-hass", "gen-icons-mdi"));
gulp.task("gen-icons-demo", (done) => {
const iconNames = findIcons(path.resolve(paths.demo_dir, "./src"), "hademo");
@@ -129,8 +120,21 @@ gulp.task("gen-icons-demo", (done) => {
done();
});
-module.exports = {
- findIcons,
- generateIconset,
- genMDIIcons,
-};
+gulp.task("gen-icons-hassio", (done) => {
+ const iconNames = findIcons(
+ path.resolve(paths.hassio_dir, "./src"),
+ "hassio"
+ );
+ // Find hassio icons inside HA main repo.
+ for (const item of findIcons(
+ path.resolve(paths.polymer_dir, "./src"),
+ "hassio"
+ )) {
+ iconNames.add(item);
+ }
+ fs.writeFileSync(
+ path.resolve(paths.hassio_dir, "hassio-icons.html"),
+ generateIconset("hassio", iconNames)
+ );
+ done();
+});
diff --git a/build-scripts/gulp/hassio.js b/build-scripts/gulp/hassio.js
new file mode 100644
index 0000000000..164a5b9deb
--- /dev/null
+++ b/build-scripts/gulp/hassio.js
@@ -0,0 +1,34 @@
+const gulp = require("gulp");
+
+const envVars = require("../env");
+
+require("./clean.js");
+require("./gen-icons.js");
+require("./webpack.js");
+require("./compress.js");
+
+gulp.task(
+ "develop-hassio",
+ gulp.series(
+ async function setEnv() {
+ process.env.NODE_ENV = "development";
+ },
+ "clean-hassio",
+ gulp.parallel("gen-icons-hassio", "gen-icons-mdi"),
+ "webpack-watch-hassio"
+ )
+);
+
+gulp.task(
+ "build-hassio",
+ gulp.series(
+ async function setEnv() {
+ process.env.NODE_ENV = "production";
+ },
+ "clean-hassio",
+ gulp.parallel("gen-icons-hassio", "gen-icons-mdi"),
+ "webpack-prod-hassio",
+ ...// Don't compress running tests
+ (envVars.isTravis ? [] : ["compress-hassio"])
+ )
+);
diff --git a/build-scripts/gulp/webpack.js b/build-scripts/gulp/webpack.js
index 6015009d2d..9ea304658b 100644
--- a/build-scripts/gulp/webpack.js
+++ b/build-scripts/gulp/webpack.js
@@ -1,6 +1,5 @@
// Tasks to run webpack.
const gulp = require("gulp");
-const path = require("path");
const webpack = require("webpack");
const WebpackDevServer = require("webpack-dev-server");
const log = require("fancy-log");
@@ -9,8 +8,33 @@ const {
createAppConfig,
createDemoConfig,
createCastConfig,
+ createHassioConfig,
+ createGalleryConfig,
} = require("../webpack");
+const bothBuilds = (createConfigFunc, params) => [
+ createConfigFunc({ ...params, latestBuild: true }),
+ createConfigFunc({ ...params, latestBuild: false }),
+];
+
+const runDevServer = ({
+ compiler,
+ contentBase,
+ port,
+ listenHost = "localhost",
+}) =>
+ new WebpackDevServer(compiler, {
+ open: true,
+ watchContentBase: true,
+ contentBase,
+ }).listen(port, listenHost, function(err) {
+ if (err) {
+ throw err;
+ }
+ // Server listening
+ log("[webpack-dev-server]", `http://localhost:${port}`);
+ });
+
const handler = (done) => (err, stats) => {
if (err) {
console.log(err.stack || err);
@@ -32,20 +56,11 @@ const handler = (done) => (err, stats) => {
};
gulp.task("webpack-watch-app", () => {
- const compiler = webpack([
- createAppConfig({
- isProdBuild: false,
- latestBuild: true,
- isStatsBuild: false,
- }),
- createAppConfig({
- isProdBuild: false,
- latestBuild: false,
- isStatsBuild: false,
- }),
- ]);
- compiler.watch({}, handler());
// we are not calling done, so this command will run forever
+ webpack([bothBuilds(createAppConfig, { isProdBuild: false })]).watch(
+ {},
+ handler()
+ );
});
gulp.task(
@@ -53,47 +68,17 @@ gulp.task(
() =>
new Promise((resolve) =>
webpack(
- [
- createAppConfig({
- isProdBuild: true,
- latestBuild: true,
- isStatsBuild: false,
- }),
- createAppConfig({
- isProdBuild: true,
- latestBuild: false,
- isStatsBuild: false,
- }),
- ],
+ bothBuilds(createAppConfig, { isProdBuild: true }),
handler(resolve)
)
)
);
gulp.task("webpack-dev-server-demo", () => {
- const compiler = webpack([
- createDemoConfig({
- isProdBuild: false,
- latestBuild: false,
- isStatsBuild: false,
- }),
- createDemoConfig({
- isProdBuild: false,
- latestBuild: true,
- isStatsBuild: false,
- }),
- ]);
-
- new WebpackDevServer(compiler, {
- open: true,
- watchContentBase: true,
- contentBase: path.resolve(paths.demo_dir, "dist"),
- }).listen(8090, "localhost", function(err) {
- if (err) {
- throw err;
- }
- // Server listening
- log("[webpack-dev-server]", "http://localhost:8090");
+ runDevServer({
+ compiler: webpack(bothBuilds(createDemoConfig, { isProdBuild: false })),
+ contentBase: paths.demo_root,
+ port: 8090,
});
});
@@ -102,51 +87,22 @@ gulp.task(
() =>
new Promise((resolve) =>
webpack(
- [
- createDemoConfig({
- isProdBuild: true,
- latestBuild: false,
- isStatsBuild: false,
- }),
- createDemoConfig({
- isProdBuild: true,
- latestBuild: true,
- isStatsBuild: false,
- }),
- ],
+ bothBuilds(createDemoConfig, {
+ isProdBuild: true,
+ }),
handler(resolve)
)
)
);
gulp.task("webpack-dev-server-cast", () => {
- const compiler = webpack([
- createCastConfig({
- isProdBuild: false,
- latestBuild: false,
- }),
- createCastConfig({
- isProdBuild: false,
- latestBuild: true,
- }),
- ]);
-
- new WebpackDevServer(compiler, {
- open: true,
- watchContentBase: true,
- contentBase: path.resolve(paths.cast_dir, "dist"),
- }).listen(
- 8080,
+ runDevServer({
+ compiler: webpack(bothBuilds(createCastConfig, { isProdBuild: false })),
+ contentBase: paths.cast_root,
+ port: 8080,
// Accessible from the network, because that's how Cast hits it.
- "0.0.0.0",
- function(err) {
- if (err) {
- throw err;
- }
- // Server listening
- log("[webpack-dev-server]", "http://localhost:8080");
- }
- );
+ listenHost: "0.0.0.0",
+ });
});
gulp.task(
@@ -154,16 +110,59 @@ gulp.task(
() =>
new Promise((resolve) =>
webpack(
- [
- createCastConfig({
- isProdBuild: true,
- latestBuild: false,
- }),
- createCastConfig({
- isProdBuild: true,
- latestBuild: true,
- }),
- ],
+ bothBuilds(createCastConfig, {
+ isProdBuild: true,
+ }),
+
+ handler(resolve)
+ )
+ )
+);
+
+gulp.task("webpack-watch-hassio", () => {
+ // we are not calling done, so this command will run forever
+ webpack(
+ createHassioConfig({
+ isProdBuild: false,
+ latestBuild: false,
+ })
+ ).watch({}, handler());
+});
+
+gulp.task(
+ "webpack-prod-hassio",
+ () =>
+ new Promise((resolve) =>
+ webpack(
+ createHassioConfig({
+ isProdBuild: true,
+ latestBuild: false,
+ }),
+ handler(resolve)
+ )
+ )
+);
+
+gulp.task("webpack-dev-server-gallery", () => {
+ runDevServer({
+ compiler: webpack(
+ createGalleryConfig({ latestBuild: true, isProdBuild: false })
+ ),
+ contentBase: paths.gallery_root,
+ port: 8100,
+ });
+});
+
+gulp.task(
+ "webpack-prod-gallery",
+ () =>
+ new Promise((resolve) =>
+ webpack(
+ createGalleryConfig({
+ isProdBuild: true,
+ latestBuild: true,
+ }),
+
handler(resolve)
)
)
diff --git a/build-scripts/paths.js b/build-scripts/paths.js
index f59dc35399..4a26ab882c 100644
--- a/build-scripts/paths.js
+++ b/build-scripts/paths.js
@@ -20,4 +20,13 @@ module.exports = {
cast_static: path.resolve(__dirname, "../cast/dist/static"),
cast_output: path.resolve(__dirname, "../cast/dist/frontend_latest"),
cast_output_es5: path.resolve(__dirname, "../cast/dist/frontend_es5"),
+
+ gallery_dir: path.resolve(__dirname, "../gallery"),
+ gallery_root: path.resolve(__dirname, "../gallery/dist"),
+ gallery_output: path.resolve(__dirname, "../gallery/dist/frontend_latest"),
+ gallery_static: path.resolve(__dirname, "../gallery/dist/static"),
+
+ hassio_dir: path.resolve(__dirname, "../hassio"),
+ hassio_root: path.resolve(__dirname, "../hassio/build"),
+ hassio_publicPath: "/api/hassio/app",
};
diff --git a/build-scripts/webpack.js b/build-scripts/webpack.js
index bb69d91948..ac04587333 100644
--- a/build-scripts/webpack.js
+++ b/build-scripts/webpack.js
@@ -15,249 +15,246 @@ if (!version) {
}
version = version[0];
-const genMode = (isProdBuild) => (isProdBuild ? "production" : "development");
-const genDevTool = (isProdBuild) =>
- isProdBuild ? "source-map" : "inline-cheap-module-source-map";
-const genFilename = (isProdBuild, dontHash = new Set()) => ({ chunk }) => {
- if (!isProdBuild || dontHash.has(chunk.name)) {
- return `${chunk.name}.js`;
- }
- return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
-};
-const genChunkFilename = (isProdBuild, isStatsBuild) =>
- isProdBuild && !isStatsBuild ? "chunk.[chunkhash].js" : "[name].chunk.js";
-
-const resolve = {
- extensions: [".ts", ".js", ".json", ".tsx"],
- alias: {
- react: "preact-compat",
- "react-dom": "preact-compat",
- // Not necessary unless you consume a module using `createClass`
- "create-react-class": "preact-compat/lib/create-react-class",
- // Not necessary unless you consume a module requiring `react-dom-factories`
- "react-dom-factories": "preact-compat/lib/react-dom-factories",
- },
-};
-
-const cssLoader = {
- test: /\.css$/,
- use: "raw-loader",
-};
-const htmlLoader = {
- test: /\.(html)$/,
- use: {
- loader: "html-loader",
- options: {
- exportAsEs6Default: true,
- },
- },
-};
-
-const plugins = [
- // Ignore moment.js locales
- new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
- // Color.js is bloated, it contains all color definitions for all material color sets.
- new webpack.NormalModuleReplacementPlugin(
- /@polymer\/paper-styles\/color\.js$/,
- path.resolve(paths.polymer_dir, "src/util/empty.js")
- ),
- // Ignore roboto pointing at CDN. We use local font-roboto-local.
- new webpack.NormalModuleReplacementPlugin(
- /@polymer\/font-roboto\/roboto\.js$/,
- path.resolve(paths.polymer_dir, "src/util/empty.js")
- ),
- // Ignore mwc icons pointing at CDN.
- new webpack.NormalModuleReplacementPlugin(
- /@material\/mwc-icon\/mwc-icon-font\.js$/,
- path.resolve(paths.polymer_dir, "src/util/empty.js")
- ),
-];
-
-const optimization = (latestBuild) => ({
- minimizer: [
- new TerserPlugin({
- cache: true,
- parallel: true,
- extractComments: true,
- sourceMap: true,
- terserOptions: {
- safari10: true,
- ecma: latestBuild ? undefined : 5,
- },
- }),
- ],
-});
-
-const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
- const isCI = process.env.CI === "true";
-
- // Create an object mapping browser urls to their paths during build
- const translationMetadata = require("../build-translations/translationMetadata.json");
- const workBoxTranslationsTemplatedURLs = {};
- const englishFP = translationMetadata.translations.en.fingerprints;
- Object.keys(englishFP).forEach((key) => {
- workBoxTranslationsTemplatedURLs[
- `/static/translations/${englishFP[key]}`
- ] = `build-translations/output/${key}.json`;
- });
-
- const entry = {
- app: "./src/entrypoints/app.ts",
- authorize: "./src/entrypoints/authorize.ts",
- onboarding: "./src/entrypoints/onboarding.ts",
- core: "./src/entrypoints/core.ts",
- compatibility: "./src/entrypoints/compatibility.ts",
- "custom-panel": "./src/entrypoints/custom-panel.ts",
- "hass-icons": "./src/entrypoints/hass-icons.ts",
- };
-
+const createWebpackConfig = ({
+ entry,
+ outputRoot,
+ defineOverlay,
+ isProdBuild,
+ latestBuild,
+ isStatsBuild,
+}) => {
return {
- mode: genMode(isProdBuild),
- devtool: genDevTool(isProdBuild),
+ mode: isProdBuild ? "production" : "development",
+ devtool: isProdBuild ? "source-map" : "inline-cheap-module-source-map",
entry,
module: {
- rules: [babelLoaderConfig({ latestBuild }), cssLoader, htmlLoader],
+ rules: [
+ babelLoaderConfig({ latestBuild }),
+ {
+ test: /\.css$/,
+ use: "raw-loader",
+ },
+ {
+ test: /\.(html)$/,
+ use: {
+ loader: "html-loader",
+ options: {
+ exportAsEs6Default: true,
+ },
+ },
+ },
+ ],
+ },
+ optimization: {
+ minimizer: [
+ new TerserPlugin({
+ cache: true,
+ parallel: true,
+ extractComments: true,
+ sourceMap: true,
+ terserOptions: {
+ safari10: true,
+ ecma: latestBuild ? undefined : 5,
+ },
+ }),
+ ],
},
- optimization: optimization(latestBuild),
plugins: [
new ManifestPlugin(),
new webpack.DefinePlugin({
- __DEV__: JSON.stringify(!isProdBuild),
- __DEMO__: false,
+ __DEV__: !isProdBuild,
__BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
__VERSION__: JSON.stringify(version),
+ __DEMO__: false,
__STATIC_PATH__: "/static/",
"process.env.NODE_ENV": JSON.stringify(
isProdBuild ? "production" : "development"
),
+ ...defineOverlay,
}),
- ...plugins,
- latestBuild &&
- new WorkboxPlugin.InjectManifest({
- swSrc: "./src/entrypoints/service-worker-hass.js",
- swDest: "service_worker.js",
- importWorkboxFrom: "local",
- include: [/\.js$/],
- templatedURLs: {
- ...workBoxTranslationsTemplatedURLs,
- "/static/icons/favicon-192x192.png":
- "public/icons/favicon-192x192.png",
- "/static/fonts/roboto/Roboto-Light.woff2":
- "node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2",
- "/static/fonts/roboto/Roboto-Medium.woff2":
- "node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2",
- "/static/fonts/roboto/Roboto-Regular.woff2":
- "node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2",
- "/static/fonts/roboto/Roboto-Bold.woff2":
- "node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2",
- },
- }),
+ // Ignore moment.js locales
+ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
+ // Color.js is bloated, it contains all color definitions for all material color sets.
+ new webpack.NormalModuleReplacementPlugin(
+ /@polymer\/paper-styles\/color\.js$/,
+ path.resolve(paths.polymer_dir, "src/util/empty.js")
+ ),
+ // Ignore roboto pointing at CDN. We use local font-roboto-local.
+ new webpack.NormalModuleReplacementPlugin(
+ /@polymer\/font-roboto\/roboto\.js$/,
+ path.resolve(paths.polymer_dir, "src/util/empty.js")
+ ),
+ // Ignore mwc icons pointing at CDN.
+ new webpack.NormalModuleReplacementPlugin(
+ /@material\/mwc-icon\/mwc-icon-font\.js$/,
+ path.resolve(paths.polymer_dir, "src/util/empty.js")
+ ),
].filter(Boolean),
+ resolve: {
+ extensions: [".ts", ".js", ".json", ".tsx"],
+ alias: {
+ react: "preact-compat",
+ "react-dom": "preact-compat",
+ // Not necessary unless you consume a module using `createClass`
+ "create-react-class": "preact-compat/lib/create-react-class",
+ // Not necessary unless you consume a module requiring `react-dom-factories`
+ "react-dom-factories": "preact-compat/lib/react-dom-factories",
+ },
+ },
output: {
- filename: genFilename(isProdBuild),
- chunkFilename: genChunkFilename(isProdBuild, isStatsBuild),
- path: latestBuild ? paths.output : paths.output_es5,
+ filename: ({ chunk }) => {
+ const dontHash = new Set();
+
+ if (!isProdBuild || dontHash.has(chunk.name)) {
+ return `${chunk.name}.js`;
+ }
+ return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
+ },
+ chunkFilename:
+ isProdBuild && !isStatsBuild
+ ? "chunk.[chunkhash].js"
+ : "[name].chunk.js",
+ path: path.resolve(
+ outputRoot,
+ latestBuild ? "frontend_latest" : "frontend_es5"
+ ),
publicPath: latestBuild ? "/frontend_latest/" : "/frontend_es5/",
// For workerize loader
globalObject: "self",
},
- resolve,
};
};
+const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
+ const config = createWebpackConfig({
+ entry: {
+ app: "./src/entrypoints/app.ts",
+ authorize: "./src/entrypoints/authorize.ts",
+ onboarding: "./src/entrypoints/onboarding.ts",
+ core: "./src/entrypoints/core.ts",
+ compatibility: "./src/entrypoints/compatibility.ts",
+ "custom-panel": "./src/entrypoints/custom-panel.ts",
+ "hass-icons": "./src/entrypoints/hass-icons.ts",
+ },
+ outputRoot: paths.root,
+ isProdBuild,
+ latestBuild,
+ isStatsBuild,
+ });
+
+ if (latestBuild) {
+ // Create an object mapping browser urls to their paths during build
+ const translationMetadata = require("../build-translations/translationMetadata.json");
+ const workBoxTranslationsTemplatedURLs = {};
+ const englishFP = translationMetadata.translations.en.fingerprints;
+ Object.keys(englishFP).forEach((key) => {
+ workBoxTranslationsTemplatedURLs[
+ `/static/translations/${englishFP[key]}`
+ ] = `build-translations/output/${key}.json`;
+ });
+
+ config.plugins.push(
+ new WorkboxPlugin.InjectManifest({
+ swSrc: "./src/entrypoints/service-worker-hass.js",
+ swDest: "service_worker.js",
+ importWorkboxFrom: "local",
+ include: [/\.js$/],
+ templatedURLs: {
+ ...workBoxTranslationsTemplatedURLs,
+ "/static/icons/favicon-192x192.png":
+ "public/icons/favicon-192x192.png",
+ "/static/fonts/roboto/Roboto-Light.woff2":
+ "node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2",
+ "/static/fonts/roboto/Roboto-Medium.woff2":
+ "node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2",
+ "/static/fonts/roboto/Roboto-Regular.woff2":
+ "node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2",
+ "/static/fonts/roboto/Roboto-Bold.woff2":
+ "node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2",
+ },
+ })
+ );
+ }
+
+ return config;
+};
+
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
- return {
- mode: genMode(isProdBuild),
- devtool: genDevTool(isProdBuild),
+ return createWebpackConfig({
entry: {
- main: "./demo/src/entrypoint.ts",
- compatibility: "./src/entrypoints/compatibility.ts",
- },
- module: {
- rules: [babelLoaderConfig({ latestBuild }), cssLoader, htmlLoader],
- },
- optimization: optimization(latestBuild),
- plugins: [
- new ManifestPlugin(),
- new webpack.DefinePlugin({
- __DEV__: !isProdBuild,
- __BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
- __VERSION__: JSON.stringify(`DEMO-${version}`),
- __DEMO__: true,
- __STATIC_PATH__: "/static/",
- "process.env.NODE_ENV": JSON.stringify(
- isProdBuild ? "production" : "development"
- ),
- }),
- ...plugins,
- ].filter(Boolean),
- resolve,
- output: {
- filename: genFilename(isProdBuild),
- chunkFilename: genChunkFilename(isProdBuild, isStatsBuild),
- path: path.resolve(
- paths.demo_root,
- latestBuild ? "frontend_latest" : "frontend_es5"
+ main: path.resolve(paths.demo_dir, "src/entrypoint.ts"),
+ compatibility: path.resolve(
+ paths.polymer_dir,
+ "src/entrypoints/compatibility.ts"
),
- publicPath: latestBuild ? "/frontend_latest/" : "/frontend_es5/",
- // For workerize loader
- globalObject: "self",
},
- };
+ outputRoot: paths.demo_root,
+ defineOverlay: {
+ __VERSION__: JSON.stringify(`DEMO-${version}`),
+ __DEMO__: true,
+ },
+ isProdBuild,
+ latestBuild,
+ isStatsBuild,
+ });
};
const createCastConfig = ({ isProdBuild, latestBuild }) => {
- const isStatsBuild = false;
const entry = {
- launcher: "./cast/src/launcher/entrypoint.ts",
+ launcher: path.resolve(paths.cast_dir, "src/launcher/entrypoint.ts"),
};
if (latestBuild) {
- entry.receiver = "./cast/src/receiver/entrypoint.ts";
+ entry.receiver = path.resolve(paths.cast_dir, "src/receiver/entrypoint.ts");
}
- return {
- mode: genMode(isProdBuild),
- devtool: genDevTool(isProdBuild),
+ return createWebpackConfig({
entry,
- module: {
- rules: [babelLoaderConfig({ latestBuild }), cssLoader, htmlLoader],
+ outputRoot: paths.cast_root,
+ isProdBuild,
+ latestBuild,
+ });
+};
+
+const createHassioConfig = ({ isProdBuild, latestBuild }) => {
+ if (latestBuild) {
+ throw new Error("Hass.io does not support latest build!");
+ }
+ const config = createWebpackConfig({
+ entry: {
+ entrypoint: path.resolve(paths.hassio_dir, "src/entrypoint.js"),
},
- optimization: optimization(latestBuild),
- plugins: [
- new ManifestPlugin(),
- new webpack.DefinePlugin({
- __DEV__: !isProdBuild,
- __BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
- __VERSION__: JSON.stringify(version),
- __DEMO__: false,
- __STATIC_PATH__: "/static/",
- "process.env.NODE_ENV": JSON.stringify(
- isProdBuild ? "production" : "development"
- ),
- }),
- ...plugins,
- ].filter(Boolean),
- resolve,
- output: {
- filename: genFilename(isProdBuild),
- chunkFilename: genChunkFilename(isProdBuild, isStatsBuild),
- path: path.resolve(
- paths.cast_root,
- latestBuild ? "frontend_latest" : "frontend_es5"
- ),
- publicPath: latestBuild ? "/frontend_latest/" : "/frontend_es5/",
- // For workerize loader
- globalObject: "self",
+ outputRoot: "",
+ isProdBuild,
+ latestBuild,
+ });
+
+ config.output.path = paths.hassio_root;
+ config.output.publicPath = paths.hassio_publicPath;
+
+ return config;
+};
+
+const createGalleryConfig = ({ isProdBuild, latestBuild }) => {
+ if (!latestBuild) {
+ throw new Error("Gallery only supports latest build!");
+ }
+ const config = createWebpackConfig({
+ entry: {
+ entrypoint: path.resolve(paths.gallery_dir, "src/entrypoint.js"),
},
- };
+ outputRoot: paths.gallery_root,
+ isProdBuild,
+ latestBuild,
+ });
+
+ return config;
};
module.exports = {
- resolve,
- plugins,
- optimization,
createAppConfig,
createDemoConfig,
createCastConfig,
+ createHassioConfig,
+ createGalleryConfig,
};
diff --git a/cast/webpack.config.js b/cast/webpack.config.js
new file mode 100644
index 0000000000..bb9746cd11
--- /dev/null
+++ b/cast/webpack.config.js
@@ -0,0 +1,11 @@
+const { createCastConfig } = require("../build-scripts/webpack.js");
+const { isProdBuild } = require("../build-scripts/env.js");
+
+// File just used for stats builds
+
+const latestBuild = true;
+
+module.exports = createCastConfig({
+ isProdBuild,
+ latestBuild,
+});
diff --git a/demo/webpack.config.js b/demo/webpack.config.js
index 266523cdbe..9ccb790f8b 100644
--- a/demo/webpack.config.js
+++ b/demo/webpack.config.js
@@ -1,10 +1,9 @@
const { createDemoConfig } = require("../build-scripts/webpack.js");
+const { isProdBuild, isStatsBuild } = require("../build-scripts/env.js");
-// This file exists because we haven't migrated the stats script yet
+// File just used for stats builds
-const isProdBuild = process.env.NODE_ENV === "production";
-const isStatsBuild = process.env.STATS === "1";
-const latestBuild = false;
+const latestBuild = true;
module.exports = createDemoConfig({
isProdBuild,
diff --git a/gallery/public/index.html b/gallery/public/index.html
deleted file mode 100644
index 7339634a60..0000000000
--- a/gallery/public/index.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
- HAGallery
-
-
-
-
-
diff --git a/gallery/script/build_gallery b/gallery/script/build_gallery
index cbf70c6d4e..3a7c77dde7 100755
--- a/gallery/script/build_gallery
+++ b/gallery/script/build_gallery
@@ -4,14 +4,6 @@
# Stop on errors
set -e
-cd "$(dirname "$0")/.."
+cd "$(dirname "$0")/../.."
-OUTPUT_DIR=dist
-
-rm -rf $OUTPUT_DIR
-
-cd ..
-./node_modules/.bin/gulp build-translations gen-icons
-cd gallery
-
-NODE_ENV=production ../node_modules/.bin/webpack -p --config webpack.config.js
+./node_modules/.bin/gulp build-gallery
diff --git a/gallery/script/develop_gallery b/gallery/script/develop_gallery
index 56bb2c678b..b346ea60bc 100755
--- a/gallery/script/develop_gallery
+++ b/gallery/script/develop_gallery
@@ -4,10 +4,6 @@
# Stop on errors
set -e
-cd "$(dirname "$0")/.."
+cd "$(dirname "$0")/../.."
-cd ..
-./node_modules/.bin/gulp build-translations gen-icons
-cd gallery
-
-../node_modules/.bin/webpack-dev-server
+./node_modules/.bin/gulp develop-gallery
diff --git a/gallery/src/components/demo-cards.js b/gallery/src/components/demo-cards.js
index a73bc53a2f..db01c7fe13 100644
--- a/gallery/src/components/demo-cards.js
+++ b/gallery/src/components/demo-cards.js
@@ -26,7 +26,9 @@ class DemoCards extends PolymerElement {
- Show config
+
+ Show config
+
@@ -51,6 +53,10 @@ class DemoCards extends PolymerElement {
},
};
}
+
+ _showConfigToggled(ev) {
+ this._showConfig = ev.target.checked;
+ }
}
customElements.define("demo-cards", DemoCards);
diff --git a/gallery/src/html/index.html.template b/gallery/src/html/index.html.template
new file mode 100644
index 0000000000..3240e59bb0
--- /dev/null
+++ b/gallery/src/html/index.html.template
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
HAGallery
+
+
+
+
+
+
diff --git a/gallery/webpack.config.js b/gallery/webpack.config.js
index dc03993c98..9bc82eedc3 100644
--- a/gallery/webpack.config.js
+++ b/gallery/webpack.config.js
@@ -1,6 +1,6 @@
const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");
-const webpackBase = require("../build-scripts/webpack.js");
+const { createGalleryConfig } = require("../build-scripts/webpack.js");
const { babelLoaderConfig } = require("../build-scripts/babel.js");
const isProd = process.env.NODE_ENV === "production";
@@ -9,58 +9,64 @@ const buildPath = path.resolve(__dirname, "dist");
const publicPath = isProd ? "./" : "http://localhost:8080/";
const latestBuild = true;
-module.exports = {
- mode: isProd ? "production" : "development",
- // Disabled in prod while we make Home Assistant able to serve the right files.
- // Was source-map
- devtool: isProd ? "none" : "inline-source-map",
- entry: "./src/entrypoint.js",
- module: {
- rules: [
- babelLoaderConfig({ latestBuild }),
- {
- test: /\.css$/,
- use: "raw-loader",
- },
- {
- test: /\.(html)$/,
- use: {
- loader: "html-loader",
- options: {
- exportAsEs6Default: true,
+module.exports = createGalleryConfig({
+ latestBuild: true,
+});
+
+const bla = () => {
+ const oldExports = {
+ mode: isProd ? "production" : "development",
+ // Disabled in prod while we make Home Assistant able to serve the right files.
+ // Was source-map
+ devtool: isProd ? "none" : "inline-source-map",
+ entry: "./src/entrypoint.js",
+ module: {
+ rules: [
+ babelLoaderConfig({ latestBuild }),
+ {
+ test: /\.css$/,
+ use: "raw-loader",
+ },
+ {
+ test: /\.(html)$/,
+ use: {
+ loader: "html-loader",
+ options: {
+ exportAsEs6Default: true,
+ },
},
},
- },
- ],
- },
- optimization: webpackBase.optimization(latestBuild),
- plugins: [
- new CopyWebpackPlugin([
- "public",
- { from: "../public", to: "static" },
- { from: "../build-translations/output", to: "static/translations" },
- {
- from: "../node_modules/leaflet/dist/leaflet.css",
- to: "static/images/leaflet/",
- },
- {
- from: "../node_modules/roboto-fontface/fonts/roboto/*.woff2",
- to: "static/fonts/roboto/",
- },
- {
- from: "../node_modules/leaflet/dist/images",
- to: "static/images/leaflet/",
- },
- ]),
- ].filter(Boolean),
- resolve: webpackBase.resolve,
- output: {
- filename: "[name].js",
- chunkFilename: chunkFilename,
- path: buildPath,
- publicPath,
- },
- devServer: {
- contentBase: "./public",
- },
+ ],
+ },
+ optimization: webpackBase.optimization(latestBuild),
+ plugins: [
+ new CopyWebpackPlugin([
+ "public",
+ { from: "../public", to: "static" },
+ { from: "../build-translations/output", to: "static/translations" },
+ {
+ from: "../node_modules/leaflet/dist/leaflet.css",
+ to: "static/images/leaflet/",
+ },
+ {
+ from: "../node_modules/roboto-fontface/fonts/roboto/*.woff2",
+ to: "static/fonts/roboto/",
+ },
+ {
+ from: "../node_modules/leaflet/dist/images",
+ to: "static/images/leaflet/",
+ },
+ ]),
+ ].filter(Boolean),
+ resolve: webpackBase.resolve,
+ output: {
+ filename: "[name].js",
+ chunkFilename: chunkFilename,
+ path: buildPath,
+ publicPath,
+ },
+ devServer: {
+ contentBase: "./public",
+ },
+ };
};
diff --git a/hassio/script/build_hassio b/hassio/script/build_hassio
index b8bd6d504e..193cbb0687 100755
--- a/hassio/script/build_hassio
+++ b/hassio/script/build_hassio
@@ -4,11 +4,6 @@
# Stop on errors
set -e
-cd "$(dirname "$0")/.."
+cd "$(dirname "$0")/../.."
-OUTPUT_DIR=build
-
-rm -rf $OUTPUT_DIR
-
-node script/gen-icons.js
-NODE_ENV=production CI=false ../node_modules/.bin/webpack -p --config webpack.config.js
+./node_modules/.bin/gulp build-hassio
diff --git a/hassio/script/develop b/hassio/script/develop
index c23fc2ea1f..0b62666b10 100755
--- a/hassio/script/develop
+++ b/hassio/script/develop
@@ -4,11 +4,6 @@
# Stop on errors
set -e
-cd "$(dirname "$0")/.."
+cd "$(dirname "$0")/../.."
-OUTPUT_DIR=build
-
-rm -rf $OUTPUT_DIR
-mkdir $OUTPUT_DIR
-node script/gen-icons.js
-../node_modules/.bin/webpack --watch --progress
+./node_modules/.bin/gulp develop-hassio
diff --git a/hassio/script/gen-icons.js b/hassio/script/gen-icons.js
deleted file mode 100755
index b355ef752b..0000000000
--- a/hassio/script/gen-icons.js
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env node
-const fs = require("fs");
-const {
- findIcons,
- generateIconset,
- genMDIIcons,
-} = require("../../build-scripts/gulp/gen-icons.js");
-
-function genHassioIcons() {
- const iconNames = findIcons("./src", "hassio");
-
- for (const item of findIcons("../src", "hassio")) {
- iconNames.add(item);
- }
-
- fs.writeFileSync("./hassio-icons.html", generateIconset("hassio", iconNames));
-}
-
-genMDIIcons();
-genHassioIcons();
diff --git a/hassio/webpack.config.js b/hassio/webpack.config.js
index 630778c69e..02e44c0d74 100644
--- a/hassio/webpack.config.js
+++ b/hassio/webpack.config.js
@@ -1,63 +1,11 @@
-const webpack = require("webpack");
-const CompressionPlugin = require("compression-webpack-plugin");
-const zopfli = require("@gfx/zopfli");
+const { createHassioConfig } = require("../build-scripts/webpack.js");
+const { isProdBuild } = require("../build-scripts/env.js");
-const config = require("./config.js");
-const webpackBase = require("../build-scripts/webpack.js");
-const { babelLoaderConfig } = require("../build-scripts/babel.js");
+// File just used for stats builds
-const isProdBuild = process.env.NODE_ENV === "production";
-const isCI = process.env.CI === "true";
-const chunkFilename = isProdBuild ? "chunk.[chunkhash].js" : "[name].chunk.js";
const latestBuild = false;
-module.exports = {
- mode: isProdBuild ? "production" : "development",
- devtool: isProdBuild ? "source-map" : "inline-source-map",
- entry: {
- entrypoint: "./src/entrypoint.js",
- },
- module: {
- rules: [
- babelLoaderConfig({ latestBuild }),
- {
- test: /\.(html)$/,
- use: {
- loader: "html-loader",
- options: {
- exportAsEs6Default: true,
- },
- },
- },
- ],
- },
- optimization: webpackBase.optimization(latestBuild),
- plugins: [
- new webpack.DefinePlugin({
- __DEV__: JSON.stringify(!isProdBuild),
- __DEMO__: false,
- __BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
- "process.env.NODE_ENV": JSON.stringify(
- isProdBuild ? "production" : "development"
- ),
- }),
- isProdBuild &&
- !isCI &&
- new CompressionPlugin({
- cache: true,
- exclude: [/\.js\.map$/, /\.LICENSE$/, /\.py$/, /\.txt$/],
- algorithm(input, compressionOptions, callback) {
- return zopfli.gzip(input, compressionOptions, callback);
- },
- }),
- ].filter(Boolean),
- resolve: {
- extensions: [".ts", ".js", ".json"],
- },
- output: {
- filename: "[name].js",
- chunkFilename,
- path: config.buildDir,
- publicPath: `${config.publicPath}/`,
- },
-};
+module.exports = createHassioConfig({
+ isProdBuild,
+ latestBuild,
+});
diff --git a/webpack.config.js b/webpack.config.js
index 49df18dfec..ff1b7462be 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,10 +1,8 @@
const { createAppConfig } = require("./build-scripts/webpack.js");
+const { isProdBuild, isStatsBuild } = require("./build-scripts/env.js");
// This file exists because we haven't migrated the stats script yet
-const isProdBuild = process.env.NODE_ENV === "production";
-const isStatsBuild = process.env.STATS === "1";
-
const configs = [
createAppConfig({
isProdBuild,