@simplysm/sd-cli 14.0.11 → 14.0.12

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 (263) hide show
  1. package/README.md +58 -253
  2. package/dist/angular/client-transform-stylesheet.js +1 -1
  3. package/dist/angular/client-transform-stylesheet.js.map +1 -1
  4. package/dist/angular/vite-angular-plugin.d.ts +1 -1
  5. package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
  6. package/dist/angular/vite-angular-plugin.js +60 -34
  7. package/dist/angular/vite-angular-plugin.js.map +1 -1
  8. package/dist/angular/vite-postcss-inline-plugin.d.ts +1 -1
  9. package/dist/angular/vite-postcss-inline-plugin.js +1 -1
  10. package/dist/capacitor/capacitor.d.ts +14 -2
  11. package/dist/capacitor/capacitor.d.ts.map +1 -1
  12. package/dist/capacitor/capacitor.js +131 -17
  13. package/dist/capacitor/capacitor.js.map +1 -1
  14. package/dist/commands/build.d.ts +3 -10
  15. package/dist/commands/build.d.ts.map +1 -1
  16. package/dist/commands/build.js +3 -10
  17. package/dist/commands/build.js.map +1 -1
  18. package/dist/commands/check.js +3 -3
  19. package/dist/commands/check.js.map +1 -1
  20. package/dist/commands/dev.d.ts +3 -9
  21. package/dist/commands/dev.d.ts.map +1 -1
  22. package/dist/commands/dev.js +3 -9
  23. package/dist/commands/dev.js.map +1 -1
  24. package/dist/commands/device.d.ts +3 -3
  25. package/dist/commands/device.js +5 -5
  26. package/dist/commands/device.js.map +1 -1
  27. package/dist/commands/publish.d.ts +1 -1
  28. package/dist/commands/publish.d.ts.map +1 -1
  29. package/dist/commands/publish.js +18 -26
  30. package/dist/commands/publish.js.map +1 -1
  31. package/dist/commands/replace-deps.d.ts +3 -3
  32. package/dist/commands/replace-deps.d.ts.map +1 -1
  33. package/dist/commands/replace-deps.js +1 -1
  34. package/dist/commands/typecheck.d.ts +4 -3
  35. package/dist/commands/typecheck.d.ts.map +1 -1
  36. package/dist/commands/typecheck.js +5 -11
  37. package/dist/commands/typecheck.js.map +1 -1
  38. package/dist/commands/watch.d.ts +9 -9
  39. package/dist/commands/watch.js +9 -9
  40. package/dist/electron/electron.d.ts.map +1 -1
  41. package/dist/electron/electron.js +42 -3
  42. package/dist/electron/electron.js.map +1 -1
  43. package/dist/engines/BaseEngine.d.ts +1 -1
  44. package/dist/engines/BaseEngine.d.ts.map +1 -1
  45. package/dist/engines/BaseEngine.js +3 -1
  46. package/dist/engines/BaseEngine.js.map +1 -1
  47. package/dist/engines/NgtscEngine.d.ts +7 -7
  48. package/dist/engines/NgtscEngine.d.ts.map +1 -1
  49. package/dist/engines/NgtscEngine.js +3 -3
  50. package/dist/engines/ServerEsbuildEngine.d.ts +7 -7
  51. package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
  52. package/dist/engines/ServerEsbuildEngine.js +3 -3
  53. package/dist/engines/TscEngine.d.ts +7 -7
  54. package/dist/engines/TscEngine.d.ts.map +1 -1
  55. package/dist/engines/TscEngine.js +3 -3
  56. package/dist/engines/ViteEngine.d.ts +1 -1
  57. package/dist/engines/ViteEngine.d.ts.map +1 -1
  58. package/dist/engines/ViteEngine.js +7 -12
  59. package/dist/engines/ViteEngine.js.map +1 -1
  60. package/dist/engines/index.d.ts +5 -5
  61. package/dist/engines/index.js +5 -5
  62. package/dist/engines/types.d.ts +20 -20
  63. package/dist/engines/types.d.ts.map +1 -1
  64. package/dist/infra/ResultCollector.d.ts +9 -9
  65. package/dist/infra/ResultCollector.js +8 -8
  66. package/dist/infra/SignalHandler.d.ts +7 -7
  67. package/dist/infra/SignalHandler.js +7 -7
  68. package/dist/infra/WorkerManager.d.ts +14 -14
  69. package/dist/infra/WorkerManager.js +14 -14
  70. package/dist/orchestrators/BuildOrchestrator.d.ts +25 -25
  71. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  72. package/dist/orchestrators/BuildOrchestrator.js +29 -29
  73. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  74. package/dist/orchestrators/DevWatchOrchestrator.d.ts +7 -7
  75. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
  76. package/dist/orchestrators/DevWatchOrchestrator.js +34 -34
  77. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
  78. package/dist/sd-cli-entry.d.ts +2 -2
  79. package/dist/sd-cli-entry.d.ts.map +1 -1
  80. package/dist/sd-cli-entry.js +15 -8
  81. package/dist/sd-cli-entry.js.map +1 -1
  82. package/dist/sd-cli.d.ts +3 -3
  83. package/dist/sd-cli.js +16 -16
  84. package/dist/sd-cli.js.map +1 -1
  85. package/dist/sd-config.types.d.ts +105 -105
  86. package/dist/sd-config.types.d.ts.map +1 -1
  87. package/dist/utils/angular-compiler.js +5 -5
  88. package/dist/utils/angular-compiler.js.map +1 -1
  89. package/dist/utils/build-env.d.ts +1 -1
  90. package/dist/utils/build-env.js +1 -1
  91. package/dist/utils/concurrency.d.ts +7 -7
  92. package/dist/utils/concurrency.js +7 -7
  93. package/dist/utils/copy-public.d.ts +9 -9
  94. package/dist/utils/copy-public.js +17 -17
  95. package/dist/utils/copy-public.js.map +1 -1
  96. package/dist/utils/copy-src.d.ts +9 -9
  97. package/dist/utils/copy-src.js +11 -11
  98. package/dist/utils/copy-src.js.map +1 -1
  99. package/dist/utils/engine-stop.d.ts +8 -9
  100. package/dist/utils/engine-stop.d.ts.map +1 -1
  101. package/dist/utils/engine-stop.js +9 -10
  102. package/dist/utils/engine-stop.js.map +1 -1
  103. package/dist/utils/esbuild-config.d.ts +23 -23
  104. package/dist/utils/esbuild-config.d.ts.map +1 -1
  105. package/dist/utils/esbuild-config.js +25 -25
  106. package/dist/utils/esbuild-config.js.map +1 -1
  107. package/dist/utils/lint-with-program.d.ts +15 -15
  108. package/dist/utils/lint-with-program.d.ts.map +1 -1
  109. package/dist/utils/lint-with-program.js +29 -29
  110. package/dist/utils/lint-with-program.js.map +1 -1
  111. package/dist/utils/ngtsc-build-core.d.ts +8 -8
  112. package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
  113. package/dist/utils/ngtsc-build-core.js +14 -14
  114. package/dist/utils/ngtsc-build-core.js.map +1 -1
  115. package/dist/utils/output-path-rewriter.d.ts +14 -14
  116. package/dist/utils/output-path-rewriter.js +18 -18
  117. package/dist/utils/output-path-rewriter.js.map +1 -1
  118. package/dist/utils/output-utils.d.ts +6 -6
  119. package/dist/utils/output-utils.js +11 -11
  120. package/dist/utils/output-utils.js.map +1 -1
  121. package/dist/utils/package-utils.d.ts +21 -21
  122. package/dist/utils/package-utils.d.ts.map +1 -1
  123. package/dist/utils/package-utils.js +56 -45
  124. package/dist/utils/package-utils.js.map +1 -1
  125. package/dist/utils/replace-deps.d.ts +25 -25
  126. package/dist/utils/replace-deps.d.ts.map +1 -1
  127. package/dist/utils/replace-deps.js +84 -65
  128. package/dist/utils/replace-deps.js.map +1 -1
  129. package/dist/utils/sd-config.d.ts +3 -3
  130. package/dist/utils/sd-config.js +3 -3
  131. package/dist/utils/tsc-build.d.ts +13 -13
  132. package/dist/utils/tsc-build.d.ts.map +1 -1
  133. package/dist/utils/tsc-build.js +9 -9
  134. package/dist/utils/tsc-build.js.map +1 -1
  135. package/dist/utils/tsconfig.d.ts +11 -9
  136. package/dist/utils/tsconfig.d.ts.map +1 -1
  137. package/dist/utils/tsconfig.js +11 -9
  138. package/dist/utils/tsconfig.js.map +1 -1
  139. package/dist/utils/typecheck-non-package.d.ts +5 -6
  140. package/dist/utils/typecheck-non-package.d.ts.map +1 -1
  141. package/dist/utils/typecheck-non-package.js +7 -8
  142. package/dist/utils/typecheck-non-package.js.map +1 -1
  143. package/dist/utils/typecheck-serialization.d.ts +8 -8
  144. package/dist/utils/typecheck-serialization.d.ts.map +1 -1
  145. package/dist/utils/typecheck-serialization.js +12 -16
  146. package/dist/utils/typecheck-serialization.js.map +1 -1
  147. package/dist/utils/vite-config.d.ts +8 -5
  148. package/dist/utils/vite-config.d.ts.map +1 -1
  149. package/dist/utils/vite-config.js +36 -29
  150. package/dist/utils/vite-config.js.map +1 -1
  151. package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
  152. package/dist/utils/vite-scope-watch-plugin.js +1 -1
  153. package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
  154. package/dist/utils/worker-events.d.ts +12 -12
  155. package/dist/utils/worker-events.d.ts.map +1 -1
  156. package/dist/utils/worker-events.js +10 -10
  157. package/dist/utils/worker-events.js.map +1 -1
  158. package/dist/utils/worker-utils.d.ts +12 -13
  159. package/dist/utils/worker-utils.d.ts.map +1 -1
  160. package/dist/utils/worker-utils.js +12 -13
  161. package/dist/utils/worker-utils.js.map +1 -1
  162. package/dist/vitest-plugin.d.ts.map +1 -1
  163. package/dist/vitest-plugin.js +5 -7
  164. package/dist/vitest-plugin.js.map +1 -1
  165. package/dist/workers/client.worker.d.ts +4 -2
  166. package/dist/workers/client.worker.d.ts.map +1 -1
  167. package/dist/workers/client.worker.js +209 -1
  168. package/dist/workers/client.worker.js.map +1 -1
  169. package/dist/workers/library-build.worker.d.ts +1 -1
  170. package/dist/workers/library-build.worker.d.ts.map +1 -1
  171. package/dist/workers/library-build.worker.js +7 -7
  172. package/dist/workers/library-build.worker.js.map +1 -1
  173. package/dist/workers/lint.worker.d.ts +2 -2
  174. package/dist/workers/lint.worker.js +2 -2
  175. package/dist/workers/ngtsc-build.worker.js +30 -30
  176. package/dist/workers/ngtsc-build.worker.js.map +1 -1
  177. package/dist/workers/server-build.worker.d.ts +17 -17
  178. package/dist/workers/server-build.worker.d.ts.map +1 -1
  179. package/dist/workers/server-build.worker.js +46 -46
  180. package/dist/workers/server-build.worker.js.map +1 -1
  181. package/dist/workers/server-runtime.worker.d.ts +7 -7
  182. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  183. package/dist/workers/server-runtime.worker.js +17 -17
  184. package/dist/workers/server-runtime.worker.js.map +1 -1
  185. package/docs/config.md +340 -0
  186. package/docs/publish-configuration-types.md +87 -0
  187. package/docs/pwa-configuration-types.md +55 -0
  188. package/docs/vitest-plugin.md +47 -0
  189. package/package.json +9 -7
  190. package/src/angular/client-transform-stylesheet.ts +1 -1
  191. package/src/angular/vite-angular-plugin.ts +70 -37
  192. package/src/angular/vite-postcss-inline-plugin.ts +1 -1
  193. package/src/capacitor/capacitor.ts +159 -23
  194. package/src/commands/build.ts +3 -10
  195. package/src/commands/check.ts +3 -3
  196. package/src/commands/dev.ts +3 -9
  197. package/src/commands/device.ts +5 -5
  198. package/src/commands/publish.ts +30 -26
  199. package/src/commands/replace-deps.ts +3 -3
  200. package/src/commands/typecheck.ts +7 -13
  201. package/src/commands/watch.ts +9 -9
  202. package/src/electron/electron.ts +49 -4
  203. package/src/engines/BaseEngine.ts +4 -1
  204. package/src/engines/NgtscEngine.ts +7 -7
  205. package/src/engines/ServerEsbuildEngine.ts +7 -7
  206. package/src/engines/TscEngine.ts +7 -7
  207. package/src/engines/ViteEngine.ts +8 -13
  208. package/src/engines/index.ts +5 -5
  209. package/src/engines/types.ts +20 -20
  210. package/src/infra/ResultCollector.ts +9 -9
  211. package/src/infra/SignalHandler.ts +7 -7
  212. package/src/infra/WorkerManager.ts +14 -14
  213. package/src/orchestrators/BuildOrchestrator.ts +37 -37
  214. package/src/orchestrators/DevWatchOrchestrator.ts +36 -36
  215. package/src/sd-cli-entry.ts +15 -8
  216. package/src/sd-cli.ts +16 -16
  217. package/src/sd-config.types.ts +107 -107
  218. package/src/utils/angular-compiler.ts +5 -5
  219. package/src/utils/build-env.ts +1 -1
  220. package/src/utils/concurrency.ts +7 -7
  221. package/src/utils/copy-public.ts +17 -17
  222. package/src/utils/copy-src.ts +11 -11
  223. package/src/utils/engine-stop.ts +9 -10
  224. package/src/utils/esbuild-config.ts +29 -29
  225. package/src/utils/lint-with-program.ts +34 -34
  226. package/src/utils/ngtsc-build-core.ts +17 -17
  227. package/src/utils/output-path-rewriter.ts +18 -18
  228. package/src/utils/output-utils.ts +11 -11
  229. package/src/utils/package-utils.ts +57 -45
  230. package/src/utils/replace-deps.ts +92 -67
  231. package/src/utils/sd-config.ts +3 -3
  232. package/src/utils/tsc-build.ts +18 -18
  233. package/src/utils/tsconfig.ts +11 -9
  234. package/src/utils/typecheck-non-package.ts +7 -8
  235. package/src/utils/typecheck-serialization.ts +13 -15
  236. package/src/utils/vite-config.ts +45 -35
  237. package/src/utils/vite-scope-watch-plugin.ts +6 -1
  238. package/src/utils/worker-events.ts +16 -16
  239. package/src/utils/worker-utils.ts +12 -13
  240. package/src/vitest-plugin.ts +5 -8
  241. package/src/workers/client.worker.ts +236 -2
  242. package/src/workers/library-build.worker.ts +8 -8
  243. package/src/workers/lint.worker.ts +2 -2
  244. package/src/workers/ngtsc-build.worker.ts +31 -31
  245. package/src/workers/server-build.worker.ts +60 -60
  246. package/src/workers/server-runtime.worker.ts +22 -22
  247. package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +1 -0
  248. package/tests/angular/vite-angular-plugin-hmr.spec.ts +78 -0
  249. package/tests/angular/vite-angular-plugin.spec.ts +67 -0
  250. package/tests/capacitor/capacitor-build.spec.ts +6 -4
  251. package/tests/capacitor/capacitor-icon.spec.ts +7 -5
  252. package/tests/capacitor/capacitor-init.spec.ts +120 -10
  253. package/tests/capacitor/capacitor-run.spec.ts +14 -17
  254. package/tests/capacitor/capacitor-workspace.spec.ts +5 -3
  255. package/tests/commands/check.spec.ts +2 -2
  256. package/tests/commands/publish.spec.ts +2 -2
  257. package/tests/commands/typecheck.spec.ts +8 -0
  258. package/tests/electron/electron.spec.ts +12 -10
  259. package/tests/engines/base-engine.spec.ts +37 -0
  260. package/tests/engines/vite-engine.spec.ts +115 -3
  261. package/tests/utils/vite-config.spec.ts +144 -90
  262. package/tests/workers/client-worker.spec.ts +690 -0
  263. package/tests/workers/server-build-worker.spec.ts +3 -3
