@simplysm/sd-cli 12.5.19 → 12.5.20
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/dist/build-tools/SdNgBundler.d.ts +1 -0
- package/dist/build-tools/SdNgBundler.js +70 -57
- package/dist/build-tools/SdNgBundler.js.map +1 -1
- package/dist/build-tools/SdServerBundler.d.ts +1 -0
- package/dist/build-tools/SdServerBundler.js +8 -7
- package/dist/build-tools/SdServerBundler.js.map +1 -1
- package/dist/build-tools/SdTsCompiler.d.ts +1 -0
- package/dist/build-tools/SdTsCompiler.js +355 -327
- package/dist/build-tools/SdTsCompiler.js.map +1 -1
- package/dist/build-tools/SdTsLibBundler.d.ts +1 -1
- package/dist/build-tools/SdTsLibBundler.js +2 -1
- package/dist/build-tools/SdTsLibBundler.js.map +1 -1
- package/dist/builders/SdCliClientBuilder.js +2 -1
- package/dist/builders/SdCliClientBuilder.js.map +1 -1
- package/dist/builders/SdCliServerBuilder.js +2 -1
- package/dist/builders/SdCliServerBuilder.js.map +1 -1
- package/dist/builders/SdCliTsLibBuilder.js +4 -2
- package/dist/builders/SdCliTsLibBuilder.js.map +1 -1
- package/dist/bundle-plugins/sdNgPlugin.d.ts +1 -0
- package/dist/bundle-plugins/sdNgPlugin.js +38 -23
- package/dist/bundle-plugins/sdNgPlugin.js.map +1 -1
- package/dist/bundle-plugins/sdServerPlugin.d.ts +1 -0
- package/dist/bundle-plugins/sdServerPlugin.js +1 -0
- package/dist/bundle-plugins/sdServerPlugin.js.map +1 -1
- package/dist/entry/SdCliProject.js +7 -4
- package/dist/entry/SdCliProject.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/SdCliPerformanceTime.d.ts +9 -0
- package/dist/utils/SdCliPerformanceTime.js +40 -0
- package/dist/utils/SdCliPerformanceTime.js.map +1 -0
- package/package.json +10 -10
- package/src/build-tools/SdNgBundler.ts +82 -68
- package/src/build-tools/SdServerBundler.ts +22 -20
- package/src/build-tools/SdTsCompiler.ts +341 -357
- package/src/build-tools/SdTsLibBundler.ts +2 -1
- package/src/builders/SdCliClientBuilder.ts +5 -3
- package/src/builders/SdCliServerBuilder.ts +5 -4
- package/src/builders/SdCliTsLibBuilder.ts +7 -4
- package/src/bundle-plugins/sdNgPlugin.ts +44 -23
- package/src/bundle-plugins/sdServerPlugin.ts +2 -0
- package/src/entry/SdCliProject.ts +6 -4
- package/src/index.ts +1 -0
- package/src/utils/SdCliPerformanceTime.ts +42 -0
- package/tsconfig.json +1 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import ts, { CompilerOptions } from "typescript";
|
|
1
|
+
import ts, { CompilerOptions, DiagnosticCategory } from "typescript";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { FsUtil, Logger, PathUtil } from "@simplysm/sd-core-node";
|
|
4
4
|
import { StringUtil } from "@simplysm/sd-core-common";
|
|
5
5
|
import esbuild from "esbuild";
|
|
6
6
|
import { NgtscProgram, OptimizeFor } from "@angular/compiler-cli";
|
|
7
|
-
import { createHash } from "crypto";
|
|
8
7
|
import { ComponentStylesheetBundler } from "@angular/build/src/tools/esbuild/angular/component-stylesheets";
|
|
9
8
|
import { AngularCompilerHost } from "@angular/build/src/tools/angular/angular-host";
|
|
10
9
|
import { transformSupportedBrowsersToTargets } from "@angular/build/src/tools/esbuild/utils";
|
|
11
10
|
import browserslist from "browserslist";
|
|
12
11
|
import { replaceBootstrap } from "@angular/build/src/tools/angular/transformers/jit-bootstrap-transformer";
|
|
12
|
+
import { SdCliPerformanceTimer } from "../utils/SdCliPerformanceTime";
|
|
13
13
|
|
|
14
14
|
export class SdTsCompiler {
|
|
15
15
|
readonly #logger = Logger.get(["simplysm", "sd-cli", "SdTsCompiler"]);
|
|
@@ -17,7 +17,7 @@ export class SdTsCompiler {
|
|
|
17
17
|
readonly #parsedTsconfig: ts.ParsedCommandLine;
|
|
18
18
|
readonly #isForAngular: boolean;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
readonly #revDependencyCacheMap = new Map<string, Set<string>>();
|
|
21
21
|
readonly #resourceDependencyCacheMap = new Map<string, Set<string>>();
|
|
22
22
|
readonly #sourceFileCacheMap = new Map<string, ts.SourceFile>();
|
|
23
23
|
readonly #emittedFilesCacheMap = new Map<
|
|
@@ -33,7 +33,6 @@ export class SdTsCompiler {
|
|
|
33
33
|
|
|
34
34
|
#ngProgram: NgtscProgram | undefined;
|
|
35
35
|
#program: ts.Program | undefined;
|
|
36
|
-
#builder: ts.EmitAndSemanticDiagnosticsBuilderProgram | undefined;
|
|
37
36
|
|
|
38
37
|
readonly #modifiedFileSet = new Set<string>();
|
|
39
38
|
|
|
@@ -43,6 +42,7 @@ export class SdTsCompiler {
|
|
|
43
42
|
readonly #pkgPath: string;
|
|
44
43
|
readonly #distPath: string;
|
|
45
44
|
readonly #globalStyleFilePath?: string;
|
|
45
|
+
readonly #watchScopePaths: string[];
|
|
46
46
|
|
|
47
47
|
readonly #isForBundle: boolean;
|
|
48
48
|
|
|
@@ -51,11 +51,13 @@ export class SdTsCompiler {
|
|
|
51
51
|
additionalOptions: CompilerOptions;
|
|
52
52
|
isForBundle: boolean;
|
|
53
53
|
isDevMode: boolean;
|
|
54
|
+
watchScopePaths: string[];
|
|
54
55
|
globalStyleFilePath?: string;
|
|
55
56
|
}) {
|
|
56
57
|
this.#pkgPath = opt.pkgPath;
|
|
57
58
|
this.#globalStyleFilePath = opt.globalStyleFilePath != null ? path.normalize(opt.globalStyleFilePath) : undefined;
|
|
58
59
|
this.#isForBundle = opt.isForBundle;
|
|
60
|
+
this.#watchScopePaths = opt.watchScopePaths;
|
|
59
61
|
|
|
60
62
|
this.#debug("초기화...");
|
|
61
63
|
|
|
@@ -196,65 +198,64 @@ export class SdTsCompiler {
|
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
invalidate(modifiedFileSet: Set<string>) {
|
|
199
|
-
|
|
200
|
-
this.#modifiedFileSet.add(modifiedFile);
|
|
201
|
-
this.#modifiedFileSet.adds(...(this.#resourceDependencyCacheMap.get(modifiedFile) ?? []));
|
|
202
|
-
}
|
|
201
|
+
this.#modifiedFileSet.adds(...Array.from(modifiedFileSet).map((item) => path.normalize(item)));
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
async buildAsync(): Promise<ISdTsCompilerResult> {
|
|
206
|
-
|
|
205
|
+
let perf = new SdCliPerformanceTimer("esbuild");
|
|
206
|
+
|
|
207
|
+
const affectedFileSet = new Set<string>();
|
|
207
208
|
const emitFileSet = new Set<string>();
|
|
208
209
|
|
|
209
210
|
this.#debug(`get affected (old deps & old res deps)...`);
|
|
210
211
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
perf.run("get affected", () => {
|
|
213
|
+
for (const modifiedFile of this.#modifiedFileSet) {
|
|
214
|
+
affectedFileSet.add(modifiedFile);
|
|
215
|
+
affectedFileSet.adds(...(this.#revDependencyCacheMap.get(modifiedFile) ?? []));
|
|
216
|
+
affectedFileSet.adds(...(this.#resourceDependencyCacheMap.get(modifiedFile) ?? []));
|
|
215
217
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
this.#watchFileSet.delete(path.normalize(modifiedFile));
|
|
220
|
-
}
|
|
221
|
-
this.#stylesheetBundler?.invalidate(this.#modifiedFileSet);
|
|
218
|
+
this.#emittedFilesCacheMap.delete(path.normalize(modifiedFile));
|
|
219
|
+
}
|
|
220
|
+
});
|
|
222
221
|
|
|
223
|
-
|
|
222
|
+
this.#debug(`invalidate & clear cache...`);
|
|
224
223
|
|
|
225
|
-
|
|
224
|
+
perf.run("invalidate & clear cache", () => {
|
|
225
|
+
this.#stylesheetBundler?.invalidate(this.#modifiedFileSet);
|
|
226
226
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
227
|
+
for (const affectedFile of affectedFileSet) {
|
|
228
|
+
this.#sourceFileCacheMap.delete(path.normalize(affectedFile));
|
|
229
|
+
this.#stylesheetBundlingResultMap.delete(path.normalize(affectedFile));
|
|
230
|
+
this.#watchFileSet.delete(path.normalize(affectedFile));
|
|
231
|
+
}
|
|
232
232
|
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
this.#revDependencyCacheMap.clear();
|
|
234
|
+
this.#resourceDependencyCacheMap.clear();
|
|
235
|
+
});
|
|
235
236
|
|
|
236
237
|
this.#debug(`create program...`);
|
|
237
238
|
|
|
238
|
-
|
|
239
|
-
this.#
|
|
240
|
-
this.#
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
this.#
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
239
|
+
perf.run("create program", () => {
|
|
240
|
+
if (this.#isForAngular) {
|
|
241
|
+
this.#ngProgram = new NgtscProgram(
|
|
242
|
+
this.#parsedTsconfig.fileNames,
|
|
243
|
+
this.#parsedTsconfig.options,
|
|
244
|
+
this.#compilerHost,
|
|
245
|
+
this.#ngProgram,
|
|
246
|
+
);
|
|
247
|
+
this.#program = this.#ngProgram.getTsProgram();
|
|
248
|
+
} else {
|
|
249
|
+
this.#program = ts.createProgram(
|
|
250
|
+
this.#parsedTsconfig.fileNames,
|
|
251
|
+
this.#parsedTsconfig.options,
|
|
252
|
+
this.#compilerHost,
|
|
253
|
+
this.#program,
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
256
257
|
|
|
257
|
-
const baseGetSourceFiles = this.#program.getSourceFiles;
|
|
258
|
+
/*const baseGetSourceFiles = this.#program.getSourceFiles;
|
|
258
259
|
this.#program.getSourceFiles = function (...parameters) {
|
|
259
260
|
const files: readonly (ts.SourceFile & { version?: string })[] = baseGetSourceFiles(...parameters);
|
|
260
261
|
|
|
@@ -265,12 +266,12 @@ export class SdTsCompiler {
|
|
|
265
266
|
}
|
|
266
267
|
|
|
267
268
|
return files;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
this.#builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(this.#program, this.#compilerHost, this.#builder);
|
|
269
|
+
};*/
|
|
271
270
|
|
|
272
271
|
if (this.#ngProgram) {
|
|
273
|
-
await
|
|
272
|
+
await perf.run("ng analyze", async () => {
|
|
273
|
+
await this.#ngProgram!.compiler.analyzeAsync();
|
|
274
|
+
});
|
|
274
275
|
}
|
|
275
276
|
|
|
276
277
|
const getOrgSourceFile = (sf: ts.SourceFile) => {
|
|
@@ -284,340 +285,281 @@ export class SdTsCompiler {
|
|
|
284
285
|
|
|
285
286
|
this.#debug(`get affected (new deps)...`);
|
|
286
287
|
|
|
287
|
-
|
|
288
|
-
// this.#program
|
|
289
|
-
// .getSourceFiles()
|
|
290
|
-
// .map((sf) => getOrgSourceFile(sf))
|
|
291
|
-
// .filterExists(),
|
|
292
|
-
// );
|
|
293
|
-
|
|
294
|
-
// const depMap = new Map<
|
|
295
|
-
// string,
|
|
296
|
-
// {
|
|
297
|
-
// fileName: string;
|
|
298
|
-
// importName: string;
|
|
299
|
-
// exportName?: string;
|
|
300
|
-
// }[]
|
|
301
|
-
// >();
|
|
302
|
-
// for (const sf of sourceFileSet) {
|
|
303
|
-
// const refs = this.#findDeps(sf);
|
|
304
|
-
// depMap.set(path.normalize(sf.fileName), refs);
|
|
305
|
-
// }
|
|
306
|
-
//
|
|
307
|
-
// const allDepMap = new Map<string, Set<string>>();
|
|
308
|
-
// const getAllDeps = (fileName: string, prevSet?: Set<string>) => {
|
|
309
|
-
// if (allDepMap.has(fileName)) {
|
|
310
|
-
// return allDepMap.get(fileName)!;
|
|
311
|
-
// }
|
|
312
|
-
//
|
|
313
|
-
// const result = new Set<string>();
|
|
314
|
-
//
|
|
315
|
-
// const deps = depMap.get(fileName) ?? [];
|
|
316
|
-
// result.adds(...deps.map((item) => item.fileName));
|
|
317
|
-
//
|
|
318
|
-
// for (const dep of deps) {
|
|
319
|
-
// const targetDeps = depMap.get(dep.fileName) ?? [];
|
|
320
|
-
//
|
|
321
|
-
// if (dep.importName === "*") {
|
|
322
|
-
// for (const targetRefItem of targetDeps.filter((item) => item.exportName != null)) {
|
|
323
|
-
// if (prevSet?.has(targetRefItem.fileName)) continue;
|
|
324
|
-
//
|
|
325
|
-
// result.add(targetRefItem.fileName);
|
|
326
|
-
// result.adds(...getAllDeps(targetRefItem.fileName, new Set<string>(prevSet).adds(...result)));
|
|
327
|
-
// }
|
|
328
|
-
// } else {
|
|
329
|
-
// for (const targetRefItem of targetDeps.filter((item) => item.exportName === dep.importName)) {
|
|
330
|
-
// if (prevSet?.has(targetRefItem.fileName)) continue;
|
|
331
|
-
//
|
|
332
|
-
// result.add(targetRefItem.fileName);
|
|
333
|
-
// result.adds(...getAllDeps(targetRefItem.fileName, new Set<string>(prevSet).adds(...result)));
|
|
334
|
-
// }
|
|
335
|
-
// }
|
|
336
|
-
// }
|
|
337
|
-
//
|
|
338
|
-
// return result;
|
|
339
|
-
// };
|
|
340
|
-
|
|
341
|
-
// for (const sf of sourceFileSet) {
|
|
342
|
-
// const deps = getAllDeps(path.normalize(sf.fileName));
|
|
343
|
-
// allDepMap.set(path.normalize(sf.fileName), deps);
|
|
344
|
-
//
|
|
345
|
-
// for (const dep of getAllDeps(path.normalize(sf.fileName))) {
|
|
346
|
-
// const depCache = this.#revDependencyCacheMap.getOrCreate(path.normalize(dep), new Set<string>());
|
|
347
|
-
// depCache.add(path.normalize(sf.fileName));
|
|
348
|
-
// if (this.#modifiedFileSet.has(path.normalize(dep))) {
|
|
349
|
-
// affectedFileSet.add(path.normalize(sf.fileName));
|
|
350
|
-
// }
|
|
351
|
-
// }
|
|
352
|
-
//
|
|
353
|
-
// if (this.#ngProgram) {
|
|
354
|
-
// if (this.#ngProgram.compiler.ignoreForEmit.has(sf)) {
|
|
355
|
-
// continue;
|
|
356
|
-
// }
|
|
357
|
-
//
|
|
358
|
-
// for (const dep of this.#ngProgram.compiler.getResourceDependencies(sf)) {
|
|
359
|
-
// const ref = this.#resourceDependencyCacheMap.getOrCreate(path.normalize(dep), new Set<string>());
|
|
360
|
-
// ref.add(path.normalize(sf.fileName));
|
|
361
|
-
// if (this.#modifiedFileSet.has(path.normalize(dep))) {
|
|
362
|
-
// affectedFileSet.add(path.normalize(sf.fileName));
|
|
363
|
-
// }
|
|
364
|
-
// }
|
|
365
|
-
// }
|
|
366
|
-
// }
|
|
367
|
-
|
|
368
|
-
// if (affectedFileSet.size === 0) {
|
|
369
|
-
// this.#debug(`get affected (init)...`);
|
|
370
|
-
//
|
|
371
|
-
// for (const sf of this.#program.getSourceFiles()) {
|
|
372
|
-
// const orgSf = getOrgSourceFile(sf);
|
|
373
|
-
// if (!orgSf) continue;
|
|
374
|
-
//
|
|
375
|
-
// affectedFileSet.add(path.normalize(orgSf.fileName));
|
|
376
|
-
// }
|
|
377
|
-
// }
|
|
288
|
+
const diagnostics: ts.Diagnostic[] = [];
|
|
378
289
|
|
|
379
|
-
|
|
290
|
+
perf.run("get affected (deps)", () => {
|
|
291
|
+
const sourceFileSet = new Set(
|
|
292
|
+
this.#program!.getSourceFiles()
|
|
293
|
+
.map((sf) => getOrgSourceFile(sf))
|
|
294
|
+
.filterExists(),
|
|
295
|
+
);
|
|
380
296
|
|
|
381
|
-
|
|
297
|
+
const depMap = new Map<
|
|
298
|
+
string,
|
|
299
|
+
{
|
|
300
|
+
fileName: string;
|
|
301
|
+
importName: string;
|
|
302
|
+
exportName?: string;
|
|
303
|
+
}[]
|
|
304
|
+
>();
|
|
305
|
+
for (const sf of sourceFileSet) {
|
|
306
|
+
if (!PathUtil.isChildPath(sf.fileName, this.#pkgPath)) {
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
382
309
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
310
|
+
const refs = this.#findDeps(sf);
|
|
311
|
+
diagnostics.push(...refs.filter((item) => "category" in item));
|
|
312
|
+
depMap.set(
|
|
313
|
+
path.normalize(sf.fileName),
|
|
314
|
+
refs
|
|
315
|
+
.filter((item) => "fileName" in item)
|
|
316
|
+
.filter((item) =>
|
|
317
|
+
this.#watchScopePaths.some((scopePath) => PathUtil.isChildPath(item.fileName, scopePath)),
|
|
318
|
+
),
|
|
319
|
+
);
|
|
320
|
+
}
|
|
388
321
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
322
|
+
const allDepMap = new Map<string, Set<string>>();
|
|
323
|
+
const getAllDeps = (fileName: string, prevSet?: Set<string>) => {
|
|
324
|
+
if (allDepMap.has(fileName)) {
|
|
325
|
+
return allDepMap.get(fileName)!;
|
|
326
|
+
}
|
|
394
327
|
|
|
395
|
-
|
|
396
|
-
diagnostics.push(...this.#ngProgram.compiler.getOptionDiagnostics());
|
|
397
|
-
}
|
|
328
|
+
const result = new Set<string>();
|
|
398
329
|
|
|
399
|
-
|
|
330
|
+
const deps = depMap.get(fileName) ?? [];
|
|
331
|
+
result.adds(...deps.map((item) => item.fileName));
|
|
400
332
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
333
|
+
for (const dep of deps) {
|
|
334
|
+
const targetDeps = depMap.get(dep.fileName) ?? [];
|
|
335
|
+
|
|
336
|
+
if (dep.importName === "*") {
|
|
337
|
+
for (const targetRefItem of targetDeps.filter((item) => item.exportName != null)) {
|
|
338
|
+
if (prevSet?.has(targetRefItem.fileName)) continue;
|
|
339
|
+
|
|
340
|
+
result.add(targetRefItem.fileName);
|
|
341
|
+
result.adds(...getAllDeps(targetRefItem.fileName, new Set<string>(prevSet).adds(...result)));
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
for (const targetRefItem of targetDeps.filter((item) => item.exportName === dep.importName)) {
|
|
345
|
+
if (prevSet?.has(targetRefItem.fileName)) continue;
|
|
346
|
+
|
|
347
|
+
result.add(targetRefItem.fileName);
|
|
348
|
+
result.adds(...getAllDeps(targetRefItem.fileName, new Set<string>(prevSet).adds(...result)));
|
|
349
|
+
}
|
|
411
350
|
}
|
|
412
|
-
return true;
|
|
413
351
|
}
|
|
414
|
-
return false;
|
|
415
|
-
});
|
|
416
|
-
if (!affectedFileResult) break;
|
|
417
352
|
|
|
418
|
-
|
|
353
|
+
return result;
|
|
354
|
+
};
|
|
419
355
|
|
|
420
|
-
|
|
421
|
-
|
|
356
|
+
for (const sf of sourceFileSet) {
|
|
357
|
+
const deps = getAllDeps(path.normalize(sf.fileName));
|
|
358
|
+
allDepMap.set(path.normalize(sf.fileName), deps);
|
|
422
359
|
|
|
423
|
-
|
|
424
|
-
|
|
360
|
+
for (const dep of getAllDeps(path.normalize(sf.fileName))) {
|
|
361
|
+
const depCache = this.#revDependencyCacheMap.getOrCreate(path.normalize(dep), new Set<string>());
|
|
362
|
+
depCache.add(path.normalize(sf.fileName));
|
|
363
|
+
if (this.#modifiedFileSet.has(path.normalize(dep))) {
|
|
364
|
+
affectedFileSet.add(path.normalize(sf.fileName));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
425
367
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
368
|
+
if (this.#ngProgram) {
|
|
369
|
+
if (this.#ngProgram.compiler.ignoreForEmit.has(sf)) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
430
372
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
373
|
+
for (const dep of this.#ngProgram.compiler.getResourceDependencies(sf)) {
|
|
374
|
+
const ref = this.#resourceDependencyCacheMap.getOrCreate(path.normalize(dep), new Set<string>());
|
|
375
|
+
ref.add(path.normalize(sf.fileName));
|
|
376
|
+
if (this.#modifiedFileSet.has(path.normalize(dep))) {
|
|
377
|
+
affectedFileSet.add(path.normalize(sf.fileName));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
434
380
|
}
|
|
435
|
-
|
|
436
|
-
diagnostics.push(
|
|
437
|
-
...this.#ngProgram.compiler.getDiagnosticsForFile(affectedSourceFile, OptimizeFor.WholeProgram),
|
|
438
|
-
);
|
|
439
381
|
}
|
|
440
|
-
}
|
|
382
|
+
});
|
|
441
383
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
if (!PathUtil.isChildPath(affectedFile, this.#pkgPath)) {
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
384
|
+
if (affectedFileSet.size === 0) {
|
|
385
|
+
this.#debug(`get affected (init)...`);
|
|
447
386
|
|
|
448
|
-
|
|
387
|
+
perf.run("get affected (init)", () => {
|
|
388
|
+
for (const sf of this.#program!.getSourceFiles()) {
|
|
389
|
+
if (!this.#watchScopePaths.some((scopePath) => PathUtil.isChildPath(sf.fileName, scopePath))) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
449
392
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
!affectedSourceFile ||
|
|
453
|
-
(this.#ngProgram && this.#ngProgram.compiler.ignoreForDiagnostics.has(affectedSourceFile))
|
|
454
|
-
) {
|
|
455
|
-
continue;
|
|
456
|
-
}
|
|
393
|
+
const orgSf = getOrgSourceFile(sf);
|
|
394
|
+
if (!orgSf) continue;
|
|
457
395
|
|
|
396
|
+
affectedFileSet.add(path.normalize(orgSf.fileName));
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
this.#debug(`get diagnostics...`);
|
|
402
|
+
|
|
403
|
+
perf.run("get program diagnostics", () => {
|
|
458
404
|
diagnostics.push(
|
|
459
|
-
...this.#program
|
|
460
|
-
...this.#program
|
|
405
|
+
...this.#program!.getConfigFileParsingDiagnostics(),
|
|
406
|
+
...this.#program!.getOptionsDiagnostics(),
|
|
407
|
+
...this.#program!.getGlobalDiagnostics(),
|
|
461
408
|
);
|
|
462
409
|
|
|
463
410
|
if (this.#ngProgram) {
|
|
464
|
-
|
|
465
|
-
continue;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
diagnostics.push(
|
|
469
|
-
...this.#ngProgram.compiler.getDiagnosticsForFile(affectedSourceFile, OptimizeFor.WholeProgram),
|
|
470
|
-
);
|
|
411
|
+
diagnostics.push(...this.#ngProgram.compiler.getOptionDiagnostics());
|
|
471
412
|
}
|
|
472
|
-
}
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
this.#debug(`get diagnostics of files...`);
|
|
473
416
|
|
|
474
|
-
|
|
417
|
+
perf.run("get file diagnostics", () => {
|
|
418
|
+
for (const affectedFile of affectedFileSet) {
|
|
419
|
+
if (!PathUtil.isChildPath(affectedFile, this.#pkgPath)) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
475
422
|
|
|
476
|
-
|
|
423
|
+
const affectedSourceFile = this.#program!.getSourceFile(affectedFile);
|
|
477
424
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
// (transformers.before ??= []).push(transformKeys(this.#program));
|
|
425
|
+
if (
|
|
426
|
+
!affectedSourceFile ||
|
|
427
|
+
(this.#ngProgram && this.#ngProgram.compiler.ignoreForDiagnostics.has(affectedSourceFile))
|
|
428
|
+
) {
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
486
431
|
|
|
487
|
-
|
|
432
|
+
// this.#debug(`get diagnostics of file ${affectedFile}...`);
|
|
488
433
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
this.#compilerHost.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
434
|
+
diagnostics.push(
|
|
435
|
+
...this.#program!.getSyntacticDiagnostics(affectedSourceFile),
|
|
436
|
+
...this.#program!.getSemanticDiagnostics(affectedSourceFile),
|
|
437
|
+
);
|
|
496
438
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
if (
|
|
439
|
+
if (this.#ngProgram) {
|
|
440
|
+
perf.run("get file diagnostics: ng", () => {
|
|
441
|
+
if (affectedSourceFile.isDeclarationFile) {
|
|
500
442
|
return;
|
|
501
443
|
}
|
|
502
|
-
this.#ngProgram.compiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);
|
|
503
|
-
}
|
|
504
444
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
path.relative(path.resolve(this.#distPath, path.basename(this.#pkgPath), "src"), realFilePath),
|
|
513
|
-
);
|
|
514
|
-
|
|
515
|
-
if (fileName.endsWith(".js.map")) {
|
|
516
|
-
const sourceMapContents = JSON.parse(realText);
|
|
517
|
-
// remove "../../"
|
|
518
|
-
sourceMapContents.sources[0] = sourceMapContents.sources[0].slice(6);
|
|
519
|
-
realText = JSON.stringify(sourceMapContents);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
445
|
+
diagnostics.push(
|
|
446
|
+
...this.#ngProgram!.compiler.getDiagnosticsForFile(affectedSourceFile, OptimizeFor.WholeProgram),
|
|
447
|
+
);
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
});
|
|
522
452
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
text: realText,
|
|
526
|
-
});
|
|
527
|
-
} else {
|
|
528
|
-
emitFileInfoCaches.push({ text });
|
|
529
|
-
}
|
|
453
|
+
perf.run("emit", () => {
|
|
454
|
+
this.#debug(`prepare emit...`);
|
|
530
455
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
// affected에 새로 추가된 파일은 포함되지 않는 현상이 있어 getSourceFiles로 바꿈
|
|
540
|
-
// 비교해보니, 딱히 getSourceFiles라서 더 느려지는것 같지는 않음
|
|
541
|
-
/*for (const affectedFile of affectedFileSet) {
|
|
542
|
-
if (this.#emittedFilesCacheMap.has(affectedFile)) {
|
|
543
|
-
continue;
|
|
456
|
+
let transformers: ts.CustomTransformers = {};
|
|
457
|
+
|
|
458
|
+
if (this.#ngProgram) {
|
|
459
|
+
transformers = {
|
|
460
|
+
...transformers,
|
|
461
|
+
...this.#ngProgram.compiler.prepareEmit().transformers,
|
|
462
|
+
};
|
|
463
|
+
(transformers.before ??= []).push(replaceBootstrap(() => this.#program!.getTypeChecker()));
|
|
544
464
|
}
|
|
465
|
+
// (transformers.before ??= []).push(transformKeys(this.#program));
|
|
545
466
|
|
|
546
|
-
|
|
547
|
-
if (!sf) {
|
|
548
|
-
continue;
|
|
549
|
-
}*/
|
|
467
|
+
this.#debug(`emit for files...`);
|
|
550
468
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
469
|
+
// affected에 새로 추가된 파일은 포함되지 않는 현상이 있어 getSourceFiles로 바꿈
|
|
470
|
+
// 비교해보니, 딱히 getSourceFiles라서 더 느려지는것 같지는 않음
|
|
471
|
+
// 그래도 affected로 다시 테스트
|
|
472
|
+
for (const affectedFile of affectedFileSet) {
|
|
473
|
+
if (this.#emittedFilesCacheMap.has(affectedFile)) {
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
555
476
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
477
|
+
const sf = this.#program!.getSourceFile(affectedFile);
|
|
478
|
+
if (!sf) {
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
559
481
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
482
|
+
// for (const sf of sourceFileSet) {
|
|
483
|
+
/*if (this.#emittedFilesCacheMap.has(path.normalize(sf.fileName))) {
|
|
484
|
+
continue;
|
|
485
|
+
}*/
|
|
563
486
|
|
|
564
|
-
|
|
565
|
-
if (!this.#isForBundle) {
|
|
566
|
-
if (!PathUtil.isChildPath(sf.fileName, this.#pkgPath)) {
|
|
487
|
+
if (sf.isDeclarationFile) {
|
|
567
488
|
continue;
|
|
568
489
|
}
|
|
569
|
-
}
|
|
570
490
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
491
|
+
if (this.#ngProgram?.compiler.ignoreForEmit.has(sf)) {
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (
|
|
496
|
+
this.#ngProgram?.compiler.incrementalCompilation.safeToSkipEmit(sf) &&
|
|
497
|
+
!affectedFileSet.has(path.normalize(sf.fileName))
|
|
498
|
+
) {
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// esbuild를 통해 bundle로 묶어야 하는놈들은 모든 output이 있어야 함.
|
|
503
|
+
if (!this.#isForBundle) {
|
|
504
|
+
if (!PathUtil.isChildPath(sf.fileName, this.#pkgPath)) {
|
|
505
|
+
continue;
|
|
578
506
|
}
|
|
507
|
+
}
|
|
579
508
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
509
|
+
// this.#debug(`emit for`, sf.fileName);
|
|
510
|
+
this.#program!.emit(
|
|
511
|
+
sf,
|
|
512
|
+
(fileName, text, writeByteOrderMark, onError, sourceFiles, data) => {
|
|
513
|
+
if (!sourceFiles || sourceFiles.length === 0) {
|
|
514
|
+
this.#compilerHost.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
|
|
583
515
|
return;
|
|
584
516
|
}
|
|
585
|
-
this.#ngProgram.compiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);
|
|
586
|
-
}
|
|
587
517
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if (PathUtil.isChildPath(realFilePath, path.resolve(this.#distPath, path.basename(this.#pkgPath), "src"))) {
|
|
593
|
-
realFilePath = path.resolve(
|
|
594
|
-
this.#distPath,
|
|
595
|
-
path.relative(path.resolve(this.#distPath, path.basename(this.#pkgPath), "src"), realFilePath),
|
|
596
|
-
);
|
|
597
|
-
|
|
598
|
-
if (fileName.endsWith(".js.map")) {
|
|
599
|
-
const sourceMapContents = JSON.parse(realText);
|
|
600
|
-
// remove "../../"
|
|
601
|
-
sourceMapContents.sources[0] = sourceMapContents.sources[0].slice(6);
|
|
602
|
-
realText = JSON.stringify(sourceMapContents);
|
|
518
|
+
const sourceFile = ts.getOriginalNode(sourceFiles[0], ts.isSourceFile);
|
|
519
|
+
if (this.#ngProgram) {
|
|
520
|
+
if (this.#ngProgram.compiler.ignoreForEmit.has(sourceFile)) {
|
|
521
|
+
return;
|
|
603
522
|
}
|
|
523
|
+
this.#ngProgram.compiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);
|
|
604
524
|
}
|
|
605
525
|
|
|
606
|
-
emitFileInfoCaches.
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
526
|
+
const emitFileInfoCaches = this.#emittedFilesCacheMap.getOrCreate(path.normalize(sourceFile.fileName), []);
|
|
527
|
+
|
|
528
|
+
if (PathUtil.isChildPath(sourceFile.fileName, this.#pkgPath)) {
|
|
529
|
+
let realFilePath = fileName;
|
|
530
|
+
let realText = text;
|
|
531
|
+
if (
|
|
532
|
+
PathUtil.isChildPath(realFilePath, path.resolve(this.#distPath, path.basename(this.#pkgPath), "src"))
|
|
533
|
+
) {
|
|
534
|
+
realFilePath = path.resolve(
|
|
535
|
+
this.#distPath,
|
|
536
|
+
path.relative(path.resolve(this.#distPath, path.basename(this.#pkgPath), "src"), realFilePath),
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
if (fileName.endsWith(".js.map")) {
|
|
540
|
+
const sourceMapContents = JSON.parse(realText);
|
|
541
|
+
// remove "../../"
|
|
542
|
+
sourceMapContents.sources[0] = sourceMapContents.sources[0].slice(6);
|
|
543
|
+
realText = JSON.stringify(sourceMapContents);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
613
546
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
547
|
+
emitFileInfoCaches.push({
|
|
548
|
+
outAbsPath: realFilePath,
|
|
549
|
+
text: realText,
|
|
550
|
+
});
|
|
551
|
+
} else {
|
|
552
|
+
emitFileInfoCaches.push({ text });
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
emitFileSet.add(path.normalize(sourceFile.fileName));
|
|
556
|
+
},
|
|
557
|
+
undefined,
|
|
558
|
+
undefined,
|
|
559
|
+
transformers,
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
});
|
|
621
563
|
|
|
622
564
|
//-- global style
|
|
623
565
|
if (
|
|
@@ -627,30 +569,31 @@ export class SdTsCompiler {
|
|
|
627
569
|
) {
|
|
628
570
|
this.#debug(`bundle global style...`);
|
|
629
571
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
572
|
+
await perf.run("bundle global style", async () => {
|
|
573
|
+
const data = await FsUtil.readFileAsync(this.#globalStyleFilePath!);
|
|
574
|
+
const contents = await this.#bundleStylesheetAsync(data, this.#globalStyleFilePath!, this.#globalStyleFilePath);
|
|
575
|
+
const emitFileInfos = this.#emittedFilesCacheMap.getOrCreate(this.#globalStyleFilePath!, []);
|
|
576
|
+
emitFileInfos.push({
|
|
577
|
+
outAbsPath: path.resolve(
|
|
578
|
+
this.#pkgPath,
|
|
579
|
+
path.relative(path.resolve(this.#pkgPath, "src"), this.#globalStyleFilePath!).replace(/\.scss$/, ".css"),
|
|
580
|
+
),
|
|
581
|
+
text: contents,
|
|
582
|
+
});
|
|
583
|
+
emitFileSet.add(this.#globalStyleFilePath!);
|
|
639
584
|
});
|
|
640
|
-
emitFileSet.add(this.#globalStyleFilePath);
|
|
641
585
|
}
|
|
642
586
|
|
|
643
587
|
//-- init
|
|
644
588
|
|
|
645
589
|
this.#modifiedFileSet.clear();
|
|
646
590
|
|
|
647
|
-
|
|
648
|
-
this.#debug(`build completed`, affectedFileSet, diagnostics.length);
|
|
591
|
+
this.#debug(`build completed`, perf.toString());
|
|
649
592
|
|
|
650
593
|
//-- result
|
|
651
594
|
|
|
652
595
|
return {
|
|
653
|
-
program: this.#program
|
|
596
|
+
program: this.#program!,
|
|
654
597
|
typescriptDiagnostics: diagnostics,
|
|
655
598
|
stylesheetBundlingResultMap: this.#stylesheetBundlingResultMap,
|
|
656
599
|
emittedFilesCacheMap: this.#emittedFilesCacheMap,
|
|
@@ -664,12 +607,15 @@ export class SdTsCompiler {
|
|
|
664
607
|
this.#logger.debug(`[${path.basename(this.#pkgPath)}]`, ...msg);
|
|
665
608
|
}
|
|
666
609
|
|
|
667
|
-
|
|
668
|
-
const deps:
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
610
|
+
#findDeps(sf: ts.SourceFile) {
|
|
611
|
+
const deps: (
|
|
612
|
+
| {
|
|
613
|
+
fileName: string;
|
|
614
|
+
importName: string;
|
|
615
|
+
exportName?: string;
|
|
616
|
+
}
|
|
617
|
+
| ts.Diagnostic
|
|
618
|
+
)[] = [];
|
|
673
619
|
|
|
674
620
|
const tc = this.#program!.getTypeChecker();
|
|
675
621
|
|
|
@@ -677,10 +623,30 @@ export class SdTsCompiler {
|
|
|
677
623
|
if (ts.isExportDeclaration(node)) {
|
|
678
624
|
if (node.moduleSpecifier) {
|
|
679
625
|
const moduleSymbol = tc.getSymbolAtLocation(node.moduleSpecifier);
|
|
680
|
-
if (!moduleSymbol)
|
|
626
|
+
if (!moduleSymbol) {
|
|
627
|
+
deps.push({
|
|
628
|
+
category: DiagnosticCategory.Error,
|
|
629
|
+
code: -1,
|
|
630
|
+
file: sf,
|
|
631
|
+
start: node.getStart(),
|
|
632
|
+
length: node.getEnd() - node.getStart(),
|
|
633
|
+
messageText: `export moduleSymbol not found`,
|
|
634
|
+
});
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
681
637
|
|
|
682
638
|
const decls = moduleSymbol.getDeclarations();
|
|
683
|
-
if (!decls)
|
|
639
|
+
if (!decls) {
|
|
640
|
+
deps.push({
|
|
641
|
+
category: DiagnosticCategory.Error,
|
|
642
|
+
code: -1,
|
|
643
|
+
file: sf,
|
|
644
|
+
start: node.getStart(),
|
|
645
|
+
length: node.getEnd() - node.getStart(),
|
|
646
|
+
messageText: `export decls not found`,
|
|
647
|
+
});
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
684
650
|
|
|
685
651
|
const namedBindings = node.exportClause;
|
|
686
652
|
if (namedBindings && ts.isNamedExports(namedBindings)) {
|
|
@@ -695,7 +661,15 @@ export class SdTsCompiler {
|
|
|
695
661
|
}
|
|
696
662
|
} else {
|
|
697
663
|
if (!moduleSymbol.exports) {
|
|
698
|
-
|
|
664
|
+
deps.push({
|
|
665
|
+
category: DiagnosticCategory.Error,
|
|
666
|
+
code: -1,
|
|
667
|
+
file: sf,
|
|
668
|
+
start: node.getStart(),
|
|
669
|
+
length: node.getEnd() - node.getStart(),
|
|
670
|
+
messageText: `moduleSymbol exports not found`,
|
|
671
|
+
});
|
|
672
|
+
return;
|
|
699
673
|
}
|
|
700
674
|
|
|
701
675
|
for (const decl of decls) {
|
|
@@ -718,12 +692,22 @@ export class SdTsCompiler {
|
|
|
718
692
|
importName: "*",
|
|
719
693
|
});
|
|
720
694
|
}
|
|
721
|
-
|
|
695
|
+
/*else {
|
|
722
696
|
throw new NeverEntryError(`import moduleSymbol: ${sf.fileName} ${node.moduleSpecifier["text"]}`);
|
|
723
|
-
}
|
|
697
|
+
}*/
|
|
724
698
|
} else {
|
|
725
699
|
const decls = moduleSymbol.getDeclarations();
|
|
726
|
-
if (!decls)
|
|
700
|
+
if (!decls) {
|
|
701
|
+
deps.push({
|
|
702
|
+
category: DiagnosticCategory.Error,
|
|
703
|
+
code: -1,
|
|
704
|
+
file: sf,
|
|
705
|
+
start: node.getStart(),
|
|
706
|
+
length: node.getEnd() - node.getStart(),
|
|
707
|
+
messageText: `import decls not found`,
|
|
708
|
+
});
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
727
711
|
|
|
728
712
|
const namedBindings = node.importClause?.namedBindings;
|
|
729
713
|
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
@@ -748,7 +732,7 @@ export class SdTsCompiler {
|
|
|
748
732
|
});
|
|
749
733
|
|
|
750
734
|
return deps;
|
|
751
|
-
}
|
|
735
|
+
}
|
|
752
736
|
}
|
|
753
737
|
|
|
754
738
|
export interface ISdTsCompilerResult {
|