From a09715173a5b25d66c0ad4deb70f9fcc146f6597 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Sep 2023 20:29:28 +0200 Subject: [PATCH] cli: make repo fix also add sideEffects: false Signed-off-by: Patrik Oldsberg --- .changeset/funny-timers-retire.md | 2 +- packages/cli/src/commands/repo/fix.ts | 35 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.changeset/funny-timers-retire.md b/.changeset/funny-timers-retire.md index cee28b5b12..87cd4d8f0d 100644 --- a/.changeset/funny-timers-retire.md +++ b/.changeset/funny-timers-retire.md @@ -2,4 +2,4 @@ '@backstage/cli': patch --- -Added a new `repo fix` command that fixes auto-fixable problems in all packages. +Added a new `repo fix` command that fixes auto-fixable problems in all packages. Initially the command fixes package export declarations, as well as marks all non-bundled frontend packages as side-effect free. Marking packages as free of side-effects can drastically reduce the Webpack bundle size. diff --git a/packages/cli/src/commands/repo/fix.ts b/packages/cli/src/commands/repo/fix.ts index 75306f226c..bd5b375ed5 100644 --- a/packages/cli/src/commands/repo/fix.ts +++ b/packages/cli/src/commands/repo/fix.ts @@ -18,6 +18,7 @@ import { BackstagePackage, BackstagePackageJson, PackageGraph, + PackageRoles, } from '@backstage/cli-node'; import { OptionValues } from 'commander'; import fs from 'fs-extra'; @@ -155,11 +156,45 @@ export function fixPackageExports(pkg: FixablePackage) { } } +export function fixSideEffects(pkg: FixablePackage) { + const role = PackageRoles.getRoleFromPackage(pkg.packageJson); + if (!role) { + return; + } + + const roleInfo = PackageRoles.getRoleInfo(role); + + // Only web and common packages benefit from being marked as side effect free + if (roleInfo.platform === 'node') { + return; + } + // Bundled packages don't need to mark themselves as having no side effects + if (roleInfo.output.length === 1 && roleInfo.output[0] === 'bundle') { + return; + } + + // Already declared + if ('sideEffects' in pkg.packageJson) { + return; + } + + const pkgEntries = Object.entries(pkg.packageJson); + pkgEntries.splice( + // Place it just above the scripts field + pkgEntries.findIndex(([name]) => name === 'scripts'), + 0, + ['sideEffects', false], + ); + pkg.packageJson = Object.fromEntries(pkgEntries) as BackstagePackageJson; + pkg.changed = true; +} + export async function command(opts: OptionValues): Promise { const packages = await readFixablePackages(); for (const pkg of packages) { fixPackageExports(pkg); + fixSideEffects(pkg); } if (opts.check) {