@roots/bud-compiler 2023.7.20-622 → 2023.7.21-611

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/service.js CHANGED
@@ -9,6 +9,8 @@ import { bind } from '@roots/bud-support/decorators/bind';
9
9
  import { BudError } from '@roots/bud-support/errors';
10
10
  import { duration } from '@roots/bud-support/human-readable';
11
11
  import { render } from '@roots/bud-support/ink';
12
+ import isNull from '@roots/bud-support/lodash/isNull';
13
+ import isString from '@roots/bud-support/lodash/isString';
12
14
  import stripAnsi from '@roots/bud-support/strip-ansi';
13
15
  import webpack from '@roots/bud-support/webpack';
14
16
  /**
@@ -44,10 +46,7 @@ export class Compiler extends Service {
44
46
  : await Promise.all(Object.values(bud.children).map(async (child) => await child.build.make().catch(error => {
45
47
  throw error;
46
48
  })));
47
- const cores = Math.max(cpus().length, 1);
48
- const compilations = Math.max(Object.keys(bud.children ?? []).length, 1);
49
- const parallelism = Math.max(Math.floor(cores / compilations), 1);
50
- this.config.parallelism = parallelism;
49
+ this.config.parallelism = Math.max(cpus().length - 1, 1);
51
50
  this.logger.info(`parallel compilations: ${this.config.parallelism}`);
52
51
  await bud.hooks.fire(`compiler.before`, bud).catch(error => {
53
52
  throw error;
@@ -73,6 +72,8 @@ export class Compiler extends Service {
73
72
  */
