From 92b0e1216fad2c6209b6c2fedbd21b0faf7a4a39 Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Tue, 26 Apr 2022 15:35:23 -0500 Subject: [PATCH 01/11] chore: add optional size.limit configuration option --- plugins/size/src/interfaces.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/size/src/interfaces.ts b/plugins/size/src/interfaces.ts index e62262cee..4792de2ad 100644 --- a/plugins/size/src/interfaces.ts +++ b/plugins/size/src/interfaces.ts @@ -19,6 +19,8 @@ export interface SizeArgs { ignore?: string[] /** The registry to install packages from */ registry?: string + /** Size limit failure threshold */ + limit?: number /** Size Failure Threshold */ failureThreshold?: number /** Run the plugin against merge base. (Will be slower due to additional build process) */ From 7cc56a7b9f6b134721c8910638382231d2ec7468 Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Tue, 26 Apr 2022 15:36:48 -0500 Subject: [PATCH 02/11] feat: add functional support for size.limit option --- plugins/size/src/index.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/size/src/index.ts b/plugins/size/src/index.ts index 159f06e64..37b0e773a 100644 --- a/plugins/size/src/index.ts +++ b/plugins/size/src/index.ts @@ -87,9 +87,15 @@ export default class SizePlugin implements Plugin { }); const header = args.css ? cssHeader : defaultHeader; + const underFailureThreshold = size && + size.percent <= FAILURE_THRESHOLD || + size.percent === Infinity; + const underSizeLimit = args.limit ? size.pr.js + size.pr.css <= args.limit : true; + const success = underFailureThreshold && underSizeLimit; + await reportResults( name, - size.percent <= FAILURE_THRESHOLD || size.percent === Infinity, + success, Boolean(args.comment), table( args.detailed @@ -107,7 +113,7 @@ export default class SizePlugin implements Plugin { createDiff(); } - if (size && size.percent > FAILURE_THRESHOLD && size.percent !== Infinity) { + if (!success) { process.exit(1); } } From 9be9f5b8ed82d3aecfaff67cd62290d076c8e01c Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Thu, 28 Apr 2022 09:34:08 -0500 Subject: [PATCH 03/11] chore: extract package loading to BuildUtils --- plugins/size/src/utils/BuildUtils.ts | 43 ++++++++++++++++++++++++-- plugins/size/src/utils/WebpackUtils.ts | 38 ++--------------------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/plugins/size/src/utils/BuildUtils.ts b/plugins/size/src/utils/BuildUtils.ts index 1e5425ae6..92a7d1bf7 100644 --- a/plugins/size/src/utils/BuildUtils.ts +++ b/plugins/size/src/utils/BuildUtils.ts @@ -1,7 +1,10 @@ -import { execSync } from 'child_process'; +import { execSync, ExecSyncOptions } from 'child_process'; import os from 'os'; import path from 'path'; -import { getMonorepoRoot, createLogger } from '@design-systems/cli-utils'; +import fs from 'fs-extra'; +import { getMonorepoRoot, createLogger, getLogLevel } from '@design-systems/cli-utils'; +import { mockPackage } from './CalcSizeUtils'; +import { GetSizesOptions, CommonOptions } from '../interfaces'; const logger = createLogger({ scope: 'size' }); @@ -54,3 +57,39 @@ export function getLocalPackage( return path.join(local, path.relative(getMonorepoRoot(), pkg.location)); } + +/** Install package to tmp dir */ +export async function loadPackage(options: GetSizesOptions & CommonOptions) { + const dir = mockPackage(); + const execOptions: ExecSyncOptions = { + cwd: dir, + stdio: getLogLevel() === 'trace' ? 'inherit' : 'ignore' + }; + try { + const browsersList = path.join(getMonorepoRoot(), '.browserslistrc'); + if (fs.existsSync(browsersList)) { + fs.copyFileSync(browsersList, path.join(dir, '.browserslistrc')); + } + + const npmrc = path.join(getMonorepoRoot(), '.npmrc'); + if (options.registry && fs.existsSync(npmrc)) { + fs.copyFileSync(npmrc, path.join(dir, '.npmrc')); + } + + logger.debug(`Installing: ${options.name}`); + if (options.registry) { + execSync( + `yarn add ${options.name} --registry ${options.registry}`, + execOptions + ); + } else { + execSync(`yarn add ${options.name}`, execOptions); + } + } catch (error) { + logger.debug(error); + logger.warn(`Could not find package ${options.name}...`); + return []; + } + + return dir; +} diff --git a/plugins/size/src/utils/WebpackUtils.ts b/plugins/size/src/utils/WebpackUtils.ts index 1b8f4bb7c..0cce43473 100644 --- a/plugins/size/src/utils/WebpackUtils.ts +++ b/plugins/size/src/utils/WebpackUtils.ts @@ -9,13 +9,11 @@ import Terser from 'terser-webpack-plugin'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin'; import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; -import { getMonorepoRoot, getLogLevel } from '@design-systems/cli-utils'; -import { execSync, ExecSyncOptions } from 'child_process'; +import { execSync } from 'child_process'; import RelativeCommentsPlugin from '../RelativeCommentsPlugin'; import { fromEntries } from './formatUtils'; import { ConfigOptions, GetSizesOptions, CommonOptions } from '../interfaces'; -import { mockPackage } from './CalcSizeUtils'; -import { getLocalPackage } from './BuildUtils'; +import { getLocalPackage, loadPackage } from './BuildUtils'; const logger = createLogger({ scope: 'size' }); @@ -163,37 +161,7 @@ async function runWebpack(config: webpack.Configuration): Promise /** Install package to tmp dir and run webpack on it to calculate size. */ async function getSizes(options: GetSizesOptions & CommonOptions) { - const dir = mockPackage(); - const execOptions: ExecSyncOptions = { - cwd: dir, - stdio: getLogLevel() === 'trace' ? 'inherit' : 'ignore' - }; - try { - const browsersList = path.join(getMonorepoRoot(), '.browserslistrc'); - if (fs.existsSync(browsersList)) { - fs.copyFileSync(browsersList, path.join(dir, '.browserslistrc')); - } - - const npmrc = path.join(getMonorepoRoot(), '.npmrc'); - if (options.registry && fs.existsSync(npmrc)) { - fs.copyFileSync(npmrc, path.join(dir, '.npmrc')); - } - - logger.debug(`Installing: ${options.name}`); - if (options.registry) { - execSync( - `yarn add ${options.name} --registry ${options.registry}`, - execOptions - ); - } else { - execSync(`yarn add ${options.name}`, execOptions); - } - } catch (error) { - logger.debug(error); - logger.warn(`Could not find package ${options.name}...`); - return []; - } - + const dir = await loadPackage(options); const result = await runWebpack( await config({ dir, From 2cb557d43a5f62afb312b9191b00d240169e06fa Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Thu, 28 Apr 2022 09:57:35 -0500 Subject: [PATCH 04/11] chore: elevate package src loading to analysis layer --- plugins/size/src/interfaces.ts | 9 +++++++++ plugins/size/src/utils/BuildUtils.ts | 4 ++-- plugins/size/src/utils/CalcSizeUtils.ts | 13 ++++++++++--- plugins/size/src/utils/WebpackUtils.ts | 25 ++++++++++++++----------- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/plugins/size/src/interfaces.ts b/plugins/size/src/interfaces.ts index 4792de2ad..c31c3112c 100644 --- a/plugins/size/src/interfaces.ts +++ b/plugins/size/src/interfaces.ts @@ -90,6 +90,15 @@ export interface GetSizesOptions extends CommonCalcSizeOptions { analyze?: boolean /** What port to start the analyzer on */ analyzerPort?: number + /** Working directory to execute analysis from */ + dir: string +} + +export interface LoadPackageOptions { + /** The name of the package to get size for */ + name: string + /** The registry to install packages from */ + registry?: string } type Scope = 'pr' | 'master' diff --git a/plugins/size/src/utils/BuildUtils.ts b/plugins/size/src/utils/BuildUtils.ts index 92a7d1bf7..166372d39 100644 --- a/plugins/size/src/utils/BuildUtils.ts +++ b/plugins/size/src/utils/BuildUtils.ts @@ -4,7 +4,7 @@ import path from 'path'; import fs from 'fs-extra'; import { getMonorepoRoot, createLogger, getLogLevel } from '@design-systems/cli-utils'; import { mockPackage } from './CalcSizeUtils'; -import { GetSizesOptions, CommonOptions } from '../interfaces'; +import { LoadPackageOptions } from '../interfaces'; const logger = createLogger({ scope: 'size' }); @@ -59,7 +59,7 @@ export function getLocalPackage( } /** Install package to tmp dir */ -export async function loadPackage(options: GetSizesOptions & CommonOptions) { +export async function loadPackage(options: LoadPackageOptions) { const dir = mockPackage(); const execOptions: ExecSyncOptions = { cwd: dir, diff --git a/plugins/size/src/utils/CalcSizeUtils.ts b/plugins/size/src/utils/CalcSizeUtils.ts index adb0f21b5..df21a5e1c 100644 --- a/plugins/size/src/utils/CalcSizeUtils.ts +++ b/plugins/size/src/utils/CalcSizeUtils.ts @@ -20,7 +20,7 @@ import { DiffSizeForPackageOptions } from '../interfaces'; import { getSizes } from './WebpackUtils'; -import { getLocalPackage } from './BuildUtils'; +import { getLocalPackage, loadPackage } from './BuildUtils'; const RUNTIME_SIZE = 537; @@ -50,15 +50,22 @@ async function calcSizeForPackage({ registry, local }: CommonOptions & CommonCalcSizeOptions): Promise { + const packageName = local ? getLocalPackage(importName, local) : name; + const dir = await loadPackage({ + name: packageName, + registry + }); const sizes = await getSizes({ - name: local ? getLocalPackage(importName, local) : name, + name: packageName, importName, scope, persist, chunkByExport, diff, - registry + registry, + dir }); + fs.removeSync(dir); const js = sizes.filter((size) => !size.chunkNames.includes('css')); const css = sizes.filter((size) => size.chunkNames.includes('css')); diff --git a/plugins/size/src/utils/WebpackUtils.ts b/plugins/size/src/utils/WebpackUtils.ts index 0cce43473..d49f62317 100644 --- a/plugins/size/src/utils/WebpackUtils.ts +++ b/plugins/size/src/utils/WebpackUtils.ts @@ -161,20 +161,16 @@ async function runWebpack(config: webpack.Configuration): Promise /** Install package to tmp dir and run webpack on it to calculate size. */ async function getSizes(options: GetSizesOptions & CommonOptions) { - const dir = await loadPackage(options); const result = await runWebpack( - await config({ - dir, - ...options - }) + await config(options) ); - logger.debug(`Completed building: ${dir}`); + logger.debug(`Completed building: ${options.dir}`); if (options.persist) { const folder = `bundle-${options.scope}-${options.importName}`; const out = path.join(process.cwd(), folder); logger.info(`Persisting output to: ${folder}`); await fs.remove(out); - await fs.copy(dir, out); + await fs.copy(options.dir, out); await fs.writeFile(`${out}/stats.json`, JSON.stringify(result.toJson())); await fs.writeFile( `${out}/.gitignore`, @@ -186,7 +182,6 @@ async function getSizes(options: GetSizesOptions & CommonOptions) { execSync('git commit -m "init"', { cwd: out }); } - fs.removeSync(dir); if (result.hasErrors()) { throw new Error(result.toString('errors-only')); } @@ -202,13 +197,19 @@ async function getSizes(options: GetSizesOptions & CommonOptions) { /** Start the webpack bundle analyzer for both of the bundles. */ async function startAnalyze(name: string, registry?: string, local?: string) { logger.start('Analyzing build output...'); + const packageName = local ? getLocalPackage(name, local) : name; + const dir = await loadPackage({ + name: packageName, + registry + }); await Promise.all([ getSizes({ - name: local ? getLocalPackage(name, local) : name, + name: packageName, importName: name, scope: 'master', analyze: true, - registry + registry, + dir }), getSizes({ name: process.cwd(), @@ -216,9 +217,11 @@ async function startAnalyze(name: string, registry?: string, local?: string) { scope: 'pr', analyze: true, analyzerPort: 9000, - registry + registry, + dir }) ]); + fs.removeSync(dir); } export { startAnalyze, runWebpack, config, getSizes }; From 9d358bc6d6964dd1818800982271f55abb45a21c Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Thu, 28 Apr 2022 10:11:28 -0500 Subject: [PATCH 05/11] feat: enforce package-scoped size limit --- plugins/size/src/index.ts | 2 +- plugins/size/src/interfaces.ts | 6 +++++- plugins/size/src/utils/CalcSizeUtils.ts | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/size/src/index.ts b/plugins/size/src/index.ts index 37b0e773a..6b0378a7c 100644 --- a/plugins/size/src/index.ts +++ b/plugins/size/src/index.ts @@ -90,7 +90,7 @@ export default class SizePlugin implements Plugin { const underFailureThreshold = size && size.percent <= FAILURE_THRESHOLD || size.percent === Infinity; - const underSizeLimit = args.limit ? size.pr.js + size.pr.css <= args.limit : true; + const underSizeLimit = size.localBudget ? size.pr.js + size.pr.css <= size.localBudget : true; const success = underFailureThreshold && underSizeLimit; await reportResults( diff --git a/plugins/size/src/interfaces.ts b/plugins/size/src/interfaces.ts index c31c3112c..2475eac36 100644 --- a/plugins/size/src/interfaces.ts +++ b/plugins/size/src/interfaces.ts @@ -20,7 +20,7 @@ export interface SizeArgs { /** The registry to install packages from */ registry?: string /** Size limit failure threshold */ - limit?: number + sizeLimit?: number /** Size Failure Threshold */ failureThreshold?: number /** Run the plugin against merge base. (Will be slower due to additional build process) */ @@ -45,6 +45,8 @@ export interface Size { js: number /** Top level exports of package */ exported?: Export[] + /** Maximum bundle size as defined by the package */ + limit?: number } export interface SizeResult { @@ -54,6 +56,8 @@ export interface SizeResult { pr: Size /** The difference between sizes */ percent: number + /** The total number of bytes allowed as defined in the local changeset */ + localBudget?: number } export interface ConfigOptions { diff --git a/plugins/size/src/utils/CalcSizeUtils.ts b/plugins/size/src/utils/CalcSizeUtils.ts index df21a5e1c..cb30b4226 100644 --- a/plugins/size/src/utils/CalcSizeUtils.ts +++ b/plugins/size/src/utils/CalcSizeUtils.ts @@ -1,4 +1,5 @@ import { monorepoName, createLogger } from '@design-systems/cli-utils'; +import { loadConfig } from '@design-systems/load-config'; import path from 'path'; import fs from 'fs-extra'; import os from 'os'; @@ -65,6 +66,9 @@ async function calcSizeForPackage({ registry, dir }); + const packageConfig = loadConfig({ + cwd: path.join(dir, 'node_modules', packageName) + }); fs.removeSync(dir); const js = sizes.filter((size) => !size.chunkNames.includes('css')); @@ -83,6 +87,7 @@ async function calcSizeForPackage({ js: js.length ? js.reduce((acc, i) => i.size + acc, 0) - RUNTIME_SIZE : 0, // Minus webpack runtime size; css: css.length ? css.reduce((acc, i) => i.size + acc, 0) : 0, exported: sizes, + limit: packageConfig?.size?.sizeLimit }; } @@ -136,6 +141,7 @@ async function diffSizeForPackage({ master, pr, percent, + localBudget: pr.limit }; } From 6dcef857ea0fc9b514dc6d0da4b8505b0971a4f8 Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Thu, 28 Apr 2022 10:26:33 -0500 Subject: [PATCH 06/11] chore: update documentation to reflect new feature --- packages/docs/generate-docs.js | 15 +++++++++++---- plugins/size/src/command.ts | 7 +++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/docs/generate-docs.js b/packages/docs/generate-docs.js index fb65512c1..ec338b836 100755 --- a/packages/docs/generate-docs.js +++ b/packages/docs/generate-docs.js @@ -46,11 +46,16 @@ const makeType = ({ type, typeName, multiple }) => { return multiple ? `${typeString}[]` : typeString; }; +/** Determine supported scope for option */ +const makeScope = ({ scope }) => { + return scope || 'Global' +} + /** Generate a table for an array of options */ function generateOptionTable(options) { let text = dedent`\n - | Name | Type | Description | - | ---- | ---- | ----------- | + | Name | Type | Scope | Description | + | ---- | ---- | ----- | ----------- | `; Object.entries(options).forEach(([option, value]) => { @@ -58,7 +63,7 @@ function generateOptionTable(options) { return; } - text += `\n| ${option} | ${makeType(value)} | ${value.description} |`; + text += `\n| ${option} | ${makeType(value)} | ${makeScope(value)} | ${value.description} |`; }); return text; @@ -82,7 +87,7 @@ async function generateConfigDocs() { \`@design-systems/cli\` supports a wide array of configuration files. - Add one of the following to to the root of the project: + Add one of the following to to the root of the project and/or the root of a given submodule: - a \`ds\` key in the \`package.json\` - \`.dsrc\` @@ -93,6 +98,8 @@ async function generateConfigDocs() { - \`ds.config.js\` - \`ds.config.json\` + !> The package-specific configuration feature is in very early stages, and only supports options with the **Local** scope. + ## Structure The config is structured with each key being a command name and the value being an object configuring options. diff --git a/plugins/size/src/command.ts b/plugins/size/src/command.ts index ff561caa2..195149dc0 100644 --- a/plugins/size/src/command.ts +++ b/plugins/size/src/command.ts @@ -89,6 +89,13 @@ const command: CliCommand = { description: 'Failure Threshold for Size', config: true }, + { + name: 'sizeLimit', + type: Number, + description: 'Size limit failure threshold', + config: true, + scope: 'Local' + } { name: 'merge-base', type: String, From 0541a255247ad2c56adf386b39bb44b74c8c454a Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Thu, 28 Apr 2022 14:38:14 -0500 Subject: [PATCH 07/11] fix: typeerrors in build --- packages/plugin/src/index.ts | 2 ++ plugins/size/package.json | 2 ++ plugins/size/src/command.ts | 2 +- plugins/size/src/utils/BuildUtils.ts | 6 +++--- plugins/size/src/utils/CalcSizeUtils.ts | 2 +- plugins/size/src/utils/WebpackUtils.ts | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index ed4b833e7..ab6bd901e 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -9,6 +9,8 @@ import { Overwrite } from 'utility-types'; export type Option = AppOption & { /** Whether the Option should be configurable via ds.config.json */ config?: boolean; + /** Whether or not the option is available in the global or local scope */ + scope?: string; }; interface Configurable { diff --git a/plugins/size/package.json b/plugins/size/package.json index 3bae024c6..672419dc9 100644 --- a/plugins/size/package.json +++ b/plugins/size/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@design-systems/cli-utils": "link:../../packages/cli-utils", + "@design-systems/load-config": "link:../../packages/load-config", "@design-systems/plugin": "link:../../packages/plugin", "@royriojas/get-exports-from-file": "https://github.com/hipstersmoothie/get-exports-from-file#all", "change-case": "4.1.1", @@ -42,6 +43,7 @@ "table": "6.0.7", "terser-webpack-plugin": "4.1.0", "tslib": "2.0.1", + "utility-types": "3.10.0", "webpack": "4.44.1", "webpack-bundle-analyzer": "3.8.0", "webpack-inject-plugin": "1.5.5", diff --git a/plugins/size/src/command.ts b/plugins/size/src/command.ts index 195149dc0..5b8c156f0 100644 --- a/plugins/size/src/command.ts +++ b/plugins/size/src/command.ts @@ -95,7 +95,7 @@ const command: CliCommand = { description: 'Size limit failure threshold', config: true, scope: 'Local' - } + }, { name: 'merge-base', type: String, diff --git a/plugins/size/src/utils/BuildUtils.ts b/plugins/size/src/utils/BuildUtils.ts index 166372d39..52dafd629 100644 --- a/plugins/size/src/utils/BuildUtils.ts +++ b/plugins/size/src/utils/BuildUtils.ts @@ -14,7 +14,7 @@ export function buildPackages(args: { mergeBase: string /** Build command for merge base */ buildCommand: string -}) { +}): string { const id = Math.random().toString(36).substring(7); const dir = path.join(os.tmpdir(), `commit-build-${id}`); const root = getMonorepoRoot(); @@ -59,7 +59,7 @@ export function getLocalPackage( } /** Install package to tmp dir */ -export async function loadPackage(options: LoadPackageOptions) { +export async function loadPackage(options: LoadPackageOptions): Promise { const dir = mockPackage(); const execOptions: ExecSyncOptions = { cwd: dir, @@ -88,7 +88,7 @@ export async function loadPackage(options: LoadPackageOptions) { } catch (error) { logger.debug(error); logger.warn(`Could not find package ${options.name}...`); - return []; + return './'; } return dir; diff --git a/plugins/size/src/utils/CalcSizeUtils.ts b/plugins/size/src/utils/CalcSizeUtils.ts index cb30b4226..0148b69a1 100644 --- a/plugins/size/src/utils/CalcSizeUtils.ts +++ b/plugins/size/src/utils/CalcSizeUtils.ts @@ -146,7 +146,7 @@ async function diffSizeForPackage({ } /** Create a mock npm package in a tmp dir on the system. */ -export function mockPackage() { +export function mockPackage(): string { const id = Math.random().toString(36).substring(7); const dir = path.join(os.tmpdir(), `package-size-${id}`); diff --git a/plugins/size/src/utils/WebpackUtils.ts b/plugins/size/src/utils/WebpackUtils.ts index d49f62317..4c35b9493 100644 --- a/plugins/size/src/utils/WebpackUtils.ts +++ b/plugins/size/src/utils/WebpackUtils.ts @@ -159,7 +159,7 @@ async function runWebpack(config: webpack.Configuration): Promise }); } -/** Install package to tmp dir and run webpack on it to calculate size. */ +/** Run webpack on package directory to calculate size. */ async function getSizes(options: GetSizesOptions & CommonOptions) { const result = await runWebpack( await config(options) From 72e0b58982c6005876266a786fe42f794b47ac74 Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Thu, 28 Apr 2022 15:21:31 -0500 Subject: [PATCH 08/11] fix: circular dependency caused by using load-config --- plugins/size/package.json | 2 +- plugins/size/src/utils/CalcSizeUtils.ts | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/plugins/size/package.json b/plugins/size/package.json index 672419dc9..3a91acb1e 100644 --- a/plugins/size/package.json +++ b/plugins/size/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@design-systems/cli-utils": "link:../../packages/cli-utils", - "@design-systems/load-config": "link:../../packages/load-config", + "cosmiconfig": "7.0.0", "@design-systems/plugin": "link:../../packages/plugin", "@royriojas/get-exports-from-file": "https://github.com/hipstersmoothie/get-exports-from-file#all", "change-case": "4.1.1", diff --git a/plugins/size/src/utils/CalcSizeUtils.ts b/plugins/size/src/utils/CalcSizeUtils.ts index 0148b69a1..4aef2c87c 100644 --- a/plugins/size/src/utils/CalcSizeUtils.ts +++ b/plugins/size/src/utils/CalcSizeUtils.ts @@ -1,5 +1,5 @@ import { monorepoName, createLogger } from '@design-systems/cli-utils'; -import { loadConfig } from '@design-systems/load-config'; +import { cosmiconfigSync as load } from 'cosmiconfig'; import path from 'path'; import fs from 'fs-extra'; import os from 'os'; @@ -40,6 +40,21 @@ const cssHeader = [ const defaultHeader = ['master', 'pr', '+/-', '%']; +function loadConfig(cwd: string) { + return load('ds', { + searchPlaces: [ + 'package.json', + `.dsrc`, + `.dsrc.json`, + `.dsrc.yaml`, + `.dsrc.yml`, + `.dsrc.js`, + `ds.config.js`, + `ds.config.json`, + ] + }).search(cwd)?.config; +} + /** Calculate the bundled CSS and JS size. */ async function calcSizeForPackage({ name, @@ -66,9 +81,7 @@ async function calcSizeForPackage({ registry, dir }); - const packageConfig = loadConfig({ - cwd: path.join(dir, 'node_modules', packageName) - }); + const packageConfig = loadConfig(path.join(dir, 'node_modules', packageName)); fs.removeSync(dir); const js = sizes.filter((size) => !size.chunkNames.includes('css')); From f1a7408e27d610835f68b737fd4271cfaabc1fe9 Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Thu, 28 Apr 2022 15:33:36 -0500 Subject: [PATCH 09/11] fix: JSDoc --- plugins/size/src/utils/CalcSizeUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/size/src/utils/CalcSizeUtils.ts b/plugins/size/src/utils/CalcSizeUtils.ts index 4aef2c87c..80c40e5dd 100644 --- a/plugins/size/src/utils/CalcSizeUtils.ts +++ b/plugins/size/src/utils/CalcSizeUtils.ts @@ -40,6 +40,7 @@ const cssHeader = [ const defaultHeader = ['master', 'pr', '+/-', '%']; +/** Load package-specific configuration options. */ function loadConfig(cwd: string) { return load('ds', { searchPlaces: [ From 42b4cfd416b77f39c6c3260f2e261b22845d3ddd Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Fri, 29 Apr 2022 09:58:13 -0500 Subject: [PATCH 10/11] fix: enable size limits for lerna packages --- plugins/size/src/index.ts | 9 ++------- plugins/size/src/utils/CalcSizeUtils.ts | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/plugins/size/src/index.ts b/plugins/size/src/index.ts index 6b0378a7c..87c127eed 100644 --- a/plugins/size/src/index.ts +++ b/plugins/size/src/index.ts @@ -8,7 +8,7 @@ import { SizeResult} from "./interfaces" import { formatLine, formatExports } from "./utils/formatUtils"; import { buildPackages } from "./utils/BuildUtils"; -import { calcSizeForAllPackages, reportResults, table, diffSizeForPackage } from "./utils/CalcSizeUtils"; +import { calcSizeForAllPackages, reportResults, table, diffSizeForPackage, sizePassesMuster } from "./utils/CalcSizeUtils"; import { startAnalyze } from "./utils/WebpackUtils"; import { createDiff } from "./utils/DiffUtils"; @@ -86,12 +86,7 @@ export default class SizePlugin implements Plugin { local }); const header = args.css ? cssHeader : defaultHeader; - - const underFailureThreshold = size && - size.percent <= FAILURE_THRESHOLD || - size.percent === Infinity; - const underSizeLimit = size.localBudget ? size.pr.js + size.pr.css <= size.localBudget : true; - const success = underFailureThreshold && underSizeLimit; + const success = sizePassesMuster(size, FAILURE_THRESHOLD); await reportResults( name, diff --git a/plugins/size/src/utils/CalcSizeUtils.ts b/plugins/size/src/utils/CalcSizeUtils.ts index 80c40e5dd..36599e692 100644 --- a/plugins/size/src/utils/CalcSizeUtils.ts +++ b/plugins/size/src/utils/CalcSizeUtils.ts @@ -294,6 +294,15 @@ function table(data: (string | number)[][], isCi?: boolean) { return cliTable(data); } +/** Analyzes a SizeResult to determine if it passes or fails */ +export function sizePassesMuster(size: SizeResult, failureThreshold: number) { + const underFailureThreshold = size && + size.percent <= failureThreshold || + size.percent === Infinity; + const underSizeLimit = size.localBudget ? size.pr.js + size.pr.css <= size.localBudget : true; + return underFailureThreshold && underSizeLimit; +} + /** Generate diff for all changed packages in the monorepo. */ async function calcSizeForAllPackages(args: SizeArgs & CommonCalcSizeOptions) { const ignore = args.ignore || []; @@ -344,11 +353,13 @@ async function calcSizeForAllPackages(args: SizeArgs & CommonCalcSizeOptions) { results.push(size); const FAILURE_THRESHOLD = args.failureThreshold || 5; - if (size.percent > FAILURE_THRESHOLD && size.percent !== Infinity) { - success = false; - logger.error(`${packageJson.package.name} failed bundle size check :(`); - } else { + + success = sizePassesMuster(size, FAILURE_THRESHOLD); + + if (success) { logger.success(`${packageJson.package.name} passed bundle size check!`); + } else { + logger.error(`${packageJson.package.name} failed bundle size check :(`); } return args.detailed From abd4826465e1bba68a438926ad0bdd48d67f1f1d Mon Sep 17 00:00:00 2001 From: Jordan Foreman Date: Fri, 29 Apr 2022 12:48:31 -0500 Subject: [PATCH 11/11] fix: loading config from PR/local path --- plugins/size/src/utils/CalcSizeUtils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/size/src/utils/CalcSizeUtils.ts b/plugins/size/src/utils/CalcSizeUtils.ts index 36599e692..3b21ae13e 100644 --- a/plugins/size/src/utils/CalcSizeUtils.ts +++ b/plugins/size/src/utils/CalcSizeUtils.ts @@ -82,7 +82,8 @@ async function calcSizeForPackage({ registry, dir }); - const packageConfig = loadConfig(path.join(dir, 'node_modules', packageName)); + const packageDir = local ? path.join(dir, 'node_modules', packageName) : name; + const packageConfig = loadConfig(packageDir); fs.removeSync(dir); const js = sizes.filter((size) => !size.chunkNames.includes('css'));