@simplysm/sd-cli 7.0.37 → 7.0.41
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/.eslintrc.cjs +2 -2
- package/dist/bin/sd-cli.mjs +3 -1
- package/dist/build-tool/SdCliNgCacheCompilerHost.mjs +3 -3
- package/dist/builder/SdCliClientBuilder.d.ts +3 -3
- package/dist/builder/SdCliClientBuilder.mjs +157 -130
- package/dist/builder/SdCliJsLibBuilder.mjs +2 -2
- package/dist/builder/SdCliServerBuilder.mjs +6 -5
- package/dist/builder/SdCliTsLibBuilder.d.ts +1 -1
- package/dist/builder/SdCliTsLibBuilder.mjs +5 -5
- package/dist/commons.d.ts +5 -1
- package/dist/entry-points/SdCliLocalUpdate.mjs +15 -9
- package/dist/entry-points/SdCliPrepare.mjs +3 -2
- package/dist/entry-points/SdCliWorkspace.d.ts +1 -0
- package/dist/entry-points/SdCliWorkspace.mjs +47 -19
- package/dist/packages/SdCliPackage.d.ts +4 -4
- package/dist/packages/SdCliPackage.mjs +11 -10
- package/dist/utils/SdCliBuildResultUtil.mjs +4 -4
- package/package.json +10 -7
- package/src/bin/sd-cli.ts +2 -0
- package/src/build-tool/SdCliNgCacheCompilerHost.ts +3 -3
- package/src/builder/SdCliClientBuilder.ts +159 -132
- package/src/builder/SdCliJsLibBuilder.ts +2 -2
- package/src/builder/SdCliServerBuilder.ts +5 -6
- package/src/builder/SdCliTsLibBuilder.ts +5 -5
- package/src/commons.ts +6 -1
- package/src/entry-points/SdCliLocalUpdate.ts +14 -8
- package/src/entry-points/SdCliPrepare.ts +2 -1
- package/src/entry-points/SdCliWorkspace.ts +54 -21
- package/src/packages/SdCliPackage.ts +12 -11
- package/src/utils/SdCliBuildResultUtil.ts +3 -3
- package/tsconfig.json +1 -1
|
@@ -50,9 +50,8 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
50
50
|
await new Promise<void>((resolve, reject) => {
|
|
51
51
|
compiler.hooks.watchRun.tapAsync(this.constructor.name, (args, callback) => {
|
|
52
52
|
this.emit("change");
|
|
53
|
-
callback();
|
|
54
|
-
|
|
55
53
|
this._logger.debug("Webpack 빌드 수행...");
|
|
54
|
+
callback();
|
|
56
55
|
});
|
|
57
56
|
|
|
58
57
|
compiler.watch({}, async (err, stats) => {
|
|
@@ -65,11 +64,9 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
65
64
|
await this._writeDistConfigFileAsync();
|
|
66
65
|
|
|
67
66
|
// 결과 반환
|
|
67
|
+
this._logger.debug("Webpack 빌드 완료");
|
|
68
68
|
const results = SdCliBuildResultUtil.convertFromWebpackStats(stats);
|
|
69
69
|
this.emit("complete", results);
|
|
70
|
-
|
|
71
|
-
// 마무리
|
|
72
|
-
this._logger.debug("Webpack 빌드 완료");
|
|
73
70
|
resolve();
|
|
74
71
|
});
|
|
75
72
|
});
|
|
@@ -239,7 +236,9 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
239
236
|
outputModule: true
|
|
240
237
|
},
|
|
241
238
|
performance: { hints: false },
|
|
242
|
-
node:
|
|
239
|
+
node: {
|
|
240
|
+
__dirname: true
|
|
241
|
+
},
|
|
243
242
|
stats: "errors-warnings",
|
|
244
243
|
externals: extModuleNames,
|
|
245
244
|
...watch ? {
|
|
@@ -33,7 +33,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
|
|
|
33
33
|
|
|
34
34
|
private readonly _isAngular: boolean;
|
|
35
35
|
|
|
36
|
-
public constructor(private readonly _rootPath) {
|
|
36
|
+
public constructor(private readonly _rootPath: string) {
|
|
37
37
|
super();
|
|
38
38
|
this._linter = new SdCliPackageLinter(this._rootPath);
|
|
39
39
|
|
|
@@ -66,7 +66,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
|
|
|
66
66
|
|
|
67
67
|
const relatedPaths = await this.getAllRelatedPathsAsync();
|
|
68
68
|
const watcher = SdFsWatcher.watch(relatedPaths);
|
|
69
|
-
watcher.onChange(async (changeInfos) => {
|
|
69
|
+
watcher.onChange({}, async (changeInfos) => {
|
|
70
70
|
const changeFilePaths = changeInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
71
71
|
if (changeFilePaths.length === 0) return;
|
|
72
72
|
|
|
@@ -194,7 +194,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
|
|
|
194
194
|
}
|
|
195
195
|
catch (err) {
|
|
196
196
|
if (err instanceof sass.Exception) {
|
|
197
|
-
const matches =
|
|
197
|
+
const matches = (/^(.*\.sd\.scss) ([0-9]*):([0-9]*)/).exec(err.sassStack)!;
|
|
198
198
|
const filePath = path.resolve(matches[1].replace(/\.sd\.scss/, "").replace(/^\.:/, item => item.toUpperCase()));
|
|
199
199
|
const scssLine = matches[2];
|
|
200
200
|
const scssChar = matches[3];
|
|
@@ -206,7 +206,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
|
|
|
206
206
|
char: undefined,
|
|
207
207
|
code: undefined,
|
|
208
208
|
severity: "error",
|
|
209
|
-
message: `스타일(${scssLine}:${scssChar}): ${message}`
|
|
209
|
+
message: `스타일(${scssLine}:${scssChar}): ${message}\n${err.message}`
|
|
210
210
|
}];
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -234,7 +234,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
|
|
|
234
234
|
const affectedSourceFileSet: Set<ts.SourceFile> = new Set<ts.SourceFile>();
|
|
235
235
|
while (true) {
|
|
236
236
|
const result = this._builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, (sourceFile) => {
|
|
237
|
-
if (ngCompiler
|
|
237
|
+
if (ngCompiler?.ignoreForDiagnostics.has(sourceFile) && sourceFile.fileName.endsWith(".ngtypecheck.ts")) {
|
|
238
238
|
const orgFileName = sourceFile.fileName.slice(0, -15) + ".ts";
|
|
239
239
|
const orgSourceFile = this._builder!.getSourceFile(orgFileName);
|
|
240
240
|
if (orgSourceFile) {
|
package/src/commons.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface ISdCliConfig {
|
|
|
40
40
|
localUpdates?: Record<string, string>;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export type TSdCliPackageConfig = ISdCliLibPackageConfig | ISdCliServerPackageConfig;
|
|
43
|
+
export type TSdCliPackageConfig = ISdCliLibPackageConfig | ISdCliServerPackageConfig | ISdCliClientPackageConfig;
|
|
44
44
|
|
|
45
45
|
export interface ISdCliLibPackageConfig {
|
|
46
46
|
type: "library";
|
|
@@ -54,3 +54,8 @@ export interface ISdCliServerPackageConfig {
|
|
|
54
54
|
pm2?: Record<string, any> | boolean;
|
|
55
55
|
iis?: { serverExeFilePath?: string } | boolean;
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
export interface ISdCliClientPackageConfig {
|
|
59
|
+
type: "client";
|
|
60
|
+
server: string;
|
|
61
|
+
}
|
|
@@ -40,19 +40,25 @@ export class SdCliLocalUpdate {
|
|
|
40
40
|
const watchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
41
41
|
|
|
42
42
|
const watcher = SdFsWatcher.watch(watchPaths);
|
|
43
|
-
watcher.onChange(async (changeInfos) => {
|
|
43
|
+
watcher.onChange({ delay: 1000 }, async (changeInfos) => {
|
|
44
44
|
const changeFilePaths = changeInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
45
45
|
if (changeFilePaths.length === 0) return;
|
|
46
46
|
|
|
47
47
|
this._logger.log("로컬 라이브러리 변경감지...");
|
|
48
48
|
for (const changedFilePath of changeFilePaths) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
if (!FsUtil.exists(changedFilePath)) continue;
|
|
50
|
+
|
|
51
|
+
for (const updatePathInfo of updatePathInfos) {
|
|
52
|
+
if (!PathUtil.isChildPath(changedFilePath, updatePathInfo.source)) continue;
|
|
53
|
+
|
|
54
|
+
const sourceRelPath = path.relative(updatePathInfo.source, changedFilePath);
|
|
55
|
+
if (sourceRelPath.includes("node_modules")) continue;
|
|
56
|
+
if (sourceRelPath.includes("package.json")) continue;
|
|
57
|
+
|
|
58
|
+
const targetFilePath = path.resolve(updatePathInfo.target, sourceRelPath);
|
|
59
|
+
|
|
60
|
+
this._logger.debug(`변경파일감지(복사): ${changedFilePath} => ${targetFilePath}`);
|
|
61
|
+
await FsUtil.copyAsync(changedFilePath, targetFilePath);
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
64
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FsUtil, Logger } from "@simplysm/sd-core-node";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
2
3
|
|
|
3
4
|
export class SdCliPrepare {
|
|
4
5
|
private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
|
|
@@ -11,7 +12,7 @@ export class SdCliPrepare {
|
|
|
11
12
|
|
|
12
13
|
private async _modifyTypescriptCodeForTypeCheckPerformanceWarning(): Promise<boolean> {
|
|
13
14
|
const fileUrl = await import.meta.resolve!("typescript");
|
|
14
|
-
const filePath = fileUrl
|
|
15
|
+
const filePath = fileURLToPath(fileUrl);
|
|
15
16
|
const fileContent = await FsUtil.readFileAsync(filePath);
|
|
16
17
|
const modifiedFileContent = fileContent.replace(`
|
|
17
18
|
function checkSourceElement(node) {
|
|
@@ -10,6 +10,7 @@ import { SdCliConfigUtil } from "../utils/SdCliConfigUtil";
|
|
|
10
10
|
import { SdServiceServer } from "@simplysm/sd-service/server";
|
|
11
11
|
import { SdCliNpm } from "./SdCliNpm";
|
|
12
12
|
import { SdCliLocalUpdate } from "./SdCliLocalUpdate";
|
|
13
|
+
import { NextHandleFunction } from "connect";
|
|
13
14
|
|
|
14
15
|
export class SdCliWorkspace {
|
|
15
16
|
private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
|
|
@@ -47,11 +48,7 @@ export class SdCliWorkspace {
|
|
|
47
48
|
this._logger.debug(`[${pkg.name}] 빌드를 시작합니다...`);
|
|
48
49
|
})
|
|
49
50
|
.on("complete", async (results) => {
|
|
50
|
-
if (pkg.type === "server") {
|
|
51
|
-
if (results.some((item) => item.severity === "error")) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
51
|
+
if (pkg.config.type === "server" && !results.some((item) => item.severity === "error")) {
|
|
55
52
|
await this._restartServerAsync(pkg);
|
|
56
53
|
}
|
|
57
54
|
|
|
@@ -62,6 +59,7 @@ export class SdCliWorkspace {
|
|
|
62
59
|
changeCount--;
|
|
63
60
|
if (changeCount === 0) {
|
|
64
61
|
this._loggingResults(totalResultMap);
|
|
62
|
+
this._loggingOpenClientHrefs();
|
|
65
63
|
this._logger.info("모든 빌드가 완료되었습니다.");
|
|
66
64
|
}
|
|
67
65
|
}, 500);
|
|
@@ -73,7 +71,16 @@ export class SdCliWorkspace {
|
|
|
73
71
|
const buildCompletedPackageNames: string[] = [];
|
|
74
72
|
await pkgs.parallelAsync(async (pkg) => {
|
|
75
73
|
await Wait.until(() => !pkg.allDependencies.some((dep) => pkgNames.includes(dep) && !buildCompletedPackageNames.includes(dep)));
|
|
76
|
-
|
|
74
|
+
if (pkg.config.type === "client") {
|
|
75
|
+
const middlewares = (await pkg.watchAsync()) as NextHandleFunction[];
|
|
76
|
+
|
|
77
|
+
const serverInfo = this._serverInfoMap.getOrCreate(pkg.config.server, { middlewares: [], clientInfos: [] });
|
|
78
|
+
serverInfo.middlewares.push(...middlewares);
|
|
79
|
+
serverInfo.clientInfos.push({ pkgKey: pkg.name.split("/").last()! });
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
await pkg.watchAsync();
|
|
83
|
+
}
|
|
77
84
|
buildCompletedPackageNames.push(pkg.name);
|
|
78
85
|
});
|
|
79
86
|
}
|
|
@@ -87,21 +94,26 @@ export class SdCliWorkspace {
|
|
|
87
94
|
const entryFilePath = path.resolve(pkg.rootPath, entryFileRelPath);
|
|
88
95
|
|
|
89
96
|
this._logger.log(`서버(${pkg.name}) 재시작...`);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
serverInfo.server = (await import("file:///" + entryFilePath + "?update=" + Uuid.new().toString())).default as SdServiceServer | undefined;
|
|
97
|
-
if (!serverInfo.server) {
|
|
98
|
-
this._logger.error(`${entryFilePath}(0, 0): 'SdServiceServer'를 'export'해야 합니다.`);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
97
|
+
try {
|
|
98
|
+
const serverInfo = this._serverInfoMap.getOrCreate(pkg.name, { middlewares: [], clientInfos: [] });
|
|
99
|
+
if (serverInfo.server) {
|
|
100
|
+
await serverInfo.server.closeAsync();
|
|
101
|
+
delete serverInfo.server;
|
|
102
|
+
}
|
|
101
103
|
|
|
102
|
-
|
|
104
|
+
serverInfo.server = (await import("file:///" + entryFilePath + "?update=" + Uuid.new().toString())).default as SdServiceServer | undefined;
|
|
105
|
+
if (!serverInfo.server) {
|
|
106
|
+
this._logger.error(`${entryFilePath}(0, 0): 'SdServiceServer'를 'export'해야 합니다.`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
serverInfo.server.devMiddlewares = serverInfo.middlewares;
|
|
110
|
+
await Wait.until(() => serverInfo.server!.isOpen);
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
this._logger.log(`서버(${pkg.name}) 재시작 완료`);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
this._logger.error(`서버(${pkg.name}) 재시작중 오류 발생`, err);
|
|
116
|
+
}
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
public async buildAsync(opt: { confFileRelPath: string; optNames: string[] }): Promise<void> {
|
|
@@ -226,7 +238,7 @@ export class SdCliWorkspace {
|
|
|
226
238
|
if (i !== sec) {
|
|
227
239
|
process.stdout.cursorTo(0);
|
|
228
240
|
}
|
|
229
|
-
process.stdout.write(msg
|
|
241
|
+
process.stdout.write(`${msg} ${i}`);
|
|
230
242
|
await Wait.time(1000);
|
|
231
243
|
}
|
|
232
244
|
|
|
@@ -252,7 +264,7 @@ export class SdCliWorkspace {
|
|
|
252
264
|
pkgName: item[0],
|
|
253
265
|
...item1
|
|
254
266
|
})))
|
|
255
|
-
.orderBy((item) => item.pkgName
|
|
267
|
+
.orderBy((item) => `${item.pkgName}_${item.filePath}`);
|
|
256
268
|
|
|
257
269
|
const warnings = totalResults
|
|
258
270
|
.filter((item) => item.severity === "warning")
|
|
@@ -278,8 +290,29 @@ export class SdCliWorkspace {
|
|
|
278
290
|
this._logger.warn(`경고: ${warnings.length}건, 오류: ${errors.length}건`);
|
|
279
291
|
}
|
|
280
292
|
}
|
|
293
|
+
|
|
294
|
+
private _loggingOpenClientHrefs(): void {
|
|
295
|
+
const clientHrefs: string[] = [];
|
|
296
|
+
|
|
297
|
+
const serverInfos = Array.from(this._serverInfoMap.values());
|
|
298
|
+
for (const serverInfo of serverInfos) {
|
|
299
|
+
if (!serverInfo.server) continue;
|
|
300
|
+
|
|
301
|
+
const protocolStr = serverInfo.server.options.ssl ? "https" : "http";
|
|
302
|
+
const portStr = serverInfo.server.options.port.toString();
|
|
303
|
+
|
|
304
|
+
for (const clientInfo of serverInfo.clientInfos) {
|
|
305
|
+
clientHrefs.push(`${protocolStr}://localhost:${portStr}/${clientInfo.pkgKey}/`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (clientHrefs.length > 0) {
|
|
309
|
+
this._logger.log(`오픈된 클라이언트: ${clientHrefs.join(", ")}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
281
312
|
}
|
|
282
313
|
|
|
283
314
|
interface IServerInfo {
|
|
284
315
|
server?: SdServiceServer;
|
|
316
|
+
middlewares: NextHandleFunction[];
|
|
317
|
+
clientInfos: { pkgKey: string }[];
|
|
285
318
|
}
|
|
@@ -7,6 +7,8 @@ import { SdCliTsLibBuilder } from "../builder/SdCliTsLibBuilder";
|
|
|
7
7
|
import { SdCliJsLibBuilder } from "../builder/SdCliJsLibBuilder";
|
|
8
8
|
import { SdCliServerBuilder } from "../builder/SdCliServerBuilder";
|
|
9
9
|
import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
|
|
10
|
+
import { SdCliClientBuilder } from "../builder/SdCliClientBuilder";
|
|
11
|
+
import { NextHandleFunction } from "connect";
|
|
10
12
|
|
|
11
13
|
export class SdCliPackage extends EventEmitter {
|
|
12
14
|
private readonly _npmConfig: INpmConfig;
|
|
@@ -23,10 +25,6 @@ export class SdCliPackage extends EventEmitter {
|
|
|
23
25
|
return this._npmConfig.main;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
public get type(): TSdCliPackageConfig["type"] {
|
|
27
|
-
return this._config.type;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
28
|
public get allDependencies(): string[] {
|
|
31
29
|
return [
|
|
32
30
|
...SdCliNpmConfigUtil.getDependencies(this._npmConfig).defaults,
|
|
@@ -36,7 +34,7 @@ export class SdCliPackage extends EventEmitter {
|
|
|
36
34
|
|
|
37
35
|
public constructor(private readonly _workspaceRootPath: string,
|
|
38
36
|
public readonly rootPath: string,
|
|
39
|
-
|
|
37
|
+
public readonly config: TSdCliPackageConfig) {
|
|
40
38
|
super();
|
|
41
39
|
|
|
42
40
|
const npmConfigFilePath = path.resolve(this.rootPath, "package.json");
|
|
@@ -69,8 +67,8 @@ export class SdCliPackage extends EventEmitter {
|
|
|
69
67
|
await FsUtil.writeJsonAsync(npmConfigFilePath, this._npmConfig, { space: 2 });
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
public async watchAsync(): Promise<void> {
|
|
73
|
-
await (await this._createBuilderAsync())
|
|
70
|
+
public async watchAsync(): Promise<NextHandleFunction[] | void> {
|
|
71
|
+
return await (await this._createBuilderAsync())
|
|
74
72
|
.on("change", () => {
|
|
75
73
|
this.emit("change");
|
|
76
74
|
})
|
|
@@ -85,24 +83,27 @@ export class SdCliPackage extends EventEmitter {
|
|
|
85
83
|
}
|
|
86
84
|
|
|
87
85
|
public async publishAsync(): Promise<void> {
|
|
88
|
-
if (this.
|
|
86
|
+
if (this.config.type === "library" && this.config.publish === "npm") {
|
|
89
87
|
await SdProcess.spawnAsync("npm publish --quiet --access public", { cwd: this.rootPath });
|
|
90
88
|
}
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
private async _createBuilderAsync(): Promise<SdCliJsLibBuilder | SdCliTsLibBuilder | SdCliServerBuilder> {
|
|
91
|
+
private async _createBuilderAsync(): Promise<SdCliJsLibBuilder | SdCliTsLibBuilder | SdCliServerBuilder | SdCliClientBuilder> {
|
|
94
92
|
const isTs = FsUtil.exists(path.resolve(this.rootPath, "tsconfig.json"));
|
|
95
93
|
|
|
96
94
|
if (isTs) {
|
|
97
95
|
await this._genBuildTsconfigAsync();
|
|
98
96
|
}
|
|
99
97
|
|
|
100
|
-
if (this.
|
|
98
|
+
if (this.config.type === "library") {
|
|
101
99
|
// const isAngular = isTs && this.allDependencies.includes("@angular/core");
|
|
102
100
|
return isTs ? new SdCliTsLibBuilder(this.rootPath) : new SdCliJsLibBuilder(this.rootPath);
|
|
103
101
|
}
|
|
102
|
+
else if (this.config.type === "server") {
|
|
103
|
+
return new SdCliServerBuilder(this.rootPath, this.config, this._workspaceRootPath);
|
|
104
|
+
}
|
|
104
105
|
else {
|
|
105
|
-
return new
|
|
106
|
+
return new SdCliClientBuilder(this.rootPath, this.config, this._workspaceRootPath);
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
@@ -11,7 +11,7 @@ export class SdCliBuildResultUtil {
|
|
|
11
11
|
: undefined;
|
|
12
12
|
if (!severity) return undefined;
|
|
13
13
|
|
|
14
|
-
const code =
|
|
14
|
+
const code = `TS${diag.code}`;
|
|
15
15
|
const message = ts.flattenDiagnosticMessageText(diag.messageText, os.EOL);
|
|
16
16
|
|
|
17
17
|
|
|
@@ -49,8 +49,8 @@ export class SdCliBuildResultUtil {
|
|
|
49
49
|
private static _convertFromWebpackError(severity: "warning" | "error", err: webpack.WebpackError): ISdCliPackageBuildResult {
|
|
50
50
|
return {
|
|
51
51
|
filePath: err.file,
|
|
52
|
-
line: err.loc["start"]
|
|
53
|
-
char: err.loc["start"]
|
|
52
|
+
line: err.file ? err.loc["start"]?.line : undefined,
|
|
53
|
+
char: err.file ? err.loc["start"]?.column : undefined,
|
|
54
54
|
code: err.name,
|
|
55
55
|
severity,
|
|
56
56
|
message: err.message
|