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