@@ -4,16 +4,10 @@ import {
4
4
  } from "../orchestrators/DevWatchOrchestrator";
5
5
 
6
6
  /**
7
- * Run Server packages in development mode.
7
+ * DevWatchOrchestrator를 통해 서버 패키지를 개발 모드로 실행한다.
8
8
  *
9
- * - Load `sd.config.ts` to check build target info per package (required)
10
- * - `server` target: Server Build Worker + Server Runtime Worker
11
- * - `client` target: recognized but skipped (BuildEngine not yet implemented)
12
- * - Library packages excluded from dev mode
13
- * - Terminate with SIGINT/SIGTERM signals
14
- *
15
- * @param options - dev execution options (targets, options)
16
- * @returns resolves on termination signal
9
+ * @param options - 개발 모드 실행 옵션 (targets, options)
10
+ * @returns 종료 시그널 수신 resolve
17
11
  */
18
12
  export async function runDev(options: Omit<DevWatchOrchestratorOptions, "mode">): Promise<void> {
19
13
  const orchestrator = new DevWatchOrchestrator({ mode: "dev", ...options });
@@ -14,10 +14,10 @@ export interface DeviceOptions {
14
14
  }
15
15
 
16
16
  /**
17
- * Run native app on device/desktop.
17
+ * 네이티브 앱을 디바이스/데스크톱에서 실행한다.
18
18
  *
19
- * - Electron config takes priority over Capacitor when both are present.
20
- * - If --url is not provided, auto-generates from sd.config.ts server port.
19
+ * - Electron 설정이 Capacitor보다 우선한다.
20
+ * - --url 제공되지 않으면 sd.config.ts 서버 포트로 자동 생성한다.
21
21
  */
22
22
  export async function runDevice(options: DeviceOptions): Promise<void> {
23
23
  const cwd = process.cwd();
@@ -34,7 +34,7 @@ export async function runDevice(options: DeviceOptions): Promise<void> {
34
34
  const clientConfig = pkgConfig;
35
35
  const pkgDir = pathx.posixResolve(cwd, "packages", options.package);
36
36
 
37
- // Determine server URL
37
+ // 서버 URL 결정
38
38
  let serverUrl = options.url;
39
39
  if (serverUrl == null) {
40
40
  if (typeof clientConfig.server === "number") {
@@ -46,7 +46,7 @@ export async function runDevice(options: DeviceOptions): Promise<void> {
46
46
  }
47
47
  }
48
48
 
49
- // Electron takes priority over Capacitor (v13 behavior)
49
+ // Electron Capacitor보다 우선
50
50
  if (clientConfig.electron != null) {
51
51
  logger.start(`${options.package} (electron) 실행 중...`);
52
52
  const electron = await Electron.create(pkgDir, clientConfig.electron, clientConfig.exclude);
@@ -144,7 +144,7 @@ async function ensureSshAuth(
144
144
  const privateKeyData = fs.readFileSync(keyPath);
145
145
  const publicKey = fs.readFileSync(pubKeyPath, "utf-8").trim();
146
146
 
147
- // 개인키가 암호화되어 있는지 확인
147
+ // 개인키 파싱 시도 (암호화 또는 형식 오류 시 Error 반환)
148
148
  const parsed = utils.parseKey(privateKeyData);
149
149
  const isKeyEncrypted = parsed instanceof Error;
150
150
  const sshAgent = process.env["SSH_AUTH_SOCK"];
@@ -352,7 +352,7 @@ async function publishPackage(
352
352
  logger.debug(`[${pkgName}] pnpm ${args.join(" ")}`);
353
353
  }
354
354
 
355
- await cpx.exec("pnpm", args, { cwd: pkgPath });
355
+ await cpx.spawn("pnpm", args, { cwd: pkgPath });
356
356
  } else if (publishConfig.type === "local-directory") {
357
357
  // 로컬 디렉토리에 복사
358
358
  const targetPath = replaceEnvVariables(publishConfig.path, version, projectPath);
@@ -466,7 +466,7 @@ async function computePublishLevels(
466
466
  * 2. 버전 업그레이드 (package.json + 템플릿)
467
467
  * 3. 빌드
468
468
  * 4. Git commit/tag/push (변경된 파일만 명시적으로 스테이징)
469
- * 5. pnpm 배포
469
+ * 5. 패키지 배포 (npm/로컬 디렉토리/스토리지)
470
470
  * 6. postPublish (실패해도 계속 진행)
471
471
  */
472
472
  export async function runPublish(options: PublishOptions): Promise<void> {
@@ -559,18 +559,18 @@ export async function runPublish(options: PublishOptions): Promise<void> {
559
559
  if (publishPackages.some((p) => p.config.type === "npm")) {
560
560
  logger.debug("npm 인증 검증 중...");
561
561
  try {
562
- const { stdout: whoami } = await cpx.exec("npm", ["whoami"]);
562
+ const { stdout: whoami } = await cpx.spawn("npm", ["whoami"]);
563
563
  if (whoami.trim() === "") {
564
564
  throw new Error("npm 로그인 정보를 찾을 수 없습니다.");
565
565
  }
566
566
  logger.debug(`npm 로그인 확인됨: ${whoami.trim()}`);
567
- } catch (err) {
568
- logger.error(`npm whoami 실패:`, err);
569
- /*logger.error(
570
- "npm token is invalid or expired.\n" +
571
- "Create a Granular Access Token at https://www.npmjs.com/settings/~/tokens, then:\n" +
572
- " npm config set //registry.npmjs.org/:_authToken <token>",
573
- );*/
567
+ } catch {
568
+ logger.error(
569
+ "npm 인증 실패. 로그인 상태를 확인해주세요.\n" +
570
+ " npm whoami # 현재 로그인 확인\n" +
571
+ " npm login # 로그인\n" +
572
+ " npm config set //registry.npmjs.org/:_authToken <token> # 토큰 직접 설정",
573
+ );
574
574
  process.exitCode = 1;
575
575
  return;
576
576
  }
@@ -589,19 +589,23 @@ export async function runPublish(options: PublishOptions): Promise<void> {
589
589
  if (!noBuild && hasGit) {
590
590
  logger.debug("git 커밋 상태 확인 중...");
591
591
  try {
592
- const { stdout: diff } = await cpx.exec("git", ["diff", "--name-only"]);
593
- const { stdout: stagedDiff } = await cpx.exec("git", ["diff", "--cached", "--name-only"]);
592
+ const { stdout: diff } = await cpx.spawn("git", ["diff", "--name-only"]);
593
+ const { stdout: stagedDiff } = await cpx.spawn("git", ["diff", "--cached", "--name-only"]);
594
594
 
595
595
  if (diff.trim() !== "" || stagedDiff.trim() !== "") {
596
596
  logger.info("커밋되지 않은 변경사항 감지. claude로 자동 커밋 시도 중...");
597
597
  try {
598
- await cpx.exec("claude", [
599
- "-p",
600
- "/sd-commit all",
601
- "--dangerously-skip-permissions",
602
- "--model",
603
- "haiku",
604
- ], { stdio: "inherit" });
598
+ await cpx.spawn(
599
+ "claude",
600
+ ["-p", "/sd-commit", "--dangerously-skip-permissions", "--model", "haiku"],
601
+ {
602
+ stdio: "inherit",
603
+ env: {
604
+ ...process.env,
605
+ MCP_CONNECTION_NONBLOCKING: "true",
606
+ },
607
+ },
608
+ );
605
609
  } catch (e) {
606
610
  throw new Error(
607
611
  "자동 커밋에 실패했습니다. 수동으로 커밋 후 다시 시도해주세요.\n" +
@@ -683,11 +687,11 @@ export async function runPublish(options: PublishOptions): Promise<void> {
683
687
  } else {
684
688
  logger.debug("Git commit/tag/push...");
685
689
  try {
686
- await cpx.exec("git", ["add", ..._changedFiles]);
687
- await cpx.exec("git", ["commit", "-m", `v${version}`]);
688
- await cpx.exec("git", ["tag", "-a", `v${version}`, "-m", `v${version}`]);
689
- await cpx.exec("git", ["push"]);
690
- await cpx.exec("git", ["push", "--tags"]);
690
+ await cpx.spawn("git", ["add", ..._changedFiles]);
691
+ await cpx.spawn("git", ["commit", "-m", `v${version}`]);
692
+ await cpx.spawn("git", ["tag", "-a", `v${version}`, "-m", `v${version}`]);
693
+ await cpx.spawn("git", ["push"]);
694
+ await cpx.spawn("git", ["push", "--tags"]);
691
695
  logger.debug("Git 작업 완료");
692
696
  } catch (err) {
693
697
  logger.error(
@@ -806,7 +810,7 @@ export async function runPublish(options: PublishOptions): Promise<void> {
806
810
  logger.info(`[DRY-RUN] 실행 예정: ${cmd} ${args.join(" ")}`);
807
811
  } else {
808
812
  logger.debug(`실행 중: ${cmd} ${args.join(" ")}`);
809
- await cpx.exec(cmd, args, { cwd });
813
+ await cpx.spawn(cmd, args, { cwd });
810
814
  }
811
815
  } catch (err) {
812
816
  // postPublish 실패 시 경고만 출력 (배포 롤백 불가)
@@ -3,15 +3,15 @@ import { loadSdConfig } from "../utils/sd-config";
3
3
  import { setupReplaceDeps } from "../utils/replace-deps";
4
4
 
5
5
  /**
6
- * replace-deps command options
6
+ * replace-deps 명령어 옵션
7
7
  */
8
8
  export interface ReplaceDepsOptions {
9
- /** Additional options to pass to sd.config.ts */
9
+ /** sd.config.ts 전달할 추가 옵션 */
10
10
  options: string[];
11
11
  }
12
12
 
13
13
  /**
14
- * Replace node_modules packages with symlinks to local source based on replaceDeps config in sd.config.ts.
14
+ * sd.config.ts의 replaceDeps 설정에 따라 node_modules 패키지를 로컬 소스 심볼릭 링크로 교체한다.
15
15
  */
16
16
  export async function runReplaceDeps(opts: ReplaceDepsOptions): Promise<void> {
17
17
  const cwd = process.cwd();
@@ -2,7 +2,6 @@ import ts from "typescript";
2
2
  import { err as errNs } from "@simplysm/core-common";
3
3
  import { pathx } from "@simplysm/core-node";
4
4
  import { consola } from "consola";
5
- import type { SdConfig } from "../sd-config.types";
6
5
  import { loadSdConfig } from "../utils/sd-config";
7
6
  import { deserializeDiagnostic } from "../utils/typecheck-serialization";
8
7
  import { createBuildEngine } from "../engines/index";
@@ -35,14 +34,14 @@ export interface TypecheckResult {
35
34
  errorCount: number;
36
35
  warningCount: number;
37
36
  formattedOutput: string;
38
- /** Lint result (present when TypecheckOptions.lint is true) */
37
+ /** lint 결과 (TypecheckOptions.lint true일 때 존재) */
39
38
  lint?: {
40
39
  success: boolean;
41
40
  errorCount: number;
42
41
  warningCount: number;
43
42
  formattedOutput: string;
44
43
  };
45
- /** Paths of scripts packages that were skipped (for separate lint) */
44
+ /** 건너뛴 scripts 패키지 경로 (별도 lint) */
46
45
  scriptsPackagePaths?: string[];
47
46
  }
48
47
 
@@ -75,7 +74,8 @@ function extractTargetPackageNames(targets: string[]): Set<string> {
75
74
  *
76
75
  * sd.config.ts의 각 패키지에 대해:
77
76
  * - 라이브러리/서버 패키지 → BuildEngine.run({js:false, dts:false})
78
- * - 스크립트/클라이언트 패키지 → 제외
77
+ * - client 패키지 → browser target으로 변환하여 포함
78
+ * - scripts 패키지 → 타입체크 제외 (별도 lint만 수행)
79
79
  * 비패키지 파일 → typecheckNonPackageFiles 유틸리티
80
80
  *
81
81
  * @param options - 타입체크 실행 옵션
@@ -97,14 +97,8 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
97
97
  };
98
98
 
99
99
  // sd.config.ts 로드
100
- let sdConfig: SdConfig;
101
- try {
102
- sdConfig = await loadSdConfig({ cwd, dev: false, options: options.options });
103
- logger.debug("sd.config.ts 로드 완료");
104
- } catch {
105
- sdConfig = { packages: {} };
106
- logger.debug("sd.config.ts 로드 실패, 기본값 사용");
107
- }
100
+ const sdConfig = await loadSdConfig({ cwd, dev: false, options: options.options });
101
+ logger.debug("sd.config.ts 로드 완료");
108
102
 
109
103
  // 워크스페이스 패키지 탐색 및 tests/를 설정에 병합
110
104
  const workspacePackages = discoverWorkspacePackages(cwd);
@@ -278,7 +272,7 @@ export async function executeTypecheck(options: TypecheckOptions): Promise<Typec
278
272
  formattedOutput = ts.formatDiagnosticsWithColorAndContext(uniqueDiagnostics, formatHost);
279
273
  }
280
274
 
281
- // Build lint result if lint was requested
275
+ // lint 요청된 경우 lint 결과 생성
282
276
  const lintResult = options.lint === true
283
277
  ? {
284
278
  success: lintSuccess,
@@ -4,17 +4,17 @@ import {
4
4
  } from "../orchestrators/DevWatchOrchestrator";
5
5
 
6
6
  /**
7
- * Build all packages in watch mode.
7
+ * DevWatchOrchestrator를 통해 모든 패키지를 watch 모드로 빌드한다.
8
8
  *
9
- * - Load `sd.config.ts` to check build target info per package (required)
10
- * - `node`/`browser`/`neutral` target: build in esbuild watch mode + generate .d.ts
11
- * - `server` target: build in esbuild watch mode (no runtime)
12
- * - `scripts` target with watch config: run hook on file changes
13
- * - Auto rebuild on file changes
14
- * - Terminate with SIGINT/SIGTERM signals
9
+ * - `sd.config.ts`를 로드하여 패키지별 빌드 대상 정보를 확인한다
10
+ * - `node`/`browser`/`neutral` target: esbuild watch 모드 빌드 + .d.ts 생성
11
+ * - `server` target: esbuild watch 모드 빌드 (런타임 없음)
12
+ * - `scripts` target (watch 설정 있을 때): 파일 변경 hook 실행
13
+ * - 파일 변경 자동 재빌드
14
+ * - SIGINT/SIGTERM 시그널로 종료
15
15
  *
16
- * @param options - watch execution options (targets, options)
17
- * @returns resolves on termination signal
16
+ * @param options - watch 실행 옵션 (targets, options)
17
+ * @returns 종료 시그널 수신 시 resolve
18
18
  */
19
19
  export async function runWatch(options: Omit<DevWatchOrchestratorOptions, "mode">): Promise<void> {
20
20
  const orchestrator = new DevWatchOrchestrator({ mode: "watch", ...options });
@@ -2,7 +2,7 @@ import os from "os";
2
2
  import fs from "fs";
3
3
  import module from "module";
4
4
  import { cpx, fsx, pathx } from "@simplysm/core-node";
5
- import { consola } from "consola";
5
+ import { consola, LogLevels } from "consola";
6
6
  import type { SdElectronConfig } from "../sd-config.types.js";
7
7
  import { createEnvBanner } from "../utils/esbuild-config.js";
8
8
 
@@ -55,7 +55,13 @@ export class Electron {
55
55
  env?: Record<string, string>,
56
56
  ): Promise<string> {
57
57
  Electron._logger.debug(`실행: ${cmd} ${args.join(" ")}`);
58
- const { stdout: result } = await cpx.exec(cmd, args, { cwd, env, shell: true });
58
+ const isDebug = consola.level >= LogLevels.debug;
59
+ const { stdout: result } = await cpx.spawn(cmd, args, {
60
+ cwd,
61
+ env,
62
+ shell: true,
63
+ ...(isDebug ? { stdio: "inherit" } : {}),
64
+ });
59
65
  Electron._logger.debug(`결과: ${result}`);
60
66
  return result;
61
67
  }
@@ -63,18 +69,28 @@ export class Electron {
63
69
  //#region Public Methods
64
70
 
65
71
  async initialize(): Promise<void> {
72
+ Electron._logger.debug("initialize 시작");
66
73
  const srcPath = pathx.posixResolve(this._electronPath, "src");
67
74
 
75
+ Electron._logger.debug("package.json 설정 시작");
68
76
  await this._setupPackageJson(srcPath);
77
+ Electron._logger.debug("package.json 설정 완료");
78
+
79
+ Electron._logger.debug("npm install 시작");
69
80
  await this._exec("npm", ["install"], srcPath);
81
+ Electron._logger.debug("npm install 완료");
70
82
 
71
83
  const reinstallDeps = this._config.reinstallDependencies ?? [];
72
84
  if (reinstallDeps.length > 0) {
85
+ Electron._logger.debug(`electron-rebuild 시작 (${reinstallDeps.join(", ")})`);
73
86
  await this._exec(this._localBin("electron-rebuild"), [], srcPath);
87
+ Electron._logger.debug("electron-rebuild 완료");
74
88
  }
89
+ Electron._logger.debug("initialize 완료");
75
90
  }
76
91
 
77
92
  async run(url: string): Promise<void> {
93
+ Electron._logger.debug(`run 시작 (url: ${url})`);
78
94
  const srcPath = pathx.posixResolve(this._electronPath, "src");
79
95
 
80
96
  await this.initialize();
@@ -90,12 +106,13 @@ export class Electron {
90
106
  const reinstallDeps = this._config.reinstallDependencies ?? [];
91
107
  await fsx.mkdir(srcPath);
92
108
 
93
- let currentElectron: cpx.ExecProcess | null = null;
109
+ let currentElectron: cpx.SpawnProcess | null = null;
94
110
  let isRestarting = false;
95
111
  let resolveTermination: (() => void) | null = null;
96
112
 
97
113
  const spawnElectron = () => {
98
- currentElectron = cpx.exec(this._localBin("electron"), ["."], {
114
+ Electron._logger.debug("Electron 프로세스 시작");
115
+ currentElectron = cpx.spawn(this._localBin("electron"), ["."], {
99
116
  cwd: srcPath,
100
117
  stdio: "inherit",
101
118
  reject: false,
@@ -112,6 +129,7 @@ export class Electron {
112
129
 
113
130
  const envBanner = createEnvBanner({ ELECTRON_DEV_URL: url, ...this._config.env });
114
131
 
132
+ Electron._logger.debug("esbuild context 생성 시작");
115
133
  const ctx = await esbuild.context({
116
134
  entryPoints: [entryPoint],
117
135
  outfile: pathx.posixResolve(srcPath, "electron-main.js"),
@@ -131,8 +149,11 @@ export class Electron {
131
149
  return;
132
150
  }
133
151
 
152
+ Electron._logger.debug("esbuild 번들링 완료");
153
+
134
154
  if (currentElectron != null) {
135
155
  isRestarting = true;
156
+ Electron._logger.debug("기존 Electron 프로세스 종료 시작");
136
157
  currentElectron.kill();
137
158
  try {
138
159
  await currentElectron;
@@ -149,8 +170,11 @@ export class Electron {
149
170
  },
150
171
  ],
151
172
  });
173
+ Electron._logger.debug("esbuild context 생성 완료");
152
174
 
175
+ Electron._logger.debug("esbuild watch 시작");
153
176
  await ctx.watch();
177
+ Electron._logger.debug("esbuild watch 시작 완료, 종료 대기 중");
154
178
 
155
179
  await new Promise<void>((resolve) => {
156
180
  let disposed = false;
@@ -158,6 +182,7 @@ export class Electron {
158
182
  const cleanup = () => {
159
183
  if (disposed) return;
160
184
  disposed = true;
185
+ Electron._logger.debug("cleanup 시작");
161
186
  process.removeListener("SIGINT", signalHandler);
162
187
  process.removeListener("SIGTERM", signalHandler);
163
188
  void ctx.dispose();
@@ -167,6 +192,7 @@ export class Electron {
167
192
  resolveTermination = cleanup;
168
193
 
169
194
  const signalHandler = () => {
195
+ Electron._logger.debug("시그널 수신, Electron 종료 중");
170
196
  if (currentElectron != null) currentElectron.kill();
171
197
  cleanup();
172
198
  };
@@ -174,15 +200,30 @@ export class Electron {
174
200
  process.once("SIGINT", signalHandler);
175
201
  process.once("SIGTERM", signalHandler);
176
202
  });
203
+ Electron._logger.debug("run 완료");
177
204
  }
178
205
 
179
206
  async build(outPath: string): Promise<void> {
207
+ Electron._logger.debug("build 시작");
180
208
  const srcPath = pathx.posixResolve(this._electronPath, "src");
181
209
 
210
+ Electron._logger.debug("메인 프로세스 번들링 시작");
182
211
  await this._bundleMainProcess(srcPath);
212
+ Electron._logger.debug("메인 프로세스 번들링 완료");
213
+
214
+ Electron._logger.debug("웹 에셋 복사 시작");
183
215
  await this._copyWebAssets(outPath, srcPath);
216
+ Electron._logger.debug("웹 에셋 복사 완료");
217
+
218
+ Electron._logger.debug("electron-builder 실행 시작");
184
219
  await this._runElectronBuilder(srcPath);
220
+ Electron._logger.debug("electron-builder 실행 완료");
221
+
222
+ Electron._logger.debug("빌드 산출물 복사 시작");
185
223
  await this._copyBuildOutput(outPath);
224
+ Electron._logger.debug("빌드 산출물 복사 완료");
225
+
226
+ Electron._logger.debug("build 완료");
186
227
  }
187
228
 
188
229
  //#endregion
@@ -245,6 +286,7 @@ export class Electron {
245
286
 
246
287
  const envBanner = createEnvBanner(this._config.env);
247
288
 
289
+ Electron._logger.debug(`esbuild 번들링: ${entryPoint}`);
248
290
  await esbuild.build({
249
291
  entryPoints: [entryPoint],
250
292
  outfile: pathx.posixResolve(outDir, "electron-main.js"),
@@ -322,6 +364,7 @@ export class Electron {
322
364
  const configFilePath = pathx.posixResolve(this._electronPath, "builder-config.json");
323
365
  await fsx.writeJson(configFilePath, builderConfig, { space: 2 });
324
366
 
367
+ Electron._logger.debug(`electron-builder 설정: ${configFilePath}`);
325
368
  await this._exec(
326
369
  this._localBin("electron-builder"),
327
370
  ["--win", "--config", configFilePath],
@@ -340,6 +383,7 @@ export class Electron {
340
383
  const isPortable = this._config.portable === true;
341
384
 
342
385
  // exe 파일 동적 탐색 — Setup 또는 portable exe를 우선 선택
386
+ Electron._logger.debug(`빌드 산출물 탐색: ${distPath}`);
343
387
  const allExeFiles = await fsx.glob(pathx.posixResolve(distPath, "*.exe"));
344
388
  if (allExeFiles.length === 0) {
345
389
  Electron._logger.warn(`빌드 산출물(.exe)을 찾을 수 없습니다: ${distPath}`);
@@ -348,6 +392,7 @@ export class Electron {
348
392
  const keyword = isPortable ? "portable" : "Setup";
349
393
  const sourcePath =
350
394
  allExeFiles.find((f) => f.toLowerCase().includes(keyword.toLowerCase())) ?? allExeFiles[0];
395
+ Electron._logger.debug(`빌드 산출물: ${sourcePath}`);
351
396
 
352
397
  const latestFileName = `${safeName}${isPortable ? "-portable" : ""}-latest.exe`;
353
398
  await fsx.copy(sourcePath, pathx.posixResolve(electronOutPath, latestFileName));
@@ -53,7 +53,7 @@ export interface BaseEngineOptions<TPkg extends PackageInfo> {
53
53
  * 이벤트 처리)이 여기에 위치하며, 서브클래스는 추상 메서드를 통해
54
54
  * 워커 경로, 빌드/워치 호출 파라미터, 타겟 결정을 제공한다.
55
55
  *
56
- * ViteEngine은 이 계층에 포함되지 않음 — 워커 이벤트 구조가 다름.
56
+ * ViteEngine은 이 계층에 포함되지 않음 — serverReady 이벤트, port 관리 등 생명주기가 다름.
57
57
  */
58
58
  export abstract class BaseEngine<
59
59
  TPkg extends PackageInfo,
@@ -189,6 +189,9 @@ export abstract class BaseEngine<
189
189
  };
190
190
  this._resultCollector?.add(result);
191
191
 
192
+ resolver?.();
193
+ resolver = undefined;
194
+
192
195
  // 에러 경로: 항상 resolve (reject하지 않음) — 호출자가 ResultCollector에서 상태를 확인
193
196
  if (isInitialBuild) {
194
197
  isInitialBuild = false;
@@ -8,24 +8,24 @@ import { consola } from "consola";
8
8
  const logger = consola.withTag("sd:cli:engine:ngtsc");
9
9
 
10
10
  /**
11
- * NgtscEngine options
11
+ * NgtscEngine 옵션
12
12
  */
13
13
  export interface NgtscEngineOptions {
14
14
  cwd: string;
15
15
  pkg: BuildPackageInfo;
16
- /** replaceDeps configuration from sd.config.ts */
16
+ /** sd.config.ts replaceDeps 설정 */
17
17
  replaceDeps?: Record<string, string>;
18
- /** ResultCollector for watch mode rebuild reporting */
18
+ /** 워치 모드 리빌드 보고용 ResultCollector */
19
19
  resultCollector?: ResultCollector;
20
- /** RebuildManager for watch mode batch coordination */
20
+ /** 워치 모드 배치 조정용 RebuildManager */
21
21
  rebuildManager?: RebuildManager;
22
22
  }
23
23
 
24
24
  /**
25
- * NgtscProgram-based build engine for Angular Library packages
25
+ * NgtscProgram 기반 Angular 라이브러리 패키지용 빌드 엔진
26
26
  *
27
- * Wraps a single ngtsc-build.worker that uses NgtscProgram for AOT compilation.
28
- * Angular packages are detected by the presence of angularCompilerOptions in tsconfig.json.
27
+ * NgtscProgram을 사용하여 AOT 컴파일을 수행하는 ngtsc-build.worker 래핑한다.
28
+ * package.json에 @angular/core 의존성이 있는 Angular 패키지용.
29
29
  */
30
30
  export class NgtscEngine extends BaseEngine<
31
31
  BuildPackageInfo,
@@ -8,24 +8,24 @@ import { consola } from "consola";
8
8
  const logger = consola.withTag("sd:cli:engine:server");
9
9
 
10
10
  /**
11
- * ServerEsbuildEngine options
11
+ * ServerEsbuildEngine 옵션
12
12
  */
13
13
  export interface ServerEsbuildEngineOptions {
14
14
  cwd: string;
15
15
  pkg: ServerPackageInfo;
16
- /** replaceDeps configuration from sd.config.ts */
16
+ /** sd.config.ts replaceDeps 설정 */
17
17
  replaceDeps?: Record<string, string>;
18
- /** ResultCollector for watch mode rebuild reporting */
18
+ /** 워치 모드 리빌드 보고용 ResultCollector */
19
19
  resultCollector?: ResultCollector;
20
- /** RebuildManager for watch mode batch coordination */
20
+ /** 워치 모드 배치 조정용 RebuildManager */
21
21
  rebuildManager?: RebuildManager;
22
22
  }
23
23
 
24
24
  /**
25
- * Esbuild-based build engine for Server packages
25
+ * esbuild 기반 서버 패키지용 빌드 엔진
26
26
  *
27
- * Wraps a single server-build.worker that combines esbuild (JS bundle)
28
- * + tsc (typecheck) in one Worker thread.
27
+ * esbuild(JS 번들) + tsc(타입체크)를 하나의 Worker 스레드에서 결합하는
28
+ * server-build.worker를 래핑한다.
29
29
  */
30
30
  export class ServerEsbuildEngine extends BaseEngine<
31
31
  ServerPackageInfo,
@@ -8,24 +8,24 @@ import { consola } from "consola";
8
8
  const logger = consola.withTag("sd:cli:engine:tsc");
9
9
 
10
10
  /**
11
- * TscEngine options
11
+ * TscEngine 옵션
12
12
  */
13
13
  export interface TscEngineOptions {
14
14
  cwd: string;
15
15
  pkg: BuildPackageInfo;
16
- /** replaceDeps configuration from sd.config.ts */
16
+ /** sd.config.ts replaceDeps 설정 */
17
17
  replaceDeps?: Record<string, string>;
18
- /** ResultCollector for watch mode rebuild reporting */
18
+ /** 워치 모드 리빌드 보고용 ResultCollector */
19
19
  resultCollector?: ResultCollector;
20
- /** RebuildManager for watch mode batch coordination */
20
+ /** 워치 모드 배치 조정용 RebuildManager */
21
21
  rebuildManager?: RebuildManager;
22
22
  }
23
23
 
24
24
  /**
25
- * tsc-based build engine for Library packages (node/browser/neutral)
25
+ * tsc 기반 라이브러리 패키지(node/browser/neutral)용 빌드 엔진
26
26
  *
27
- * Wraps a single library-build.worker that uses tsc for JS + DTS emit
28
- * in one Worker thread.
27
+ * tsc 사용하여 JS + DTS emit하는 library-build.worker를
28
+ * 하나의 Worker 스레드에서 래핑한다.
29
29
  */
30
30
  export class TscEngine extends BaseEngine<
31
31
  BuildPackageInfo,
@@ -64,6 +64,7 @@ export class ViteEngine implements BuildEngine {
64
64
  configs: this._pkg.config.configs,
65
65
  browserSupport: this._pkg.config.browserSupport,
66
66
  enableLint: output.lint,
67
+ exclude: this._pkg.config.exclude,
67
68
  });
68
69
 
69
70
  logger.debug(`[${this._pkg.name}] ViteEngine.run 완료 (success: ${result.success})`);
@@ -81,7 +82,7 @@ export class ViteEngine implements BuildEngine {
81
82
 
82
83
  /**
83
84
  * 워치 모드 시작 (Vite 개발 서버)
84
- * 개발 서버가 준비되면 Promise가 resolve된다.
85
+ * worker의 startWatch()가 완료되면 Promise가 resolve된다.
85
86
  */
86
87
  async startWatch(output: BuildOutput): Promise<void> {
87
88
  logger.debug(`[${this._pkg.name}] ViteEngine.startWatch 시작`);
@@ -94,7 +95,7 @@ export class ViteEngine implements BuildEngine {
94
95
  this.port = event.port;
95
96
  });
96
97
 
97
- // 리빌드 이벤트 처리 (Feature 3.3 HMR)
98
+ // 리빌드 이벤트 처리 (HMR)
98
99
  let resolver: (() => void) | undefined;
99
100
  const workerKey = `vite:${this._pkg.name}`;
100
101
 
@@ -152,6 +153,9 @@ export class ViteEngine implements BuildEngine {
152
153
  message: event.message,
153
154
  };
154
155
  this._resultCollector?.add(buildResult);
156
+
157
+ resolver?.();
158
+ resolver = undefined;
155
159
  });
156
160
 
157
161
  const port =
@@ -159,7 +163,7 @@ export class ViteEngine implements BuildEngine {
159
163
  ? this._pkg.config.server
160
164
  : undefined;
161
165
 
162
- const result = await this._worker!.startWatch({
166
+ await this._worker!.startWatch({
163
167
  name: this._pkg.name,
164
168
  cwd: this._cwd,
165
169
  pkgDir: this._pkg.dir,
@@ -169,17 +173,8 @@ export class ViteEngine implements BuildEngine {
169
173
  replaceDeps: this._replaceDeps,
170
174
  browserSupport: this._pkg.config.browserSupport,
171
175
  enableLint: output.lint,
176
+ exclude: this._pkg.config.exclude,
172
177
  });
173
-
174
- // 초기 빌드 결과 보고
175
- const buildResult: BuildResult = {
176
- name: this._pkg.name,
177
- target: "client",
178
- type: "build",
179
- status: result.success ? "success" : "error",
180
- message: result.errors?.join("\n"),
181
- };
182
- this._resultCollector?.add(buildResult);
183
178
  }
184
179
 
185
180
  /**
@@ -23,12 +23,12 @@ export type { ViteEngineOptions } from "./ViteEngine";
23
23
  export type { BuildEngine, BuildOutput, BuildPackageInfo, ClientPackageInfo, EngineResult, PackageInfo, ServerPackageInfo } from "./types";
24
24
 
25
25
  /**
26
- * Create a BuildEngine for the given package.
26
+ * 주어진 패키지에 맞는 BuildEngine 생성한다.
27
27
  *
28
- * Client packages use ViteEngine (Angular buildApplicationInternal / serveWithVite).
29
- * Server packages use ServerEsbuildEngine.
30
- * Angular Library packages (detected by @angular/core in package.json) use NgtscEngine.
31
- * Other Library packages (node/browser/neutral) use TscEngine.
28
+ * 클라이언트 패키지는 ViteEngine 사용한다.
29
+ * 서버 패키지는 ServerEsbuildEngine을 사용한다.
30
+ * Angular 라이브러리 패키지(package.json에 @angular/core 의존성 감지) NgtscEngine을 사용한다.
31
+ * 기타 라이브러리 패키지(node/browser/neutral) TscEngine을 사용한다.
32
32
  */
33
33
  export function createBuildEngine(
34
34
  pkg: BuildPackageInfo | ServerPackageInfo | ClientPackageInfo,