74
73
  onError(error) {
75
74
  process.exitCode = 1;
75
+ if (!error)
76
+ return;
76
77
  this.app.server?.appliedMiddleware?.hot?.publish({ error });
77
78
  this.app.notifier?.notify({
78
79
  group: this.app.label,
@@ -157,27 +158,38 @@ export class Compiler extends Service {
157
158
  if (!errors || !errors.length)
158
159
  return [];
159
160
  try {
160
- const parseError = (error) => {
161
+ return errors
162
+ ?.map((error) => {
161
163
  let file;
162
- const moduleIdent = error.moduleId ?? error.moduleName;
164
+ let module;
165
+ const ident = error.moduleId ?? error.moduleName;
163
166
  /**
164
167
  * In a perfect world webpack plugins would use the
165
168
  * `nameForCondition` property to identify the module.
166
169
  */
167
- let module = this.compilationStats.children
168
- .flatMap(child => child?.modules)
169
- .find(module => module?.id === moduleIdent || module?.name === moduleIdent);
170
+ if (ident) {
171
+ module = this.compilationStats.children
172
+ .flatMap(child => child?.modules)
173
+ .find(module => [module?.id, module?.name].includes(ident));
174
+ }
170
175
  /**
171
176
  * If the module is not found, we try to parse the error message
172
177
  */
173
- if (!moduleIdent) {
174
- const stylelintExtracted = error.message.match(/file:\/\/(.*)\x07(.*)\x1B]8;;/);
175
- if (stylelintExtracted?.[1]) {
176
- module = {
177
- name: stylelintExtracted[2] ?? stylelintExtracted[1],
178
- nameForCondition: stylelintExtracted[1],
179
- };
180
- }
178
+ if (!ident && error.message?.includes(`[stylelint]`)) {
179
+ // try to get the origin of the stylelint error,
180
+ // which is contained in the second line of the error message
181
+ const unparsedOrigin = error.message?.split(`\n`)?.[1];
182
+ // if the origin is not a string or too long, we return the error as-is
183
+ if (!isString(unparsedOrigin) || unparsedOrigin.length > 100)
184
+ return error;
185
+ // extract absolute path and context relative name of module
186
+ const styleError = unparsedOrigin.match(/file:\/\/(.*)\x07(.*)\x1B]8;;/);
187
+ if (isNull(styleError))
188
+ return error;
189
+ // get parts of matched error
190
+ const [, file, name] = styleError;
191
+ // return enriched error
192
+ return { ...error, file, name, nameForCondition: file };
181
193
  }
182
194
  /**
183
195
  * If the module is still not found, we return the error as-is
@@ -194,14 +206,13 @@ export class Compiler extends Service {
194
206
  else if (module.name) {
195
207
  file = this.app.path(`@src`, module.name);
196
208
  }
197
- return !file
198
- ? { ...error, name: module.name ?? error.name }
199
- : { ...error, file, name: module.name ?? error.name };
200
- };
201
- return errors?.map(parseError).filter(Boolean);
209
+ const name = module.name ?? error.name ?? `error`;
210
+ return { ...error, file, name };
211
+ })
212
+ .filter(Boolean);
202
213
  }
203
214
  catch (error) {
204
- this.logger.warn(`error parsing errors`, error);
215
+ this.logger.warn(`Problem parsing errors. This probably won't break anything but please report it: https://github.com/roots/bud/issues/new`, error);
205
216
  return errors;
206
217
  }
207
218
  }
@@ -245,16 +256,12 @@ const statsOptions = {
245
256
  cachedAssets: true,
246
257
  cachedModules: true,
247
258
  entrypoints: true,
248
- errorDetails: false,
249
259
  errors: true,
250
260
  errorsCount: true,
251
- errorStack: false,
252
261
  hash: true,
253
262
  modules: true,
254
263
  name: true,
255
264
  outputPath: true,
256
- reasons: false,
257
- runtime: true,
258
265
  timings: true,
259
266
  warnings: true,
260
267
  warningsCount: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roots/bud-compiler",
3
- "version": "2023.7.20-622",
3
+ "version": "2023.7.21-611",
4
4
  "description": "Compilation handler",
5
5
  "engines": {
6
6
  "node": ">=16"
@@ -61,15 +61,15 @@
61
61
  "types": "./lib/index.d.ts",
62
62
  "module": "./lib/index.js",
63
63
  "devDependencies": {
64
- "@roots/bud-api": "2023.7.20-622",
64
+ "@roots/bud-api": "2023.7.21-611",
65
65
  "@skypack/package-check": "0.2.2",
66
66
  "@types/node": "18.16.19",
67
67
  "@types/react": "18.2.15"
68
68
  },
69
69
  "dependencies": {
70
- "@roots/bud-dashboard": "2023.7.20-622",
71
- "@roots/bud-framework": "2023.7.20-622",
72
- "@roots/bud-support": "2023.7.20-622",
70
+ "@roots/bud-dashboard": "2023.7.21-611",
71
+ "@roots/bud-framework": "2023.7.21-611",
72
+ "@roots/bud-support": "2023.7.21-611",
73
73
  "react": "18.2.0",
74
74
  "tslib": "2.6.0"
75
75
  },
package/src/service.tsx CHANGED
@@ -23,6 +23,8 @@ import {bind} from '@roots/bud-support/decorators/bind'
23
23
  import {BudError, type BudErrorClass} from '@roots/bud-support/errors'
24
24
  import {duration} from '@roots/bud-support/human-readable'
25
25
  import {render} from '@roots/bud-support/ink'
26
+ import isNull from '@roots/bud-support/lodash/isNull'
27
+ import isString from '@roots/bud-support/lodash/isString'
26
28
  import stripAnsi from '@roots/bud-support/strip-ansi'
27
29
  import webpack from '@roots/bud-support/webpack'
28
30
 
@@ -71,14 +73,7 @@ export class Compiler extends Service implements BudCompiler {
71
73
  ),
72
74
  )
73
75
 
74
- const cores = Math.max(cpus().length, 1)
75
- const compilations = Math.max(
76
- Object.keys(bud.children ?? []).length,
77
- 1,
78
- )
79
- const parallelism = Math.max(Math.floor(cores / compilations), 1)
80
-
81
- this.config.parallelism = parallelism
76
+ this.config.parallelism = Math.max(cpus().length - 1, 1)
82
77
  this.logger.info(`parallel compilations: ${this.config.parallelism}`)
83
78
 
84
79
  await bud.hooks.fire(`compiler.before`, bud).catch(error => {
@@ -96,7 +91,6 @@ export class Compiler extends Service implements BudCompiler {
96
91
 
97
92
  this.instance.hooks.done.tap(bud.label, (stats: any) => {
98
93
  this.onStats(stats)
99
-
100
94
  bud.hooks.fire(`compiler.done`, bud, this.stats).catch(error => {
101
95
  throw error
102
96
  })
@@ -111,6 +105,7 @@ export class Compiler extends Service implements BudCompiler {
111
105
  @bind
112
106
  public onError(error: BudErrorClass | webpack.WebpackError) {
113
107
  process.exitCode = 1
108
+ if (!error) return
114
109
 
115
110
  this.app.server?.appliedMiddleware?.hot?.publish({error})
116
111
 
@@ -217,63 +212,71 @@ export class Compiler extends Service implements BudCompiler {
217
212
  if (!errors || !errors.length) return []
218
213
 
219
214
  try {
220
- const parseError = (
221
- error: StatsError,
222
- ): ErrorWithSourceFile | StatsError => {
223
- let file: SourceFile[`file`] | undefined
224
-
225
- const moduleIdent = error.moduleId ?? error.moduleName
226
-
227
- /**
228
- * In a perfect world webpack plugins would use the
229
- * `nameForCondition` property to identify the module.
230
- */
231
- let module = this.compilationStats.children
232
- .flatMap(child => child?.modules)
233
- .find(
234
- module =>
235
- module?.id === moduleIdent || module?.name === moduleIdent,
236
- )
237
-
238
- /**
239
- * If the module is not found, we try to parse the error message
240
- */
241
- if (!moduleIdent) {
242
- const stylelintExtracted = error.message.match(
243
- /file:\/\/(.*)\x07(.*)\x1B]8;;/,
244
- )
245
-
246
- if (stylelintExtracted?.[1]) {
247
- module = {
248
- name: stylelintExtracted[2] ?? stylelintExtracted[1],
249
- nameForCondition: stylelintExtracted[1],
250
- }
215
+ return errors
216
+ ?.map((error: StatsError): ErrorWithSourceFile | StatsError => {
217
+ let file: SourceFile[`file`] | undefined
218
+ let module: undefined | Webpack.StatsModule
219
+
220
+ const ident = error.moduleId ?? error.moduleName
221
+
222
+ /**
223
+ * In a perfect world webpack plugins would use the
224
+ * `nameForCondition` property to identify the module.
225
+ */
226
+ if (ident) {
227
+ module = this.compilationStats.children
228
+ .flatMap(child => child?.modules)
229
+ .find(module => [module?.id, module?.name].includes(ident))
251
230
  }
252
- }
253
231
 
254
- /**
255
- * If the module is still not found, we return the error as-is
256
- */
257
- if (!module) return error
258
-
259
- /**
260
- * We'll prefer the `nameForCondition` property if it exists,
261
- * otherwise we'll use the `name` property.
262
- */
263
- if (module.nameForCondition) {
264
- file = module.nameForCondition
265
- } else if (module.name) {
266
- file = this.app.path(`@src`, module.name)
267
- }
232
+ /**
233
+ * If the module is not found, we try to parse the error message
234
+ */
235
+ if (!ident && error.message?.includes(`[stylelint]`)) {
236
+ // try to get the origin of the stylelint error,
237
+ // which is contained in the second line of the error message
238
+ const unparsedOrigin = error.message?.split(`\n`)?.[1]
239
+
240
+ // if the origin is not a string or too long, we return the error as-is
241
+ if (!isString(unparsedOrigin) || unparsedOrigin.length > 100)
242
+ return error
243
+
244
+ // extract absolute path and context relative name of module
245
+ const styleError = unparsedOrigin.match(
246
+ /file:\/\/(.*)\x07(.*)\x1B]8;;/,
247
+ )
248
+ if (isNull(styleError)) return error
249
+
250
+ // get parts of matched error
251
+ const [, file, name] = styleError
252
+ // return enriched error
253
+ return {...error, file, name, nameForCondition: file}
254
+ }
268
255
 
269
- return !file
270
- ? {...error, name: module.name ?? error.name}
271
- : {...error, file, name: module.name ?? error.name}
272
- }
256
+ /**
257
+ * If the module is still not found, we return the error as-is
258
+ */
259
+ if (!module) return error
260
+
261
+ /**
262
+ * We'll prefer the `nameForCondition` property if it exists,
263
+ * otherwise we'll use the `name` property.
264
+ */
265
+ if (module.nameForCondition) {
266
+ file = module.nameForCondition
267
+ } else if (module.name) {
268
+ file = this.app.path(`@src`, module.name)
269
+ }
273
270
 
274
- return errors?.map(parseError).filter(Boolean)
271
+ const name = module.name ?? error.name ?? `error`
272
+ return {...error, file, name}
273
+ })
274
+ .filter(Boolean)
275
275
  } catch (error) {
276
- this.logger.warn(`error parsing errors`, error)
276
+ this.logger.warn(
277
+ `Problem parsing errors. This probably won't break anything but please report it: https://github.com/roots/bud/issues/new`,
278
+ error,
279
+ )
277
280
  return errors
278
281
  }
279
282
  }
@@ -288,16 +291,12 @@ const statsOptions = {
288
291
  cachedAssets: true,
289
292
  cachedModules: true,
290
293
  entrypoints: true,
291
- errorDetails: false,
292
294
  errors: true,
293
295
  errorsCount: true,
294
- errorStack: false,
295
296
  hash: true,
296
297
  modules: true,
297
298
  name: true,
298
299
  outputPath: true,
299
- reasons: false,
300
- runtime: true,
301
300
  timings: true,
302
301
  warnings: true,
303
302
  warningsCount: true,