@simplysm/sd-cli 12.5.16 → 12.5.18

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.
Files changed (34) hide show
  1. package/dist/build-tools/SdCliIndexFileGenerator.js +2 -2
  2. package/dist/build-tools/SdCliIndexFileGenerator.js.map +1 -1
  3. package/dist/build-tools/SdLinter.js +5 -2
  4. package/dist/build-tools/SdLinter.js.map +1 -1
  5. package/dist/build-tools/SdReactBundler.d.ts +24 -0
  6. package/dist/build-tools/SdReactBundler.js +294 -0
  7. package/dist/build-tools/SdReactBundler.js.map +1 -0
  8. package/dist/build-tools/SdReactBundlerContext.d.ts +14 -0
  9. package/dist/build-tools/SdReactBundlerContext.js +59 -0
  10. package/dist/build-tools/SdReactBundlerContext.js.map +1 -0
  11. package/dist/build-tools/SdTsCompiler.js +274 -226
  12. package/dist/build-tools/SdTsCompiler.js.map +1 -1
  13. package/dist/builders/SdCliClientBuilder.js +41 -17
  14. package/dist/builders/SdCliClientBuilder.js.map +1 -1
  15. package/dist/bundle-plugins/sdReactPlugin.d.ts +15 -0
  16. package/dist/bundle-plugins/sdReactPlugin.js +116 -0
  17. package/dist/bundle-plugins/sdReactPlugin.js.map +1 -0
  18. package/dist/entry/SdCliProject.js +2 -2
  19. package/dist/entry/SdCliProject.js.map +1 -1
  20. package/dist/index.d.ts +3 -0
  21. package/dist/index.js +3 -0
  22. package/dist/index.js.map +1 -1
  23. package/package.json +15 -15
  24. package/src/build-tools/SdCliIndexFileGenerator.ts +2 -2
  25. package/src/build-tools/SdLinter.ts +8 -2
  26. package/src/build-tools/SdReactBundler.ts +370 -0
  27. package/src/build-tools/SdReactBundlerContext.ts +71 -0
  28. package/src/build-tools/SdTsCompiler.ts +227 -112
  29. package/src/builders/SdCliClientBuilder.ts +52 -27
  30. package/src/bundle-plugins/sdReactPlugin.ts +160 -0
  31. package/src/entry/SdCliProject.ts +6 -2
  32. package/src/index.ts +3 -0
  33. package/tsconfig.json +5 -11
  34. package/eslint.config.js +0 -1
@@ -1,7 +1,7 @@
1
1
  import ts, { CompilerOptions } from "typescript";
2
2
  import path from "path";
3
3
  import { FsUtil, Logger, PathUtil } from "@simplysm/sd-core-node";
4
- import { NeverEntryError, StringUtil } from "@simplysm/sd-core-common";
4
+ import { StringUtil } from "@simplysm/sd-core-common";
5
5
  import esbuild from "esbuild";
6
6
  import { NgtscProgram, OptimizeFor } from "@angular/compiler-cli";
7
7
  import { createHash } from "crypto";
