From e56066b90ab9318e804ab0df72fa61342c39bd76 Mon Sep 17 00:00:00 2001 From: Kelly Mears Date: Thu, 20 Jul 2023 20:10:31 -0400 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=91=8D=F0=9F=8F=BC=20improve:=20build?= =?UTF-8?q?=20performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bud-build/src/config/experiments.ts | 1 + .../bud-build/src/config/optimization.ts | 2 +- .../bud-build/src/config/output/index.ts | 6 ++- sources/@roots/bud-compiler/src/service.tsx | 51 +++++++++---------- sources/@roots/bud-framework/src/notifier.ts | 25 +++++---- yarn.lock | 9 ++++ 6 files changed, 54 insertions(+), 40 deletions(-) diff --git a/sources/@roots/bud-build/src/config/experiments.ts b/sources/@roots/bud-build/src/config/experiments.ts index 0547424c3e..23db1d3e6a 100644 --- a/sources/@roots/bud-build/src/config/experiments.ts +++ b/sources/@roots/bud-build/src/config/experiments.ts @@ -6,6 +6,7 @@ export const experiments: Factory<`experiments`> = async ({ }) => hooks.filter(`build.experiments`, { backCompat: false, + cacheUnaffected: true, lazyCompilation: isDevelopment ? {entries: false, imports: true} : false, diff --git a/sources/@roots/bud-build/src/config/optimization.ts b/sources/@roots/bud-build/src/config/optimization.ts index 31858c26cb..10b0d4b56b 100644 --- a/sources/@roots/bud-build/src/config/optimization.ts +++ b/sources/@roots/bud-build/src/config/optimization.ts @@ -31,7 +31,7 @@ export const optimization: Factory<`optimization`> = async ({ ), removeEmptyChunks: filter( `build.optimization.removeEmptyChunks`, - isProduction, + false, ), runtimeChunk: filter(`build.optimization.runtimeChunk`, `single`), sideEffects: filter(`build.optimization.sideEffects`, isProduction), diff --git a/sources/@roots/bud-build/src/config/output/index.ts b/sources/@roots/bud-build/src/config/output/index.ts index 6441e9de34..250d9f6194 100644 --- a/sources/@roots/bud-build/src/config/output/index.ts +++ b/sources/@roots/bud-build/src/config/output/index.ts @@ -24,7 +24,11 @@ export const output: Factory<`output`> = async ({ iife: filter(`build.output.iife`, undefined), module: filter(`build.output.module`, false), path: filter(`build.output.path`, path(`@dist`)), - pathinfo: filter(`build.output.pathinfo`, true), + /** + * Path info is not necessary unless the user + * really knows what's going on. + */ + pathinfo: filter(`build.output.pathinfo`, false), publicPath: filter(`build.output.publicPath`, `auto`), scriptType: filter( `build.output.scriptType`, diff --git a/sources/@roots/bud-compiler/src/service.tsx b/sources/@roots/bud-compiler/src/service.tsx index 9ec02be234..43f790d045 100644 --- a/sources/@roots/bud-compiler/src/service.tsx +++ b/sources/@roots/bud-compiler/src/service.tsx @@ -214,32 +214,31 @@ export class Compiler extends Service implements BudCompiler { error: StatsError, ): ErrorWithSourceFile | StatsError => { let file: SourceFile[`file`] | undefined + let module: undefined | Webpack.StatsModule - const moduleIdent = error.moduleId ?? error.moduleName + const ident = error.moduleId ?? error.moduleName /** * In a perfect world webpack plugins would use the * `nameForCondition` property to identify the module. */ - let module = this.compilationStats.children - .flatMap(child => child?.modules) - .find( - module => - module?.id === moduleIdent || module?.name === moduleIdent, - ) - - /** - * If the module is not found, we try to parse the error message - */ - if (!moduleIdent) { - const stylelintExtracted = error.message.match( - /file:\/\/(.*)\x07(.*)\x1B]8;;/, - ) - - if (stylelintExtracted?.[1]) { + if (ident) { + module = this.compilationStats.children + .flatMap(child => child?.modules) + .find(module => [module?.id, module?.name].includes(ident)) + + /** + * If the module is not found, we try to parse the error message + */ + } else { + const styleError = error.message + .split(`\n`)?.[1] + ?.match(/file:\/\/(.*)\x07(.*)\x1B]8;;/) + + if (styleError?.[1]) { module = { - name: stylelintExtracted[2] ?? stylelintExtracted[1], - nameForCondition: stylelintExtracted[1], + name: styleError[2] ?? styleError[1], + nameForCondition: styleError[1], } } } @@ -259,14 +258,16 @@ export class Compiler extends Service implements BudCompiler { file = this.app.path(`@src`, module.name) } - return !file - ? {...error, name: module.name ?? error.name} - : {...error, file, name: module.name ?? error.name} + const name = module.name ?? error.name ?? `error` + return {...error, file, name} } return errors?.map(parseError).filter(Boolean) } catch (error) { - this.logger.warn(`error parsing errors`, error) + this.logger.warn( + `Problem parsing errors. This probably won't break anything but please report it: https://github.com/roots/bud/issues/new`, + error, + ) return errors } } @@ -281,16 +282,12 @@ const statsOptions = { cachedAssets: true, cachedModules: true, entrypoints: true, - errorDetails: false, errors: true, errorsCount: true, - errorStack: false, hash: true, modules: true, name: true, outputPath: true, - reasons: false, - runtime: true, timings: true, warnings: true, warningsCount: true, diff --git a/sources/@roots/bud-framework/src/notifier.ts b/sources/@roots/bud-framework/src/notifier.ts index daffaf8c18..1d18d6e5ba 100644 --- a/sources/@roots/bud-framework/src/notifier.ts +++ b/sources/@roots/bud-framework/src/notifier.ts @@ -12,6 +12,7 @@ import isEmpty from '@roots/bud-support/lodash/isEmpty' import isString from '@roots/bud-support/lodash/isString' import logger from '@roots/bud-support/logger' import {open, openEditor} from '@roots/bud-support/open' +import chalk from 'chalk' const notifierPath = resolve( dirname(fileURLToPath(import.meta.url)), @@ -193,21 +194,23 @@ export class Notifier { * True if editor opening is enabled */ public get openEditorEnabled(): boolean { - if (!this.editor) { + const enabled = + this.app.context.editor === true || // if true, fall back to default behavior + typeof this.app.context.editor === `string` // if string, opens in that editor + + if (enabled && !this.editor) { logger .scope(`notifier`, `editor check`) .warn( - `Editor not set.`, - `\n\nYou should set an editor using any of the following env vars:\n`, - `\n - BUD_EDITOR (bud specific; preferred)`, - `\n - VISUAL (unix standard)`, - `\n - EDITOR (unix standard)`, - `\n\nAlternatively, use the --editor flag.`, + chalk.magenta(`\n\nEditor not defined.`), + `\n\nYou should set an editor using any of the following ENV variables:\n`, + `\n - ${chalk.blue(`BUD_EDITOR`)} (bud specific; preferred)`, + `\n - ${chalk.blue(`VISUAL`)} (unix standard)`, + `\n - ${chalk.blue(`EDITOR`)} (unix standard)`, + `\n\nAlternatively, use the ${chalk.blue(`--editor`)} flag.`, ) } - return ( - this.app.context.editor === true || // if true, fall back to default behavior - typeof this.app.context.editor === `string` // if string, opens in that editor - ) + + return enabled } } diff --git a/yarn.lock b/yarn.lock index 02bb89a199..a87859f75f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4688,6 +4688,7 @@ __metadata: "@roots/bud-babel": "workspace:*" "@roots/bud-postcss": "workspace:*" "@roots/bud-react": "workspace:*" + preact: 10.16.0 languageName: unknown linkType: soft @@ -8362,6 +8363,7 @@ __metadata: open-editor: 4.0.0 parse-semver: 1.1.1 patch-console: 2.0.0 + preact: 10.16.0 pretty-format: 29.6.1 react: 18.2.0 remark: 14.0.3 @@ -29942,6 +29944,13 @@ __metadata: languageName: node linkType: hard +"preact@npm:10.16.0": + version: 10.16.0 + resolution: "preact@npm:10.16.0" + checksum: 47a91f47d583b68a4afe971a7f992c06547df6d637cadf56eb3b69fee1fb202659b199af37d0e1a90637385144cadd75aa40acdb4e125cc4b3155e2883c24c07 + languageName: node + linkType: hard + "prebuild-install@npm:^7.1.1": version: 7.1.1 resolution: "prebuild-install@npm:7.1.1" From f0da14d52a030f7aa0b7ae92b255b0e6939025f8 Mon Sep 17 00:00:00 2001 From: Kelly Mears Date: Thu, 20 Jul 2023 20:46:21 -0400 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=A6=20yarn.lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yarn.lock | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index a87859f75f..88d5b53bca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4688,7 +4688,6 @@ __metadata: "@roots/bud-babel": "workspace:*" "@roots/bud-postcss": "workspace:*" "@roots/bud-react": "workspace:*" - preact: 10.16.0 languageName: unknown linkType: soft @@ -8363,7 +8362,6 @@ __metadata: open-editor: 4.0.0 parse-semver: 1.1.1 patch-console: 2.0.0 - preact: 10.16.0 pretty-format: 29.6.1 react: 18.2.0 remark: 14.0.3 @@ -15304,9 +15302,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001464, caniuse-lite@npm:^1.0.30001503": - version: 1.0.30001516 - resolution: "caniuse-lite@npm:1.0.30001516" - checksum: 044adf3493b734a356a2922445a30095a0f6de6b9194695cdf74deafe7bef658e85858a31177762c2813f6e1ed2722d832d59eee0ecb2151e93a611ee18cb21f + version: 1.0.30001517 + resolution: "caniuse-lite@npm:1.0.30001517" + checksum: e4e87436ae1c4408cf4438aac22902b31eb03f3f5bad7f33bc518d12ffb35f3fd9395ccf7efc608ee046f90ce324ec6f7f26f8a8172b8c43c26a06ecee612a29 languageName: node linkType: hard @@ -29944,13 +29942,6 @@ __metadata: languageName: node linkType: hard -"preact@npm:10.16.0": - version: 10.16.0 - resolution: "preact@npm:10.16.0" - checksum: 47a91f47d583b68a4afe971a7f992c06547df6d637cadf56eb3b69fee1fb202659b199af37d0e1a90637385144cadd75aa40acdb4e125cc4b3155e2883c24c07 - languageName: node - linkType: hard - "prebuild-install@npm:^7.1.1": version: 7.1.1 resolution: "prebuild-install@npm:7.1.1" From 684a7b3a75acc82da656ce19ec4736635f6feced Mon Sep 17 00:00:00 2001 From: Kelly Mears Date: Fri, 21 Jul 2023 01:35:34 -0400 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=91=8D=F0=9F=8F=BC=20improve:=20style?= =?UTF-8?q?lint=20--editor=20behavior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/@roots/bud-compiler/src/service.tsx | 99 +++++++++++--------- sources/@roots/bud-framework/src/notifier.ts | 1 - 2 files changed, 54 insertions(+), 46 deletions(-) diff --git a/sources/@roots/bud-compiler/src/service.tsx b/sources/@roots/bud-compiler/src/service.tsx index 43f790d045..3e27722544 100644 --- a/sources/@roots/bud-compiler/src/service.tsx +++ b/sources/@roots/bud-compiler/src/service.tsx @@ -23,6 +23,8 @@ import {bind} from '@roots/bud-support/decorators/bind' import {BudError, type BudErrorClass} from '@roots/bud-support/errors' import {duration} from '@roots/bud-support/human-readable' import {render} from '@roots/bud-support/ink' +import isNull from '@roots/bud-support/lodash/isNull' +import isString from '@roots/bud-support/lodash/isString' import stripAnsi from '@roots/bud-support/strip-ansi' import webpack from '@roots/bud-support/webpack' @@ -210,59 +212,66 @@ export class Compiler extends Service implements BudCompiler { if (!errors || !errors.length) return [] try { - const parseError = ( - error: StatsError, - ): ErrorWithSourceFile | StatsError => { - let file: SourceFile[`file`] | undefined - let module: undefined | Webpack.StatsModule - - const ident = error.moduleId ?? error.moduleName - - /** - * In a perfect world webpack plugins would use the - * `nameForCondition` property to identify the module. - */ - if (ident) { - module = this.compilationStats.children - .flatMap(child => child?.modules) - .find(module => [module?.id, module?.name].includes(ident)) + return errors + ?.map((error: StatsError): ErrorWithSourceFile | StatsError => { + let file: SourceFile[`file`] | undefined + let module: undefined | Webpack.StatsModule + + const ident = error.moduleId ?? error.moduleName + + /** + * In a perfect world webpack plugins would use the + * `nameForCondition` property to identify the module. + */ + if (ident) { + module = this.compilationStats.children + .flatMap(child => child?.modules) + .find(module => [module?.id, module?.name].includes(ident)) + } /** * If the module is not found, we try to parse the error message */ - } else { - const styleError = error.message - .split(`\n`)?.[1] - ?.match(/file:\/\/(.*)\x07(.*)\x1B]8;;/) - - if (styleError?.[1]) { - module = { - name: styleError[2] ?? styleError[1], - nameForCondition: styleError[1], - } + if (!ident && error.message?.includes(`[stylelint]`)) { + // try to get the origin of the stylelint error, + // which is contained in the second line of the error message + const unparsedOrigin = error.message?.split(`\n`)?.[1] + + // if the origin is not a string or too long, we return the error as-is + if (!isString(unparsedOrigin) || unparsedOrigin.length > 100) + return error + + // extract absolute path and context relative name of module + const styleError = unparsedOrigin.match( + /file:\/\/(.*)\x07(.*)\x1B]8;;/, + ) + if (isNull(styleError)) return error + + // get parts of matched error + const [, file, name] = styleError + // return enriched error + return {...error, file, name, nameForCondition: file} } - } - /** - * If the module is still not found, we return the error as-is - */ - if (!module) return error - - /** - * We'll prefer the `nameForCondition` property if it exists, - * otherwise we'll use the `name` property. - */ - if (module.nameForCondition) { - file = module.nameForCondition - } else if (module.name) { - file = this.app.path(`@src`, module.name) - } + /** + * If the module is still not found, we return the error as-is + */ + if (!module) return error - const name = module.name ?? error.name ?? `error` - return {...error, file, name} - } + /** + * We'll prefer the `nameForCondition` property if it exists, + * otherwise we'll use the `name` property. + */ + if (module.nameForCondition) { + file = module.nameForCondition + } else if (module.name) { + file = this.app.path(`@src`, module.name) + } - return errors?.map(parseError).filter(Boolean) + const name = module.name ?? error.name ?? `error` + return {...error, file, name} + }) + .filter(Boolean) } catch (error) { this.logger.warn( `Problem parsing errors. This probably won't break anything but please report it: https://github.com/roots/bud/issues/new`, diff --git a/sources/@roots/bud-framework/src/notifier.ts b/sources/@roots/bud-framework/src/notifier.ts index 1d18d6e5ba..7dfa33cbdd 100644 --- a/sources/@roots/bud-framework/src/notifier.ts +++ b/sources/@roots/bud-framework/src/notifier.ts @@ -174,7 +174,6 @@ export class Notifier { */ public openEditor(input: Array | string) { if (!this.openEditorEnabled) return - if (!input || isEmpty(input)) return logger.scope(`notifier`, `openEditor`).log(`input received`, input)