@roots/bud-compiler 2023.7.20-622 → 2023.7.23-80
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.d.ts +2 -2
- package/lib/service.js +36 -29
- package/package.json +5 -5
- package/src/service.tsx +71 -73
package/lib/service.d.ts
CHANGED
@@ -3,7 +3,7 @@ import type { Bud } from '@roots/bud-framework';
|
|
3
3
|
import type { MultiCompiler, MultiStats, Stats, StatsError, Webpack } from '@roots/bud-framework/config';
|
4
4
|
import type { ErrorWithSourceFile } from '@roots/bud-support/open';
|
5
5
|
import { Service } from '@roots/bud-framework/service';
|
6
|
-
import {
|
6
|
+
import { BudError } from '@roots/bud-support/errors';
|
7
7
|
import webpack from '@roots/bud-support/webpack';
|
8
8
|
/**
|
9
9
|
* {@link BudCompiler} implementation
|
@@ -36,7 +36,7 @@ export declare class Compiler extends Service implements BudCompiler {
|
|
36
36
|
/**
|
37
37
|
* {@link BudCompiler.onError}
|
38
38
|
*/
|
39
|
-
onError(error:
|
39
|
+
onError(error: BudError | webpack.WebpackError): void;
|
40
40
|
/**
|
41
41
|
* {@link BudCompiler.onStats}
|
42
42
|
*/
|
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
|
/**
|
@@ -41,13 +43,10 @@ export class Compiler extends Service {
|
|
41
43
|
async compile(bud) {
|
42
44
|
this.config = !bud.hasChildren
|
43
45
|
? [await bud.build.make()]
|
44
|
-
: await Promise.all(Object.values(bud.children).map(async (child) =>
|
46
|
+
: await Promise.all(Object.values(bud.children).map(async (child) => child.build.make().catch(error => {
|
45
47
|
throw error;
|
46
48
|
})));
|
47
|
-
|
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;
|
@@ -58,7 +57,7 @@ export class Compiler extends Service {
|
|
58
57
|
this.instance = this.implementation(this.config);
|
59
58
|
}
|
60
59
|
catch (error) {
|
61
|
-
|
60
|
+
this.onError(error);
|
62
61
|
}
|
63
62
|
this.instance.hooks.done.tap(bud.label, (stats) => {
|
64
63
|
this.onStats(stats);
|
@@ -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
|
-
|
161
|
+
return errors
|
162
|
+
?.map((error) => {
|
161
163
|
let file;
|
162
|
-
|
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
|
-
|
168
|
-
|
169
|
-
|
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 (!
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
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(`
|
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.
|
3
|
+
"version": "2023.7.23-80",
|
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.
|
64
|
+
"@roots/bud-api": "2023.7.23-80",
|
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.
|
71
|
-
"@roots/bud-framework": "2023.7.
|
72
|
-
"@roots/bud-support": "2023.7.
|
70
|
+
"@roots/bud-dashboard": "2023.7.23-80",
|
71
|
+
"@roots/bud-framework": "2023.7.23-80",
|
72
|
+
"@roots/bud-support": "2023.7.23-80",
|
73
73
|
"react": "18.2.0",
|
74
74
|
"tslib": "2.6.0"
|
75
75
|
},
|
package/src/service.tsx
CHANGED
@@ -20,9 +20,11 @@ import {pathToFileURL} from 'node:url'
|
|
20
20
|
import {Error} from '@roots/bud-dashboard/components/error'
|
21
21
|
import {Service} from '@roots/bud-framework/service'
|
22
22
|
import {bind} from '@roots/bud-support/decorators/bind'
|
23
|
-
import {BudError
|
23
|
+
import {BudError} 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
|
|
@@ -63,22 +65,14 @@ export class Compiler extends Service implements BudCompiler {
|
|
63
65
|
this.config = !bud.hasChildren
|
64
66
|
? [await bud.build.make()]
|
65
67
|
: await Promise.all(
|
66
|
-
Object.values(bud.children).map(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
}),
|
68
|
+
Object.values(bud.children).map(async (child: Bud) =>
|
69
|
+
child.build.make().catch(error => {
|
70
|
+
throw error
|
71
|
+
}),
|
71
72
|
),
|
72
73
|
)
|
73
74
|
|
74
|
-
|
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
|
75
|
+
this.config.parallelism = Math.max(cpus().length - 1, 1)
|
82
76
|
this.logger.info(`parallel compilations: ${this.config.parallelism}`)
|
83
77
|
|
84
78
|
await bud.hooks.fire(`compiler.before`, bud).catch(error => {
|
@@ -91,12 +85,11 @@ export class Compiler extends Service implements BudCompiler {
|
|
91
85
|
try {
|
92
86
|
this.instance = this.implementation(this.config)
|
93
87
|
} catch (error) {
|
94
|
-
|
88
|
+
this.onError(error)
|
95
89
|
}
|
96
90
|
|
97
91
|
this.instance.hooks.done.tap(bud.label, (stats: any) => {
|
98
92
|
this.onStats(stats)
|
99
|
-
|
100
93
|
bud.hooks.fire(`compiler.done`, bud, this.stats).catch(error => {
|
101
94
|
throw error
|
102
95
|
})
|
@@ -109,8 +102,9 @@ export class Compiler extends Service implements BudCompiler {
|
|
109
102
|
* {@link BudCompiler.onError}
|
110
103
|
*/
|
111
104
|
@bind
|
112
|
-
public onError(error:
|
105
|
+
public onError(error: BudError | webpack.WebpackError) {
|
113
106
|
process.exitCode = 1
|
107
|
+
if (!error) return
|
114
108
|
|
115
109
|
this.app.server?.appliedMiddleware?.hot?.publish({error})
|
116
110
|
|
@@ -217,63 +211,71 @@ export class Compiler extends Service implements BudCompiler {
|
|
217
211
|
if (!errors || !errors.length) return []
|
218
212
|
|
219
213
|
try {
|
220
|
-
|
221
|
-
error: StatsError
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
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
|
-
}
|
214
|
+
return errors
|
215
|
+
?.map((error: StatsError): ErrorWithSourceFile | StatsError => {
|
216
|
+
let file: SourceFile[`file`] | undefined
|
217
|
+
let module: undefined | Webpack.StatsModule
|
218
|
+
|
219
|
+
const ident = error.moduleId ?? error.moduleName
|
220
|
+
|
221
|
+
/**
|
222
|
+
* In a perfect world webpack plugins would use the
|
223
|
+
* `nameForCondition` property to identify the module.
|
224
|
+
*/
|
225
|
+
if (ident) {
|
226
|
+
module = this.compilationStats.children
|
227
|
+
.flatMap(child => child?.modules)
|
228
|
+
.find(module => [module?.id, module?.name].includes(ident))
|
251
229
|
}
|
252
|
-
}
|
253
230
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
231
|
+
/**
|
232
|
+
* If the module is not found, we try to parse the error message
|
233
|
+
*/
|
234
|
+
if (!ident && error.message?.includes(`[stylelint]`)) {
|
235
|
+
// try to get the origin of the stylelint error,
|
236
|
+
// which is contained in the second line of the error message
|
237
|
+
const unparsedOrigin = error.message?.split(`\n`)?.[1]
|
238
|
+
|
239
|
+
// if the origin is not a string or too long, we return the error as-is
|
240
|
+
if (!isString(unparsedOrigin) || unparsedOrigin.length > 100)
|
241
|
+
return error
|
242
|
+
|
243
|
+
// extract absolute path and context relative name of module
|
244
|
+
const styleError = unparsedOrigin.match(
|
245
|
+
/file:\/\/(.*)\x07(.*)\x1B]8;;/,
|
246
|
+
)
|
247
|
+
if (isNull(styleError)) return error
|
248
|
+
|
249
|
+
// get parts of matched error
|
250
|
+
const [, file, name] = styleError
|
251
|
+
// return enriched error
|
252
|
+
return {...error, file, name, nameForCondition: file}
|
253
|
+
}
|
268
254
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
255
|
+
/**
|
256
|
+
* If the module is still not found, we return the error as-is
|
257
|
+
*/
|
258
|
+
if (!module) return error
|
259
|
+
|
260
|
+
/**
|
261
|
+
* We'll prefer the `nameForCondition` property if it exists,
|
262
|
+
* otherwise we'll use the `name` property.
|
263
|
+
*/
|
264
|
+
if (module.nameForCondition) {
|
265
|
+
file = module.nameForCondition
|
266
|
+
} else if (module.name) {
|
267
|
+
file = this.app.path(`@src`, module.name)
|
268
|
+
}
|
273
269
|
|
274
|
-
|
270
|
+
const name = module.name ?? error.name ?? `error`
|
271
|
+
return {...error, file, name}
|
272
|
+
})
|
273
|
+
.filter(Boolean)
|
275
274
|
} catch (error) {
|
276
|
-
this.logger.warn(
|
275
|
+
this.logger.warn(
|
276
|
+
`Problem parsing errors. This probably won't break anything but please report it: https://github.com/roots/bud/issues/new`,
|
277
|
+
error,
|
278
|
+
)
|
277
279
|
return errors
|
278
280
|
}
|
279
281
|
}
|
@@ -288,16 +290,12 @@ const statsOptions = {
|
|
288
290
|
cachedAssets: true,
|
289
291
|
cachedModules: true,
|
290
292
|
entrypoints: true,
|
291
|
-
errorDetails: false,
|
292
293
|
errors: true,
|
293
294
|
errorsCount: true,
|
294
|
-
errorStack: false,
|
295
295
|
hash: true,
|
296
296
|
modules: true,
|
297
297
|
name: true,
|
298
298
|
outputPath: true,
|
299
|
-
reasons: false,
|
300
|
-
runtime: true,
|
301
299
|
timings: true,
|
302
300
|
warnings: true,
|
303
301
|
warningsCount: true,
|