@roots/bud-compiler 6.14.2 → 6.15.0
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/index.d.ts
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
* @see https://bud.js.org
|
5
5
|
* @see https://github.com/roots/bud
|
6
6
|
*/
|
7
|
-
import { Compiler } from '
|
7
|
+
import { default as Compiler } from '@roots/bud-compiler/service';
|
8
8
|
declare module '@roots/bud-framework' {
|
9
9
|
interface Services {
|
10
10
|
compiler: Compiler;
|
package/lib/index.js
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
import type { Compiler as BudCompiler } from '@roots/bud-framework';
|
2
1
|
import type { Bud } from '@roots/bud-framework';
|
2
|
+
import type { Compiler as BudCompiler } 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 { type BudHandler } from '@roots/bud-support/errors';
|
7
|
-
import webpack from '@roots/bud-support/webpack';
|
8
6
|
/**
|
9
7
|
* {@link BudCompiler} implementation
|
10
8
|
*/
|
11
|
-
|
9
|
+
declare class Compiler extends Service implements BudCompiler {
|
12
10
|
/**
|
13
11
|
* {@link BudCompiler.compilationStats}
|
14
12
|
*/
|
@@ -36,7 +34,7 @@ export declare class Compiler extends Service implements BudCompiler {
|
|
36
34
|
/**
|
37
35
|
* {@link BudCompiler.onError}
|
38
36
|
*/
|
39
|
-
onError(error:
|
37
|
+
onError(error: Error): void;
|
40
38
|
/**
|
41
39
|
* {@link BudCompiler.onStats}
|
42
40
|
*/
|
@@ -45,5 +43,6 @@ export declare class Compiler extends Service implements BudCompiler {
|
|
45
43
|
* {@link Service.register}
|
46
44
|
*/
|
47
45
|
register?(bud: Bud): Promise<any>;
|
48
|
-
sourceErrors?(errors: Array<StatsError>): Array<ErrorWithSourceFile | StatsError>;
|
46
|
+
sourceErrors?(errors: Array<StatsError> | undefined): Array<ErrorWithSourceFile | StatsError>;
|
49
47
|
}
|
48
|
+
export { Compiler as default };
|
@@ -1,24 +1,21 @@
|
|
1
|
-
import { __decorate
|
1
|
+
import { __decorate } from "tslib";
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
3
3
|
import { cpus } from 'node:os';
|
4
4
|
import process from 'node:process';
|
5
5
|
import { pathToFileURL } from 'node:url';
|
6
|
-
import { Error } from '@roots/bud-dashboard/components/error';
|
6
|
+
import { Error as DisplayError } from '@roots/bud-dashboard/components/error';
|
7
7
|
import { Service } from '@roots/bud-framework/service';
|
8
8
|
import { bind } from '@roots/bud-support/decorators/bind';
|
9
9
|
import { BudError } from '@roots/bud-support/errors';
|
10
|
-
import { duration } from '@roots/bud-support/human-readable';
|
11
10
|
import { render } from '@roots/bud-support/ink';
|
11
|
+
import isNull from '@roots/bud-support/lodash/isNull';
|
12
|
+
import isNumber from '@roots/bud-support/lodash/isNumber';
|
13
|
+
import isString from '@roots/bud-support/lodash/isString';
|
12
14
|
import stripAnsi from '@roots/bud-support/strip-ansi';
|
13
|
-
import webpack from '@roots/bud-support/webpack';
|
14
15
|
/**
|
15
16
|
* {@link BudCompiler} implementation
|
16
17
|
*/
|
17
|
-
|
18
|
-
/**
|
19
|
-
* {@link BudCompiler.compilationStats}
|
20
|
-
*/
|
21
|
-
compilationStats;
|
18
|
+
class Compiler extends Service {
|
22
19
|
/**
|
23
20
|
* {@link BudCompiler.config}
|
24
21
|
*/
|
@@ -27,24 +24,18 @@ export class Compiler extends Service {
|
|
27
24
|
* {@link BudCompiler.implementation}
|
28
25
|
*/
|
29
26
|
implementation;
|
30
|
-
/**
|
31
|
-
* {@link BudCompiler.instance}
|
32
|
-
*/
|
33
|
-
instance;
|
34
|
-
/**
|
35
|
-
* {@link BudCompiler.stats}
|
36
|
-
*/
|
37
|
-
stats;
|
38
27
|
/**
|
39
28
|
* {@link BudCompiler.compile}
|
40
29
|
*/
|
41
30
|
async compile(bud) {
|
42
|
-
|
31
|
+
const config = !bud.hasChildren
|
43
32
|
? [await bud.build.make()]
|
44
|
-
: await Promise.all(Object.values(bud.children).map(async (child) =>
|
33
|
+
: await Promise.all(Object.values(bud.children).map(async (child) => child.build.make().catch(error => {
|
45
34
|
throw error;
|
46
35
|
})));
|
47
|
-
this.config
|
36
|
+
this.config = config?.filter(Boolean);
|
37
|
+
this.config.parallelism = Math.max(cpus().length - 1, 1);
|
38
|
+
this.logger.info(`parallel compilations: ${this.config.parallelism}`);
|
48
39
|
await bud.hooks.fire(`compiler.before`, bud).catch(error => {
|
49
40
|
throw error;
|
50
41
|
});
|
@@ -54,7 +45,8 @@ export class Compiler extends Service {
|
|
54
45
|
this.instance = this.implementation(this.config);
|
55
46
|
}
|
56
47
|
catch (error) {
|
57
|
-
|
48
|
+
const normalError = error instanceof Error ? error : BudError.normalize(error);
|
49
|
+
this.onError(normalError);
|
58
50
|
}
|
59
51
|
this.instance.hooks.done.tap(bud.label, (stats) => {
|
60
52
|
this.onStats(stats);
|
@@ -69,6 +61,8 @@ export class Compiler extends Service {
|
|
69
61
|
*/
|
70
62
|
onError(error) {
|
71
63
|
process.exitCode = 1;
|
64
|
+
if (!error)
|
65
|
+
return;
|
72
66
|
this.app.server?.appliedMiddleware?.hot?.publish({ error });
|
73
67
|
this.app.notifier?.notify({
|
74
68
|
group: this.app.label,
|
@@ -76,10 +70,10 @@ export class Compiler extends Service {
|
|
76
70
|
subtitle: error.name,
|
77
71
|
});
|
78
72
|
if (`isBudError` in error) {
|
79
|
-
render(_jsx(
|
73
|
+
render(_jsx(DisplayError, { error: error }));
|
80
74
|
}
|
81
75
|
else {
|
82
|
-
render(_jsx(
|
76
|
+
render(_jsx(DisplayError, { error: BudError.normalize(error) }));
|
83
77
|
}
|
84
78
|
}
|
85
79
|
/**
|
@@ -96,10 +90,12 @@ export class Compiler extends Service {
|
|
96
90
|
process.exitCode = 1;
|
97
91
|
this.compilationStats.children = this.compilationStats.children?.map(child => ({
|
98
92
|
...child,
|
99
|
-
errors: this.sourceErrors
|
93
|
+
errors: child.errors && this.sourceErrors
|
94
|
+
? this.sourceErrors(child.errors)
|
95
|
+
: child.errors ?? [],
|
100
96
|
}));
|
101
97
|
this.compilationStats.children
|
102
|
-
?.filter(child => child.errorsCount > 0)
|
98
|
+
?.filter(child => isNumber(child.errorsCount) && child.errorsCount > 0)
|
103
99
|
.forEach(child => {
|
104
100
|
try {
|
105
101
|
const error = child.errors?.shift();
|
@@ -112,7 +108,7 @@ export class Compiler extends Service {
|
|
112
108
|
subtitle: error.file ? `Error in ${error.name}` : error.name,
|
113
109
|
title: makeNoticeTitle(child),
|
114
110
|
});
|
115
|
-
this.app.notifier.openEditor(error.file);
|
111
|
+
error.file && this.app.notifier.openEditor(error.file);
|
116
112
|
}
|
117
113
|
catch (error) {
|
118
114
|
this.logger.error(error);
|
@@ -126,13 +122,14 @@ export class Compiler extends Service {
|
|
126
122
|
this.app.notifier.notify({
|
127
123
|
group: `${this.app.label}-${child.name}`,
|
128
124
|
message: child.modules
|
129
|
-
? `${child.modules.length} modules compiled
|
130
|
-
: `
|
125
|
+
? `${child.modules.length} modules compiled`
|
126
|
+
: `Modules compiled successfully`,
|
131
127
|
open: this.app.server?.publicUrl.href,
|
132
128
|
subtitle: `Build successful`,
|
133
129
|
title: makeNoticeTitle(child),
|
134
130
|
});
|
135
|
-
this.app.
|
131
|
+
this.app.server?.publicUrl.href &&
|
132
|
+
this.app.notifier.openBrowser(this.app.server?.publicUrl.href);
|
136
133
|
}
|
137
134
|
catch (error) {
|
138
135
|
this.logger.error(error);
|
@@ -153,61 +150,79 @@ export class Compiler extends Service {
|
|
153
150
|
if (!errors || !errors.length)
|
154
151
|
return [];
|
155
152
|
try {
|
156
|
-
|
153
|
+
return errors
|
154
|
+
?.map((error) => {
|
157
155
|
let file;
|
158
|
-
|
159
|
-
const
|
160
|
-
|
161
|
-
|
156
|
+
let module;
|
157
|
+
const ident = error.moduleId ?? error.moduleName;
|
158
|
+
/**
|
159
|
+
* In a perfect world webpack plugins would use the
|
160
|
+
* `nameForCondition` property to identify the module.
|
161
|
+
*/
|
162
|
+
if (ident && this.compilationStats?.children) {
|
163
|
+
module = this.compilationStats.children
|
164
|
+
.flatMap(child => child?.modules)
|
165
|
+
.find(module => [module?.id, module?.name].includes(ident));
|
166
|
+
}
|
167
|
+
/**
|
168
|
+
* If the module is not found, we try to parse the error message
|
169
|
+
*/
|
170
|
+
if (!ident && error.message?.includes(`[stylelint]`)) {
|
171
|
+
// try to get the origin of the stylelint error,
|
172
|
+
// which is contained in the second line of the error message
|
173
|
+
const unparsedOrigin = error.message?.split(`\n`)?.[1];
|
174
|
+
// if the origin is not a string or too long, we return the error as-is
|
175
|
+
if (!isString(unparsedOrigin) || unparsedOrigin.length > 100)
|
176
|
+
return error;
|
177
|
+
// extract absolute path and context relative name of module
|
178
|
+
const styleError = unparsedOrigin.match(/file:\/\/(.*)\x07(.*)\x1B]8;;/);
|
179
|
+
if (isNull(styleError))
|
180
|
+
return error;
|
181
|
+
// get parts of matched error
|
182
|
+
const [, file, name] = styleError;
|
183
|
+
// return enriched error
|
184
|
+
return { ...error, file, name, nameForCondition: file };
|
185
|
+
}
|
186
|
+
/**
|
187
|
+
* If the module is still not found, we return the error as-is
|
188
|
+
*/
|
162
189
|
if (!module)
|
163
190
|
return error;
|
191
|
+
/**
|
192
|
+
* We'll prefer the `nameForCondition` property if it exists,
|
193
|
+
* otherwise we'll use the `name` property.
|
194
|
+
*/
|
164
195
|
if (module.nameForCondition) {
|
165
196
|
file = module.nameForCondition;
|
166
197
|
}
|
167
198
|
else if (module.name) {
|
168
199
|
file = this.app.path(`@src`, module.name);
|
169
200
|
}
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
return errors?.map(parseError).filter(Boolean);
|
201
|
+
const name = module.name ?? error.name ?? `error`;
|
202
|
+
return { ...error, file, name };
|
203
|
+
})
|
204
|
+
.filter(Boolean);
|
175
205
|
}
|
176
206
|
catch (error) {
|
177
|
-
this.
|
178
|
-
return
|
207
|
+
this.logger.warn(`Problem parsing errors. This probably won't break anything but please report it: https://github.com/roots/bud/issues/new`, error);
|
208
|
+
return errors;
|
179
209
|
}
|
180
210
|
}
|
181
211
|
}
|
182
212
|
__decorate([
|
183
|
-
bind
|
184
|
-
__metadata("design:type", Function),
|
185
|
-
__metadata("design:paramtypes", [Function]),
|
186
|
-
__metadata("design:returntype", Promise)
|
213
|
+
bind
|
187
214
|
], Compiler.prototype, "compile", null);
|
188
215
|
__decorate([
|
189
|
-
bind
|
190
|
-
__metadata("design:type", Function),
|
191
|
-
__metadata("design:paramtypes", [Object]),
|
192
|
-
__metadata("design:returntype", void 0)
|
216
|
+
bind
|
193
217
|
], Compiler.prototype, "onError", null);
|
194
218
|
__decorate([
|
195
|
-
bind
|
196
|
-
__metadata("design:type", Function),
|
197
|
-
__metadata("design:paramtypes", [Function]),
|
198
|
-
__metadata("design:returntype", void 0)
|
219
|
+
bind
|
199
220
|
], Compiler.prototype, "onStats", null);
|
200
221
|
__decorate([
|
201
|
-
bind
|
202
|
-
__metadata("design:type", Function),
|
203
|
-
__metadata("design:paramtypes", [Function]),
|
204
|
-
__metadata("design:returntype", Promise)
|
222
|
+
bind
|
205
223
|
], Compiler.prototype, "register", null);
|
206
224
|
__decorate([
|
207
|
-
bind
|
208
|
-
__metadata("design:type", Function),
|
209
|
-
__metadata("design:paramtypes", [Array]),
|
210
|
-
__metadata("design:returntype", Array)
|
225
|
+
bind
|
211
226
|
], Compiler.prototype, "sourceErrors", null);
|
212
227
|
const statsOptions = {
|
213
228
|
all: false,
|
@@ -221,16 +236,14 @@ const statsOptions = {
|
|
221
236
|
errorDetails: false,
|
222
237
|
errors: true,
|
223
238
|
errorsCount: true,
|
224
|
-
errorStack: false,
|
225
239
|
hash: true,
|
226
240
|
modules: true,
|
227
241
|
name: true,
|
228
242
|
outputPath: true,
|
229
|
-
reasons: false,
|
230
|
-
runtime: true,
|
231
243
|
timings: true,
|
232
244
|
warnings: true,
|
233
245
|
warningsCount: true,
|
234
246
|
},
|
235
247
|
name: true,
|
236
248
|
};
|
249
|
+
export { Compiler as default };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@roots/bud-compiler",
|
3
|
-
"version": "6.
|
3
|
+
"version": "6.15.0",
|
4
4
|
"description": "Compilation handler",
|
5
5
|
"engines": {
|
6
6
|
"node": ">=16"
|
@@ -49,27 +49,31 @@
|
|
49
49
|
],
|
50
50
|
"type": "module",
|
51
51
|
"exports": {
|
52
|
-
".": "./lib/index.js"
|
52
|
+
".": "./lib/index.js",
|
53
|
+
"./service": "./lib/service/index.js"
|
53
54
|
},
|
54
55
|
"typesVersions": {
|
55
56
|
"*": {
|
56
57
|
".": [
|
57
58
|
"./lib/index.d.ts"
|
59
|
+
],
|
60
|
+
"service": [
|
61
|
+
"./lib/service/index.d.ts"
|
58
62
|
]
|
59
63
|
}
|
60
64
|
},
|
61
65
|
"types": "./lib/index.d.ts",
|
62
66
|
"module": "./lib/index.js",
|
63
67
|
"devDependencies": {
|
64
|
-
"@roots/bud-api": "6.
|
68
|
+
"@roots/bud-api": "6.15.0",
|
65
69
|
"@skypack/package-check": "0.2.2",
|
66
|
-
"@types/node": "18.16.
|
67
|
-
"@types/react": "18.2.
|
70
|
+
"@types/node": "18.16.19",
|
71
|
+
"@types/react": "18.2.15"
|
68
72
|
},
|
69
73
|
"dependencies": {
|
70
|
-
"@roots/bud-dashboard": "6.
|
71
|
-
"@roots/bud-framework": "6.
|
72
|
-
"@roots/bud-support": "6.
|
74
|
+
"@roots/bud-dashboard": "6.15.0",
|
75
|
+
"@roots/bud-framework": "6.15.0",
|
76
|
+
"@roots/bud-support": "6.15.0",
|
73
77
|
"react": "18.2.0",
|
74
78
|
"tslib": "2.6.0"
|
75
79
|
},
|
package/src/index.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import type {Compiler as BudCompiler} from '@roots/bud-framework'
|
2
1
|
import type {Bud} from '@roots/bud-framework'
|
2
|
+
import type {Compiler as BudCompiler} from '@roots/bud-framework'
|
3
3
|
import type {
|
4
4
|
MultiCompiler,
|
5
5
|
MultiStats,
|
@@ -17,23 +17,24 @@ import {cpus} from 'node:os'
|
|
17
17
|
import process from 'node:process'
|
18
18
|
import {pathToFileURL} from 'node:url'
|
19
19
|
|
20
|
-
import {Error} from '@roots/bud-dashboard/components/error'
|
20
|
+
import {Error as DisplayError} 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
|
24
|
-
import {duration} from '@roots/bud-support/human-readable'
|
23
|
+
import {BudError} from '@roots/bud-support/errors'
|
25
24
|
import {render} from '@roots/bud-support/ink'
|
25
|
+
import isNull from '@roots/bud-support/lodash/isNull'
|
26
|
+
import isNumber from '@roots/bud-support/lodash/isNumber'
|
27
|
+
import isString from '@roots/bud-support/lodash/isString'
|
26
28
|
import stripAnsi from '@roots/bud-support/strip-ansi'
|
27
|
-
import webpack from '@roots/bud-support/webpack'
|
28
29
|
|
29
30
|
/**
|
30
31
|
* {@link BudCompiler} implementation
|
31
32
|
*/
|
32
|
-
|
33
|
+
class Compiler extends Service implements BudCompiler {
|
33
34
|
/**
|
34
35
|
* {@link BudCompiler.compilationStats}
|
35
36
|
*/
|
36
|
-
public compilationStats: BudCompiler[`compilationStats`]
|
37
|
+
public declare compilationStats: BudCompiler[`compilationStats`]
|
37
38
|
|
38
39
|
/**
|
39
40
|
* {@link BudCompiler.config}
|
@@ -48,29 +49,32 @@ export class Compiler extends Service implements BudCompiler {
|
|
48
49
|
/**
|
49
50
|
* {@link BudCompiler.instance}
|
50
51
|
*/
|
51
|
-
public instance: BudCompiler[`instance`]
|
52
|
+
public declare instance: BudCompiler[`instance`]
|
52
53
|
|
53
54
|
/**
|
54
55
|
* {@link BudCompiler.stats}
|
55
56
|
*/
|
56
|
-
public stats: BudCompiler[`stats`]
|
57
|
+
public declare stats: BudCompiler[`stats`]
|
57
58
|
|
58
59
|
/**
|
59
60
|
* {@link BudCompiler.compile}
|
60
61
|
*/
|
61
62
|
@bind
|
62
63
|
public async compile(bud: Bud): Promise<MultiCompiler> {
|
63
|
-
|
64
|
+
const config = !bud.hasChildren
|
64
65
|
? [await bud.build.make()]
|
65
66
|
: await Promise.all(
|
66
|
-
Object.values(bud.children).map(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
}),
|
67
|
+
Object.values(bud.children).map(async (child: Bud) =>
|
68
|
+
child.build.make().catch(error => {
|
69
|
+
throw error
|
70
|
+
}),
|
71
71
|
),
|
72
72
|
)
|
73
|
-
|
73
|
+
|
74
|
+
this.config = config?.filter(Boolean)
|
75
|
+
|
76
|
+
this.config.parallelism = Math.max(cpus().length - 1, 1)
|
77
|
+
this.logger.info(`parallel compilations: ${this.config.parallelism}`)
|
74
78
|
|
75
79
|
await bud.hooks.fire(`compiler.before`, bud).catch(error => {
|
76
80
|
throw error
|
@@ -81,13 +85,14 @@ export class Compiler extends Service implements BudCompiler {
|
|
81
85
|
|
82
86
|
try {
|
83
87
|
this.instance = this.implementation(this.config)
|
84
|
-
} catch (error) {
|
85
|
-
|
88
|
+
} catch (error: unknown) {
|
89
|
+
const normalError =
|
90
|
+
error instanceof Error ? error : BudError.normalize(error)
|
91
|
+
this.onError(normalError)
|
86
92
|
}
|
87
93
|
|
88
94
|
this.instance.hooks.done.tap(bud.label, (stats: any) => {
|
89
95
|
this.onStats(stats)
|
90
|
-
|
91
96
|
bud.hooks.fire(`compiler.done`, bud, this.stats).catch(error => {
|
92
97
|
throw error
|
93
98
|
})
|
@@ -100,8 +105,9 @@ export class Compiler extends Service implements BudCompiler {
|
|
100
105
|
* {@link BudCompiler.onError}
|
101
106
|
*/
|
102
107
|
@bind
|
103
|
-
public onError(error:
|
108
|
+
public onError(error: Error) {
|
104
109
|
process.exitCode = 1
|
110
|
+
if (!error) return
|
105
111
|
|
106
112
|
this.app.server?.appliedMiddleware?.hot?.publish({error})
|
107
113
|
|
@@ -112,9 +118,9 @@ export class Compiler extends Service implements BudCompiler {
|
|
112
118
|
})
|
113
119
|
|
114
120
|
if (`isBudError` in error) {
|
115
|
-
render(<
|
121
|
+
render(<DisplayError error={error} />)
|
116
122
|
} else {
|
117
|
-
render(<
|
123
|
+
render(<DisplayError error={BudError.normalize(error)} />)
|
118
124
|
}
|
119
125
|
}
|
120
126
|
|
@@ -140,12 +146,17 @@ export class Compiler extends Service implements BudCompiler {
|
|
140
146
|
this.compilationStats.children = this.compilationStats.children?.map(
|
141
147
|
child => ({
|
142
148
|
...child,
|
143
|
-
errors:
|
149
|
+
errors:
|
150
|
+
child.errors && this.sourceErrors
|
151
|
+
? this.sourceErrors(child.errors)
|
152
|
+
: child.errors ?? [],
|
144
153
|
}),
|
145
154
|
)
|
146
155
|
|
147
156
|
this.compilationStats.children
|
148
|
-
?.filter(
|
157
|
+
?.filter(
|
158
|
+
child => isNumber(child.errorsCount) && child.errorsCount > 0,
|
159
|
+
)
|
149
160
|
.forEach(child => {
|
150
161
|
try {
|
151
162
|
const error = child.errors?.shift()
|
@@ -158,7 +169,8 @@ export class Compiler extends Service implements BudCompiler {
|
|
158
169
|
subtitle: error.file ? `Error in ${error.name}` : error.name,
|
159
170
|
title: makeNoticeTitle(child),
|
160
171
|
})
|
161
|
-
|
172
|
+
|
173
|
+
error.file && this.app.notifier.openEditor(error.file)
|
162
174
|
} catch (error) {
|
163
175
|
this.logger.error(error)
|
164
176
|
}
|
@@ -172,16 +184,15 @@ export class Compiler extends Service implements BudCompiler {
|
|
172
184
|
this.app.notifier.notify({
|
173
185
|
group: `${this.app.label}-${child.name}`,
|
174
186
|
message: child.modules
|
175
|
-
? `${child.modules.length} modules compiled
|
176
|
-
|
177
|
-
)}`
|
178
|
-
: `Compiled in ${duration(child.time)}`,
|
187
|
+
? `${child.modules.length} modules compiled`
|
188
|
+
: `Modules compiled successfully`,
|
179
189
|
open: this.app.server?.publicUrl.href,
|
180
190
|
subtitle: `Build successful`,
|
181
191
|
title: makeNoticeTitle(child),
|
182
192
|
})
|
183
193
|
|
184
|
-
this.app.
|
194
|
+
this.app.server?.publicUrl.href &&
|
195
|
+
this.app.notifier.openBrowser(this.app.server?.publicUrl.href)
|
185
196
|
} catch (error) {
|
186
197
|
this.logger.error(error)
|
187
198
|
}
|
@@ -202,42 +213,77 @@ export class Compiler extends Service implements BudCompiler {
|
|
202
213
|
|
203
214
|
@bind
|
204
215
|
public sourceErrors?(
|
205
|
-
errors: Array<StatsError
|
216
|
+
errors: Array<StatsError> | undefined,
|
206
217
|
): Array<ErrorWithSourceFile | StatsError> {
|
207
218
|
if (!errors || !errors.length) return []
|
208
219
|
|
209
220
|
try {
|
210
|
-
|
211
|
-
error: StatsError
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
221
|
+
return errors
|
222
|
+
?.map((error: StatsError): ErrorWithSourceFile | StatsError => {
|
223
|
+
let file: SourceFile[`file`] | undefined
|
224
|
+
let module: undefined | Webpack.StatsModule
|
225
|
+
|
226
|
+
const ident = error.moduleId ?? error.moduleName
|
227
|
+
|
228
|
+
/**
|
229
|
+
* In a perfect world webpack plugins would use the
|
230
|
+
* `nameForCondition` property to identify the module.
|
231
|
+
*/
|
232
|
+
if (ident && this.compilationStats?.children) {
|
233
|
+
module = this.compilationStats.children
|
234
|
+
.flatMap(child => child?.modules)
|
235
|
+
.find(module => [module?.id, module?.name].includes(ident))
|
236
|
+
}
|
237
|
+
|
238
|
+
/**
|
239
|
+
* If the module is not found, we try to parse the error message
|
240
|
+
*/
|
241
|
+
if (!ident && error.message?.includes(`[stylelint]`)) {
|
242
|
+
// try to get the origin of the stylelint error,
|
243
|
+
// which is contained in the second line of the error message
|
244
|
+
const unparsedOrigin = error.message?.split(`\n`)?.[1]
|
245
|
+
|
246
|
+
// if the origin is not a string or too long, we return the error as-is
|
247
|
+
if (!isString(unparsedOrigin) || unparsedOrigin.length > 100)
|
248
|
+
return error
|
249
|
+
|
250
|
+
// extract absolute path and context relative name of module
|
251
|
+
const styleError = unparsedOrigin.match(
|
252
|
+
/file:\/\/(.*)\x07(.*)\x1B]8;;/,
|
253
|
+
)
|
254
|
+
if (isNull(styleError)) return error
|
255
|
+
|
256
|
+
// get parts of matched error
|
257
|
+
const [, file, name] = styleError
|
258
|
+
// return enriched error
|
259
|
+
return {...error, file, name, nameForCondition: file}
|
260
|
+
}
|
231
261
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
262
|
+
/**
|
263
|
+
* If the module is still not found, we return the error as-is
|
264
|
+
*/
|
265
|
+
if (!module) return error
|
266
|
+
|
267
|
+
/**
|
268
|
+
* We'll prefer the `nameForCondition` property if it exists,
|
269
|
+
* otherwise we'll use the `name` property.
|
270
|
+
*/
|
271
|
+
if (module.nameForCondition) {
|
272
|
+
file = module.nameForCondition
|
273
|
+
} else if (module.name) {
|
274
|
+
file = this.app.path(`@src`, module.name)
|
275
|
+
}
|
236
276
|
|
237
|
-
|
277
|
+
const name = module.name ?? error.name ?? `error`
|
278
|
+
return {...error, file, name}
|
279
|
+
})
|
280
|
+
.filter(Boolean)
|
238
281
|
} catch (error) {
|
239
|
-
this.
|
240
|
-
|
282
|
+
this.logger.warn(
|
283
|
+
`Problem parsing errors. This probably won't break anything but please report it: https://github.com/roots/bud/issues/new`,
|
284
|
+
error,
|
285
|
+
)
|
286
|
+
return errors
|
241
287
|
}
|
242
288
|
}
|
243
289
|
}
|
@@ -254,16 +300,15 @@ const statsOptions = {
|
|
254
300
|
errorDetails: false,
|
255
301
|
errors: true,
|
256
302
|
errorsCount: true,
|
257
|
-
errorStack: false,
|
258
303
|
hash: true,
|
259
304
|
modules: true,
|
260
305
|
name: true,
|
261
306
|
outputPath: true,
|
262
|
-
reasons: false,
|
263
|
-
runtime: true,
|
264
307
|
timings: true,
|
265
308
|
warnings: true,
|
266
309
|
warningsCount: true,
|
267
310
|
},
|
268
311
|
name: true,
|
269
312
|
}
|
313
|
+
|
314
|
+
export {Compiler as default}
|