@@ -18,7 +18,7 @@ export class SdTsCompiler {
18
18
  readonly #parsedTsconfig: ts.ParsedCommandLine;
19
19
  readonly #isForAngular: boolean;
20
20
 
21
- readonly #revDependencyCacheMap = new Map<string, Set<string>>();
21
+ // readonly #revDependencyCacheMap = new Map<string, Set<string>>();
22
22
  readonly #resourceDependencyCacheMap = new Map<string, Set<string>>();
23
23
  readonly #sourceFileCacheMap = new Map<string, ts.SourceFile>();
24
24
  readonly #emittedFilesCacheMap = new Map<
@@ -34,6 +34,7 @@ export class SdTsCompiler {
34
34
 
35
35
  #ngProgram: NgtscProgram | undefined;
36
36
  #program: ts.Program | undefined;
37
+ #builder: ts.EmitAndSemanticDiagnosticsBuilderProgram | undefined;
37
38
 
38
39
  readonly #modifiedFileSet = new Set<string>();
39
40
 
@@ -196,34 +197,41 @@ export class SdTsCompiler {
196
197
  }
197
198
 
198
199
  invalidate(modifiedFileSet: Set<string>) {
199
- this.#modifiedFileSet.adds(...Array.from(modifiedFileSet).map((item) => path.normalize(item)));
200
+ for (const modifiedFile of Array.from(modifiedFileSet).map((item) => path.normalize(item))) {
201
+ this.#modifiedFileSet.add(modifiedFile);
202
+ this.#modifiedFileSet.adds(...(this.#resourceDependencyCacheMap.get(modifiedFile) ?? []));
203
+ }
200
204
  }
201
205
 
202
206
  async buildAsync(): Promise<ISdTsCompilerResult> {
203
- const affectedFileSet = new Set<string>();
207
+ const affectedSourceFileSet = new Set<ts.SourceFile>();
204
208
  const emitFileSet = new Set<string>();
205
209
 
206
210
  this.#debug(`get affected (old deps & old res deps)...`);
207
211
 
208
212
  for (const modifiedFile of this.#modifiedFileSet) {
209
- affectedFileSet.add(modifiedFile);
210
- affectedFileSet.adds(...(this.#revDependencyCacheMap.get(modifiedFile) ?? []));
211
- affectedFileSet.adds(...(this.#resourceDependencyCacheMap.get(modifiedFile) ?? []));
213
+ // affectedFileSet.add(modifiedFile);
214
+ // affectedFileSet.adds(...(this.#revDependencyCacheMap.get(modifiedFile) ?? []));
215
+ // affectedFileSet.adds(...(this.#resourceDependencyCacheMap.get(modifiedFile) ?? []));
212
216
 
213
217
  this.#emittedFilesCacheMap.delete(path.normalize(modifiedFile));
218
+ this.#sourceFileCacheMap.delete(path.normalize(modifiedFile));
219
+ this.#stylesheetBundlingResultMap.delete(path.normalize(modifiedFile));
220
+ this.#watchFileSet.delete(path.normalize(modifiedFile));
214
221
  }
222
+ this.#stylesheetBundler?.invalidate(this.#modifiedFileSet);
215
223
 
216
- this.#debug(`invalidate & clear cache...`);
224
+ // this.#debug(`invalidate & clear cache...`);
217
225
 
218
- this.#stylesheetBundler?.invalidate(this.#modifiedFileSet);
226
+ // this.#stylesheetBundler?.invalidate(affectedFileSet);
219
227
 
220
- for (const affectedFile of affectedFileSet) {
221
- this.#sourceFileCacheMap.delete(path.normalize(affectedFile));
222
- this.#stylesheetBundlingResultMap.delete(path.normalize(affectedFile));
223
- this.#watchFileSet.delete(path.normalize(affectedFile));
224
- }
228
+ // for (const affectedFile of affectedFileSet) {
229
+ // this.#sourceFileCacheMap.delete(path.normalize(affectedFile));
230
+ // this.#stylesheetBundlingResultMap.delete(path.normalize(affectedFile));
231
+ // this.#watchFileSet.delete(path.normalize(affectedFile));
232
+ // }
225
233
 
226
- this.#revDependencyCacheMap.clear();
234
+ // this.#revDependencyCacheMap.clear();
227
235
  this.#resourceDependencyCacheMap.clear();
228
236
 
229
237
  this.#debug(`create program...`);
@@ -245,6 +253,8 @@ export class SdTsCompiler {
245
253
  );
246
254
  }
247
255
 
256
+ this.#debug(`create builder...`);
257
+
248
258
  const baseGetSourceFiles = this.#program.getSourceFiles;
249
259
  this.#program.getSourceFiles = function (...parameters) {
250
260
  const files: readonly (ts.SourceFile & { version?: string })[] = baseGetSourceFiles(...parameters);
@@ -258,7 +268,7 @@ export class SdTsCompiler {
258
268
  return files;
259
269
  };
260
270
 
261
- this.#debug(`create builder...`);
271
+ this.#builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(this.#program, this.#compilerHost, this.#builder);
262
272
 
263
273
  if (this.#ngProgram) {
264
274
  await this.#ngProgram.compiler.analyzeAsync();
@@ -275,113 +285,169 @@ export class SdTsCompiler {
275
285
 
276
286
  this.#debug(`get affected (new deps)...`);
277
287
 
278
- const sourceFileSet = new Set(
279
- this.#program
280
- .getSourceFiles()
281
- .map((sf) => getOrgSourceFile(sf))
282
- .filterExists(),
283
- );
284
-
285
- const depMap = new Map<
286
- string,
287
- {
288
- fileName: string;
289
- importName: string;
290
- exportName?: string;
291
- }[]
292
- >();
293
- for (const sf of sourceFileSet) {
294
- const refs = this.#findDeps(sf);
295
- depMap.set(path.normalize(sf.fileName), refs);
296
- }
288
+ // const sourceFileSet = new Set(
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
+ // }
297
379
 
298
- const allDepMap = new Map<string, Set<string>>();
299
- const getAllDeps = (fileName: string, prevSet?: Set<string>) => {
300
- if (allDepMap.has(fileName)) {
301
- return allDepMap.get(fileName)!;
302
- }
303
-
304
- const result = new Set<string>();
380
+ this.#debug(`get diagnostics...`);
305
381
 
306
- const deps = depMap.get(fileName) ?? [];
307
- result.adds(...deps.map((item) => item.fileName));
382
+ const diagnostics: ts.Diagnostic[] = [];
308
383
 
309
- for (const dep of deps) {
310
- const targetDeps = depMap.get(dep.fileName) ?? [];
384
+ diagnostics.push(
385
+ ...this.#builder.getConfigFileParsingDiagnostics(),
386
+ ...this.#builder.getOptionsDiagnostics(),
387
+ ...this.#builder.getGlobalDiagnostics(),
388
+ );
311
389
 
312
- if (dep.importName === "*") {
313
- for (const targetRefItem of targetDeps.filter((item) => item.exportName != null)) {
314
- if (prevSet?.has(targetRefItem.fileName)) continue;
390
+ /*diagnostics.push(
391
+ ...this.#program.getConfigFileParsingDiagnostics(),
392
+ ...this.#program.getOptionsDiagnostics(),
393
+ ...this.#program.getGlobalDiagnostics(),
394
+ );*/
315
395
 
316
- result.add(targetRefItem.fileName);
317
- result.adds(...getAllDeps(targetRefItem.fileName, new Set<string>(prevSet).adds(...result)));
318
- }
319
- } else {
320
- for (const targetRefItem of targetDeps.filter((item) => item.exportName === dep.importName)) {
321
- if (prevSet?.has(targetRefItem.fileName)) continue;
396
+ if (this.#ngProgram) {
397
+ diagnostics.push(...this.#ngProgram.compiler.getOptionDiagnostics());
398
+ }
322
399
 
323
- result.add(targetRefItem.fileName);
324
- result.adds(...getAllDeps(targetRefItem.fileName, new Set<string>(prevSet).adds(...result)));
400
+ this.#debug(`get diagnostics of files...`);
401
+
402
+ while (true) {
403
+ const affectedFileResult = this.#builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, (sf) => {
404
+ if (
405
+ this.#ngProgram &&
406
+ this.#ngProgram.compiler.ignoreForDiagnostics.has(sf) &&
407
+ sf.fileName.endsWith(".ngtypecheck.ts")
408
+ ) {
409
+ const orgSourceFile = getOrgSourceFile(sf);
410
+ if (orgSourceFile) {
411
+ affectedSourceFileSet.add(orgSourceFile);
325
412
  }
413
+ return true;
326
414
  }
327
- }
415
+ return false;
416
+ });
417
+ if (!affectedFileResult) break;
328
418
 
329
- return result;
330
- };
419
+ const affectedSourceFile = affectedFileResult.affected as ts.SourceFile;
420
+
421
+ affectedSourceFileSet.add(affectedSourceFile);
422
+ }
331
423
 
332
- for (const sf of sourceFileSet) {
333
- const deps = getAllDeps(path.normalize(sf.fileName));
334
- allDepMap.set(path.normalize(sf.fileName), deps);
424
+ for (const affectedSourceFile of affectedSourceFileSet) {
425
+ this.#debug(`get diagnostics of file [${affectedSourceFile.fileName}]`);
335
426
 
336
- for (const dep of getAllDeps(path.normalize(sf.fileName))) {
337
- const depCache = this.#revDependencyCacheMap.getOrCreate(path.normalize(dep), new Set<string>());
338
- depCache.add(path.normalize(sf.fileName));
339
- if (this.#modifiedFileSet.has(path.normalize(dep))) {
340
- affectedFileSet.add(path.normalize(sf.fileName));
341
- }
342
- }
427
+ diagnostics.push(
428
+ ...this.#program.getSyntacticDiagnostics(affectedSourceFile),
429
+ ...this.#program.getSemanticDiagnostics(affectedSourceFile),
430
+ );
343
431
 
344
432
  if (this.#ngProgram) {
345
- if (this.#ngProgram.compiler.ignoreForEmit.has(sf)) {
433
+ if (affectedSourceFile.isDeclarationFile) {
346
434
  continue;
347
435
  }
348
436
 
349
- for (const dep of this.#ngProgram.compiler.getResourceDependencies(sf)) {
350
- const ref = this.#resourceDependencyCacheMap.getOrCreate(path.normalize(dep), new Set<string>());
351
- ref.add(path.normalize(sf.fileName));
352
- if (this.#modifiedFileSet.has(path.normalize(dep))) {
353
- affectedFileSet.add(path.normalize(sf.fileName));
354
- }
355
- }
437
+ diagnostics.push(
438
+ ...this.#ngProgram.compiler.getDiagnosticsForFile(affectedSourceFile, OptimizeFor.WholeProgram),
439
+ );
356
440
  }
357
441
  }
358
442
 
359
- if (affectedFileSet.size === 0) {
360
- this.#debug(`get affected (init)...`);
361
-
362
- for (const sf of this.#program.getSourceFiles()) {
363
- const orgSf = getOrgSourceFile(sf);
364
- if (!orgSf) continue;
365
-
366
- affectedFileSet.add(path.normalize(orgSf.fileName));
443
+ /*
444
+ for (const affectedFile of affectedFileSet) {
445
+ if (!PathUtil.isChildPath(affectedFile, this.#pkgPath)) {
446
+ continue;
367
447
  }
368
- }
369
-
370
- this.#debug(`get diagnostics...`);
371
-
372
- const diagnostics: ts.Diagnostic[] = [];
373
-
374
- diagnostics.push(
375
- ...this.#program.getConfigFileParsingDiagnostics(),
376
- ...this.#program.getOptionsDiagnostics(),
377
- ...this.#program.getGlobalDiagnostics(),
378
- );
379
448
 
380
- if (this.#ngProgram) {
381
- diagnostics.push(...this.#ngProgram.compiler.getOptionDiagnostics());
382
- }
449
+ this.#debug(`get diagnostics of file [${affectedFile}]`);
383
450
 
384
- for (const affectedFile of affectedFileSet) {
385
451
  const affectedSourceFile = this.#program.getSourceFile(affectedFile);
386
452
  if (
387
453
  !affectedSourceFile ||
@@ -390,10 +456,6 @@ export class SdTsCompiler {
390
456
  continue;
391
457
  }
392
458
 
393
- if (!PathUtil.isChildPath(affectedFile, this.#pkgPath)) {
394
- continue;
395
- }
396
-
397
459
  diagnostics.push(
398
460
  ...this.#program.getSyntacticDiagnostics(affectedSourceFile),
399
461
  ...this.#program.getSemanticDiagnostics(affectedSourceFile),
@@ -408,7 +470,7 @@ export class SdTsCompiler {
408
470
  ...this.#ngProgram.compiler.getDiagnosticsForFile(affectedSourceFile, OptimizeFor.WholeProgram),
409
471
  );
410
472
  }
411
- }
473
+ }*/
412
474
 
413
475
  this.#debug(`prepare emit...`);
414
476
 
@@ -423,6 +485,58 @@ export class SdTsCompiler {
423
485
  }
424
486
  (transformers.before ??= []).push(transformKeys(this.#program));
425
487
 
488
+ this.#debug(`prepare emit files...`);
489
+
490
+ while (
491
+ this.#builder.emitNextAffectedFile(
492
+ (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => {
493
+ if (!sourceFiles || sourceFiles.length === 0) {
494
+ this.#compilerHost.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
495
+ return;
496
+ }
497
+
498
+ const sourceFile = ts.getOriginalNode(sourceFiles[0], ts.isSourceFile);
499
+ if (this.#ngProgram) {
500
+ if (this.#ngProgram.compiler.ignoreForEmit.has(sourceFile)) {
501
+ return;
502
+ }
503
+ this.#ngProgram.compiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);
504
+ }
505
+
506
+ const emitFileInfoCaches = this.#emittedFilesCacheMap.getOrCreate(path.normalize(sourceFile.fileName), []);
507
+ if (PathUtil.isChildPath(sourceFile.fileName, this.#pkgPath)) {
508
+ let realFilePath = fileName;
509
+ let realText = text;
510
+ if (PathUtil.isChildPath(realFilePath, path.resolve(this.#distPath, path.basename(this.#pkgPath), "src"))) {
511
+ realFilePath = path.resolve(
512
+ this.#distPath,
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
+ }
523
+
524
+ emitFileInfoCaches.push({
525
+ outAbsPath: realFilePath,
526
+ text: realText,
527
+ });
528
+ } else {
529
+ emitFileInfoCaches.push({ text });
530
+ }
531
+
532
+ emitFileSet.add(path.normalize(sourceFile.fileName));
533
+ },
534
+ undefined,
535
+ undefined,
536
+ transformers,
537
+ )
538
+ ) {}
539
+
426
540
  // affected에 새로 추가된 파일은 포함되지 않는 현상이 있어 getSourceFiles로 바꿈
427
541
  // 비교해보니, 딱히 getSourceFiles라서 더 느려지는것 같지는 않음
428
542
  /*for (const affectedFile of affectedFileSet) {
@@ -435,7 +549,7 @@ export class SdTsCompiler {
435
549
  continue;
436
550
  }*/
437
551
 
438
- for (const sf of sourceFileSet) {
552
+ /*for (const sf of sourceFileSet) {
439
553
  if (this.#emittedFilesCacheMap.has(path.normalize(sf.fileName))) {
440
554
  continue;
441
555
  }
@@ -504,7 +618,7 @@ export class SdTsCompiler {
504
618
  undefined,
505
619
  transformers,
506
620
  );
507
- }
621
+ }*/
508
622
 
509
623
  //-- global style
510
624
  if (
@@ -531,6 +645,7 @@ export class SdTsCompiler {
531
645
 
532
646
  this.#modifiedFileSet.clear();
533
647
 
648
+ const affectedFileSet = new Set(Array.from(affectedSourceFileSet).map((item) => path.normalize(item.fileName)));
534
649
  this.#debug(`build completed`, affectedFileSet, diagnostics.length);
535
650
 
536
651
  //-- result
@@ -550,7 +665,7 @@ export class SdTsCompiler {
550
665
  this.#logger.debug(`[${path.basename(this.#pkgPath)}]`, ...msg);
551
666
  }
552
667
 
553
- #findDeps(sf: ts.SourceFile) {
668
+ /*#findDeps(sf: ts.SourceFile) {
554
669
  const deps: {
555
670
  fileName: string;
556
671
  importName: string;
@@ -604,9 +719,9 @@ export class SdTsCompiler {
604
719
  importName: "*",
605
720
  });
606
721
  }
607
- /*else {
722
+ /!*else {
608
723
  throw new NeverEntryError(`import moduleSymbol: ${sf.fileName} ${node.moduleSpecifier["text"]}`);
609
- }*/
724
+ }*!/
610
725
  } else {
611
726
  const decls = moduleSymbol.getDeclarations();
612
727
  if (!decls) throw new NeverEntryError(`import decls: ${sf.fileName}`);
@@ -634,7 +749,7 @@ export class SdTsCompiler {
634
749
  });
635
750
 
636
751
  return deps;
637
- }
752
+ }*/
638
753
  }
639
754
 
640
755
  export interface ISdTsCompilerResult {
@@ -14,6 +14,7 @@ import { SdCliCordova } from "../build-tools/SdCliCordova";
14
14
  import { SdCliNgRoutesFileGenerator } from "../build-tools/SdCliNgRoutesFileGenerator";
15
15
  import { SdLinter } from "../build-tools/SdLinter";
16
16
  import { SdCliElectron } from "../entry/SdCliElectron";
17
+ import { SdReactBundler } from "../build-tools/SdReactBundler";
17
18
 
18
19
  // import ts from "typescript";
19
20
 
@@ -21,7 +22,7 @@ export class SdCliClientBuilder extends EventEmitter {
21
22
  private readonly _logger = Logger.get(["simplysm", "sd-cli", "SdCliClientBuilder"]);
22
23
  private readonly _pkgConf: ISdCliClientPackageConfig;
23
24
  private readonly _npmConf: INpmConfig;
24
- private _builders?: SdNgBundler[];
25
+ private _builders?: (SdNgBundler | SdReactBundler)[];
25
26
  private _cordova?: SdCliCordova;
26
27
 
27
28
  // #program?: ts.Program;
@@ -129,27 +130,55 @@ export class SdCliClientBuilder extends EventEmitter {
129
130
  if (!this._builders) {
130
131
  this._debug(`BUILD 준비...`);
131
132
 
132
- this._builders = builderTypes.map(
133
- (builderType) =>
134
- new SdNgBundler({
135
- dev: opt.dev,
136
- builderType: builderType,
137
- pkgPath: this._pkgPath,
138
- outputPath:
139
- builderType === "web"
140
- ? path.resolve(this._pkgPath, "dist")
141
- : builderType === "electron" && !opt.dev
142
- ? path.resolve(this._pkgPath, ".electron/src")
143
- : builderType === "cordova" && !opt.dev
144
- ? path.resolve(this._pkgPath, ".cordova/www")
145
- : path.resolve(this._pkgPath, "dist", builderType),
146
- env: {
147
- ...this._pkgConf.env,
148
- ...this._pkgConf.builder?.[builderType]?.env,
149
- },
150
- cordovaConfig: builderType === "cordova" ? this._pkgConf.builder!.cordova : undefined,
151
- }),
152
- );
133
+ if (
134
+ this._npmConf.dependencies &&
135
+ (Object.keys(this._npmConf.dependencies).includes("preact") ||
136
+ Object.keys(this._npmConf.dependencies).includes("react"))
137
+ ) {
138
+ this._builders = builderTypes.map(
139
+ (builderType) =>
140
+ new SdReactBundler({
141
+ dev: opt.dev,
142
+ builderType: builderType,
143
+ pkgPath: this._pkgPath,
144
+ outputPath:
145
+ builderType === "web"
146
+ ? path.resolve(this._pkgPath, "dist")
147
+ : builderType === "electron" && !opt.dev
148
+ ? path.resolve(this._pkgPath, ".electron/src")
149
+ : builderType === "cordova" && !opt.dev
150
+ ? path.resolve(this._pkgPath, ".cordova/www")
151
+ : path.resolve(this._pkgPath, "dist", builderType),
152
+ env: {
153
+ ...this._pkgConf.env,
154
+ ...this._pkgConf.builder?.[builderType]?.env,
155
+ },
156
+ cordovaConfig: builderType === "cordova" ? this._pkgConf.builder!.cordova : undefined,
157
+ }),
158
+ );
159
+ } else {
160
+ this._builders = builderTypes.map(
161
+ (builderType) =>
162
+ new SdNgBundler({
163
+ dev: opt.dev,
164
+ builderType: builderType,
165
+ pkgPath: this._pkgPath,
166
+ outputPath:
167
+ builderType === "web"
168
+ ? path.resolve(this._pkgPath, "dist")
169
+ : builderType === "electron" && !opt.dev
170
+ ? path.resolve(this._pkgPath, ".electron/src")
171
+ : builderType === "cordova" && !opt.dev
172
+ ? path.resolve(this._pkgPath, ".cordova/www")
173
+ : path.resolve(this._pkgPath, "dist", builderType),
174
+ env: {
175
+ ...this._pkgConf.env,
176
+ ...this._pkgConf.builder?.[builderType]?.env,
177
+ },
178
+ cordovaConfig: builderType === "cordova" ? this._pkgConf.builder!.cordova : undefined,
179
+ }),
180
+ );
181
+ }
153
182
  }
154
183
 
155
184
  this._debug(`BUILD & CHECK...`);
@@ -168,11 +197,7 @@ export class SdCliClientBuilder extends EventEmitter {
168
197
  // oldProgram: this.#program
169
198
  // });
170
199
  // const pkgFilePaths = filePaths.filter(item => PathUtil.isChildPath(item, this._pkgPath));
171
- const lintResults = await SdLinter.lintAsync(
172
- this._pkgPath,
173
- affectedFileSet,
174
- firstProgram,
175
- );
200
+ const lintResults = await SdLinter.lintAsync(this._pkgPath, affectedFileSet, firstProgram);
176
201
 
177
202
  if (!opt.dev && this._cordova) {
178
203
  this._debug("CORDOVA BUILD...");