diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d03778e6dc..f61aa3306b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -85,6 +85,12 @@ jobs: run: ./node_modules/.bin/gulp build-app env: IS_TEST: "true" + - name: Upload bundle stats + uses: actions/upload-artifact@v3.1.3 + with: + name: frontend-bundle-stats + path: build/stats/*.json + if-no-files-found: error supervisor: name: Build supervisor needs: [lint, test] @@ -103,3 +109,9 @@ jobs: run: ./node_modules/.bin/gulp build-hassio env: IS_TEST: "true" + - name: Upload bundle stats + uses: actions/upload-artifact@v3.1.3 + with: + name: supervisor-bundle-stats + path: build/stats/*.json + if-no-files-found: error diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 1316a20f7d..98d3e876fe 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -57,14 +57,14 @@ jobs: run: tar -czvf translations.tar.gz translations - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v3.1.3 with: name: wheels path: dist/home_assistant_frontend*.whl if-no-files-found: error - name: Upload translations - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v3.1.3 with: name: translations path: translations.tar.gz diff --git a/.github/workflows/relative-ci.yaml b/.github/workflows/relative-ci.yaml new file mode 100644 index 0000000000..3ccade78bb --- /dev/null +++ b/.github/workflows/relative-ci.yaml @@ -0,0 +1,28 @@ +name: RelativeCI + +on: + workflow_run: + workflows: [CI] + types: + - completed + branches: + - dev + +jobs: + upload: + name: Upload stats + if: ${{ github.event.workflow_run.conclusion == 'success' }} + strategy: + matrix: + bundle: [frontend, supervisor] + build: [modern, legacy] + runs-on: ubuntu-latest + steps: + - name: Send bundle stats and build information to RelativeCI + uses: relative-ci/agent-action@v2.1.8 + with: + key: ${{ secrets[format('RELATIVE_CI_KEY_{1}_{2}', matrix.bundle, matrix.build)] }} + token: ${{ github.token }} + slug: ${{ format('{1}-{2}', matrix.bundle, matrix.build) }} + artifactName: ${{ format('{1}-bundle-stats', matrix.bundle) }} + artifactWebpackStatsFile: ${{ format('{1}-{2}.json', matrix.bundle, matrix.build) }} diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index b359a07374..aa84af365c 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -149,7 +149,7 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ sourceMaps: !isTestBuild, }); -const nameSuffix = (latestBuild) => (latestBuild ? "-latest" : "-es5"); +const nameSuffix = (latestBuild) => (latestBuild ? "-modern" : "-legacy"); const outputPath = (outputRoot, latestBuild) => path.resolve(outputRoot, latestBuild ? "frontend_latest" : "frontend_es5"); @@ -183,7 +183,7 @@ const publicPath = (latestBuild, root = "") => module.exports.config = { app({ isProdBuild, latestBuild, isStatsBuild, isTestBuild, isWDS }) { return { - name: "app" + nameSuffix(latestBuild), + name: "frontend" + nameSuffix(latestBuild), entry: { service_worker: "./src/entrypoints/service_worker.ts", app: "./src/entrypoints/app.ts", diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs index 769dd58a12..5997e59d58 100644 --- a/build-scripts/webpack.cjs +++ b/build-scripts/webpack.cjs @@ -1,6 +1,8 @@ const { existsSync } = require("fs"); const path = require("path"); const webpack = require("webpack"); +const { StatsWriterPlugin } = require("webpack-stats-plugin"); +const filterStats = require("@bundle-stats/plugin-webpack-filter").default; const TerserPlugin = require("terser-webpack-plugin"); const { WebpackManifestPlugin } = require("webpack-manifest-plugin"); const log = require("fancy-log"); @@ -152,6 +154,15 @@ const createWebpackConfig = ({ ) ), !isProdBuild && new LogStartCompilePlugin(), + isProdBuild && + new StatsWriterPlugin({ + filename: path.relative( + outputPath, + path.join(paths.build_dir, "stats", `${name}.json`) + ), + stats: { assets: true, chunks: true, modules: true }, + transform: (stats) => JSON.stringify(filterStats(stats)), + }), ].filter(Boolean), resolve: { extensions: [".ts", ".js", ".json"], diff --git a/package.json b/package.json index 633ac8ba8c..24b209ef96 100644 --- a/package.json +++ b/package.json @@ -159,6 +159,7 @@ "@babel/plugin-transform-runtime": "7.22.15", "@babel/preset-env": "7.22.20", "@babel/preset-typescript": "7.23.0", + "@bundle-stats/plugin-webpack-filter": "4.7.6", "@koa/cors": "4.0.0", "@lokalise/node-api": "12.0.0", "@octokit/auth-oauth-device": "6.0.1", @@ -248,6 +249,7 @@ "webpack-cli": "5.1.4", "webpack-dev-server": "4.15.1", "webpack-manifest-plugin": "5.0.0", + "webpack-stats-plugin": "1.1.3", "webpackbar": "5.0.2", "workbox-build": "7.0.0" }, diff --git a/yarn.lock b/yarn.lock index 147f9a3f3a..19c16fe853 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1437,6 +1437,15 @@ __metadata: languageName: node linkType: hard +"@bundle-stats/plugin-webpack-filter@npm:4.7.6": + version: 4.7.6 + resolution: "@bundle-stats/plugin-webpack-filter@npm:4.7.6" + peerDependencies: + core-js: ^3.0.0 + checksum: a7bb72f6222dc8ec06c923d93772c2569885fbeb127d5a7df3e0c88b4f23b7ec7d92ae5525b5ede6a81b00416c8d3a18a00d7637990f51afc1fc0a284d275426 + languageName: node + linkType: hard + "@codemirror/autocomplete@npm:6.9.2": version: 6.9.2 resolution: "@codemirror/autocomplete@npm:6.9.2" @@ -9634,6 +9643,7 @@ __metadata: "@babel/preset-typescript": 7.23.0 "@babel/runtime": 7.23.1 "@braintree/sanitize-url": 6.0.4 + "@bundle-stats/plugin-webpack-filter": 4.7.6 "@codemirror/autocomplete": 6.9.2 "@codemirror/commands": 6.3.0 "@codemirror/language": 6.9.1 @@ -9840,6 +9850,7 @@ __metadata: webpack-cli: 5.1.4 webpack-dev-server: 4.15.1 webpack-manifest-plugin: 5.0.0 + webpack-stats-plugin: 1.1.3 webpackbar: 5.0.2 weekstart: 2.0.0 workbox-build: 7.0.0 @@ -16335,6 +16346,13 @@ __metadata: languageName: node linkType: hard +"webpack-stats-plugin@npm:1.1.3": + version: 1.1.3 + resolution: "webpack-stats-plugin@npm:1.1.3" + checksum: 9a71d329c5d55e33105abfe4c72d715a0a6ce4ab8da6faa2bc5a65953915d656cdf3c420b3fc0628b0d9859cc59c09e49f731645746739e417da531130a7a9a8 + languageName: node + linkType: hard + "webpack@npm:5.88.2": version: 5.88.2 resolution: "webpack@npm:5.88.2"