diff --git a/.changes/web-version-only-from-package-json.md b/.changes/web-version-only-from-package-json.md new file mode 100644 index 000000000..3cecf7190 --- /dev/null +++ b/.changes/web-version-only-from-package-json.md @@ -0,0 +1,7 @@ +--- +type: perf +area: web +--- + +The app no longer ships its whole `package.json` inside the startup bundle, +only its version number, which trims about 11 KB from every launch. diff --git a/apps/web/jest.config.ts b/apps/web/jest.config.ts index 15277199e..6fb90a9a1 100644 --- a/apps/web/jest.config.ts +++ b/apps/web/jest.config.ts @@ -39,6 +39,7 @@ export default { tslib: 'tslib/tslib.es6.js', '^iptv-playlist-parser$': '/src/test-stubs/iptv-playlist-parser.mjs', + '^@package$': '/src/test-stubs/package.mjs', '^shaka-player$': '/src/test-stubs/shaka-player.js', '^video.js$': '/src/test-stubs/video-js.js', '^rxjs': '/../../node_modules/rxjs/dist/bundles/rxjs.umd.js', diff --git a/apps/web/src/environments/environment.dev.ts b/apps/web/src/environments/environment.dev.ts index f176f814a..24edf3e91 100644 --- a/apps/web/src/environments/environment.dev.ts +++ b/apps/web/src/environments/environment.dev.ts @@ -3,11 +3,11 @@ // `ng build --env=prod` then `index.prod.ts` will be used instead. // The list of which env maps to which file can be found in `.angular-cli.json`. -import packageJson from '@package'; +import { version as appVersion } from '@package'; export const AppConfig = { production: false, environment: 'DEV', - version: packageJson.version, + version: appVersion, BACKEND_URL: 'http://localhost:3000', }; diff --git a/apps/web/src/environments/environment.prod.ts b/apps/web/src/environments/environment.prod.ts index 87f4284ef..f0e2a57d0 100644 --- a/apps/web/src/environments/environment.prod.ts +++ b/apps/web/src/environments/environment.prod.ts @@ -1,8 +1,8 @@ -import packageJson from '@package'; +import { version as appVersion } from '@package'; export const AppConfig = { production: true, environment: 'PROD', - version: packageJson.version, + version: appVersion, BACKEND_URL: 'https://iptvnator-playlist-parser-api.vercel.app', }; diff --git a/apps/web/src/environments/environment.ts b/apps/web/src/environments/environment.ts index 0790b2105..92988b7ba 100644 --- a/apps/web/src/environments/environment.ts +++ b/apps/web/src/environments/environment.ts @@ -1,8 +1,8 @@ -import packageJson from '@package'; +import { version as appVersion } from '@package'; export const AppConfig = { production: false, environment: 'LOCAL', - version: packageJson.version, + version: appVersion, BACKEND_URL: 'http://localhost:3000', }; diff --git a/apps/web/src/environments/environment.web.ts b/apps/web/src/environments/environment.web.ts index 688520218..6b85ff494 100644 --- a/apps/web/src/environments/environment.web.ts +++ b/apps/web/src/environments/environment.web.ts @@ -1,8 +1,8 @@ -import packageJson from '@package'; +import { version as appVersion } from '@package'; export const AppConfig = { production: false, environment: 'WEB', - version: packageJson.version, + version: appVersion, BACKEND_URL: 'http://localhost:3333', }; diff --git a/apps/web/src/test-stubs/package.mjs b/apps/web/src/test-stubs/package.mjs new file mode 100644 index 000000000..04f30e1f5 --- /dev/null +++ b/apps/web/src/test-stubs/package.mjs @@ -0,0 +1,12 @@ +// Jest's ESM loader exposes a JSON module only as a default export, while the +// app imports `{ version }` from '@package' so esbuild can tree-shake the rest +// of package.json out of the bundle. This stub serves the real file's fields +// as named exports for tests. +import { readFileSync } from 'node:fs'; + +const packageJson = JSON.parse( + readFileSync(new URL('../../../../package.json', import.meta.url), 'utf8') +); + +export const version = packageJson.version; +export default packageJson; diff --git a/docs/architecture/performance-journeys.md b/docs/architecture/performance-journeys.md index 4e1a35629..e2352362b 100644 --- a/docs/architecture/performance-journeys.md +++ b/docs/architecture/performance-journeys.md @@ -38,7 +38,9 @@ error, never zero bytes. The value is raw (uncompressed) size, which is what the renderer parses. It is Angular's "Initial total" plus `index.html` and `assets/app-config.js` (about 4 KB together), so it sits slightly above the rounded figure the build prints; never copy that figure into a baseline, use -the script's output. +the script's output. The bundle embeds only the app version from +`package.json` (a named import, which esbuild tree-shakes), not the whole +file, so editing scripts or dependencies does not move the counter. ```bash pnpm nx build web # production configuration diff --git a/jest.web-esm.workspace.ts b/jest.web-esm.workspace.ts index ed6badaa6..c0b3f992e 100644 --- a/jest.web-esm.workspace.ts +++ b/jest.web-esm.workspace.ts @@ -37,6 +37,7 @@ export default { tslib: 'tslib/tslib.es6.js', '^iptv-playlist-parser$': '/apps/web/src/test-stubs/iptv-playlist-parser.mjs', + '^@package$': '/apps/web/src/test-stubs/package.mjs', '^shaka-player$': '/apps/web/src/test-stubs/shaka-player.js', '^rxjs': '/node_modules/rxjs/dist/bundles/rxjs.umd.js', '^uuid$': '/node_modules/uuid/wrapper.mjs', diff --git a/libs/ui/playback/src/lib/playback-diagnostic-panel/playback-diagnostic-panel.component.ts b/libs/ui/playback/src/lib/playback-diagnostic-panel/playback-diagnostic-panel.component.ts index ff1bc5f6e..ba573007d 100644 --- a/libs/ui/playback/src/lib/playback-diagnostic-panel/playback-diagnostic-panel.component.ts +++ b/libs/ui/playback/src/lib/playback-diagnostic-panel/playback-diagnostic-panel.component.ts @@ -1,5 +1,5 @@ import { DOCUMENT } from '@angular/common'; -import packageJson from '@package'; +import { version as appVersion } from '@package'; import { createDiagnosticReport } from './playback-diagnostic-report.util'; import { ClipboardModule } from '@angular/cdk/clipboard'; import { @@ -91,7 +91,7 @@ export class PlaybackDiagnosticPanelComponent { readonly diagnosticReport = computed(() => createDiagnosticReport( this.diagnostic(), - packageJson.version, + appVersion, this.document.defaultView?.navigator.userAgent ?? '' ) );