@simplysm/sd-cli 14.0.11 → 14.0.13

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 (265) 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 +4 -2
  5. package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
  6. package/dist/angular/vite-angular-plugin.js +73 -36
  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 +20 -2
  11. package/dist/capacitor/capacitor.d.ts.map +1 -1
  12. package/dist/capacitor/capacitor.js +155 -28
  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 +24 -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 +7 -1
  57. package/dist/engines/ViteEngine.d.ts.map +1 -1
  58. package/dist/engines/ViteEngine.js +13 -12
  59. package/dist/engines/ViteEngine.js.map +1 -1
  60. package/dist/engines/index.d.ts +9 -5
  61. package/dist/engines/index.d.ts.map +1 -1
  62. package/dist/engines/index.js +7 -5
  63. package/dist/engines/index.js.map +1 -1
  64. package/dist/engines/types.d.ts +20 -20
  65. package/dist/engines/types.d.ts.map +1 -1
  66. package/dist/infra/ResultCollector.d.ts +9 -9
  67. package/dist/infra/ResultCollector.js +8 -8
  68. package/dist/infra/SignalHandler.d.ts +7 -7
  69. package/dist/infra/SignalHandler.js +7 -7
  70. package/dist/infra/WorkerManager.d.ts +14 -14
  71. package/dist/infra/WorkerManager.js +14 -14
  72. package/dist/orchestrators/BuildOrchestrator.d.ts +25 -25
  73. package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
  74. package/dist/orchestrators/BuildOrchestrator.js +34 -30
  75. package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
  76. package/dist/orchestrators/DevWatchOrchestrator.d.ts +7 -7
  77. package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
  78. package/dist/orchestrators/DevWatchOrchestrator.js +34 -34
  79. package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
  80. package/dist/sd-cli-entry.d.ts +2 -2
  81. package/dist/sd-cli-entry.d.ts.map +1 -1
  82. package/dist/sd-cli-entry.js +15 -8
  83. package/dist/sd-cli-entry.js.map +1 -1
  84. package/dist/sd-cli.d.ts +3 -3
  85. package/dist/sd-cli.js +16 -16
  86. package/dist/sd-cli.js.map +1 -1
  87. package/dist/sd-config.types.d.ts +105 -105
  88. package/dist/sd-config.types.d.ts.map +1 -1
  89. package/dist/utils/angular-compiler.js +5 -5
  90. package/dist/utils/angular-compiler.js.map +1 -1
  91. package/dist/utils/build-env.d.ts +1 -1
  92. package/dist/utils/build-env.js +1 -1
  93. package/dist/utils/concurrency.d.ts +7 -7
  94. package/dist/utils/concurrency.js +7 -7
  95. package/dist/utils/copy-public.d.ts +9 -9
  96. package/dist/utils/copy-public.js +17 -17
  97. package/dist/utils/copy-public.js.map +1 -1
  98. package/dist/utils/copy-src.d.ts +9 -9
  99. package/dist/utils/copy-src.js +11 -11
  100. package/dist/utils/copy-src.js.map +1 -1
  101. package/dist/utils/engine-stop.d.ts +8 -9
  102. package/dist/utils/engine-stop.d.ts.map +1 -1
  103. package/dist/utils/engine-stop.js +9 -10
  104. package/dist/utils/engine-stop.js.map +1 -1
  105. package/dist/utils/esbuild-config.d.ts +23 -23
  106. package/dist/utils/esbuild-config.d.ts.map +1 -1
  107. package/dist/utils/esbuild-config.js +25 -25
  108. package/dist/utils/esbuild-config.js.map +1 -1
  109. package/dist/utils/lint-with-program.d.ts +15 -15
  110. package/dist/utils/lint-with-program.d.ts.map +1 -1
  111. package/dist/utils/lint-with-program.js +29 -29
  112. package/dist/utils/lint-with-program.js.map +1 -1
  113. package/dist/utils/ngtsc-build-core.d.ts +8 -8
  114. package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
  115. package/dist/utils/ngtsc-build-core.js +14 -14
  116. package/dist/utils/ngtsc-build-core.js.map +1 -1
  117. package/dist/utils/output-path-rewriter.d.ts +14 -14
  118. package/dist/utils/output-path-rewriter.js +18 -18
  119. package/dist/utils/output-path-rewriter.js.map +1 -1
  120. package/dist/utils/output-utils.d.ts +6 -6
  121. package/dist/utils/output-utils.js +11 -11
  122. package/dist/utils/output-utils.js.map +1 -1
  123. package/dist/utils/package-utils.d.ts +21 -21
  124. package/dist/utils/package-utils.d.ts.map +1 -1
  125. package/dist/utils/package-utils.js +56 -45
  126. package/dist/utils/package-utils.js.map +1 -1
  127. package/dist/utils/replace-deps.d.ts +25 -25
  128. package/dist/utils/replace-deps.d.ts.map +1 -1
  129. package/dist/utils/replace-deps.js +84 -65
  130. package/dist/utils/replace-deps.js.map +1 -1
  131. package/dist/utils/sd-config.d.ts +3 -3
  132. package/dist/utils/sd-config.js +3 -3
  133. package/dist/utils/tsc-build.d.ts +13 -13
  134. package/dist/utils/tsc-build.d.ts.map +1 -1
  135. package/dist/utils/tsc-build.js +9 -9
  136. package/dist/utils/tsc-build.js.map +1 -1
  137. package/dist/utils/tsconfig.d.ts +11 -9
  138. package/dist/utils/tsconfig.d.ts.map +1 -1
  139. package/dist/utils/tsconfig.js +11 -9
  140. package/dist/utils/tsconfig.js.map +1 -1
  141. package/dist/utils/typecheck-non-package.d.ts +5 -6
  142. package/dist/utils/typecheck-non-package.d.ts.map +1 -1
  143. package/dist/utils/typecheck-non-package.js +7 -8
  144. package/dist/utils/typecheck-non-package.js.map +1 -1
  145. package/dist/utils/typecheck-serialization.d.ts +8 -8
  146. package/dist/utils/typecheck-serialization.d.ts.map +1 -1
  147. package/dist/utils/typecheck-serialization.js +12 -16
  148. package/dist/utils/typecheck-serialization.js.map +1 -1
  149. package/dist/utils/vite-config.d.ts +12 -5
  150. package/dist/utils/vite-config.d.ts.map +1 -1
  151. package/dist/utils/vite-config.js +95 -41
  152. package/dist/utils/vite-config.js.map +1 -1
  153. package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
  154. package/dist/utils/vite-scope-watch-plugin.js +1 -1
  155. package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
  156. package/dist/utils/worker-events.d.ts +12 -12
  157. package/dist/utils/worker-events.d.ts.map +1 -1
  158. package/dist/utils/worker-events.js +10 -10
  159. package/dist/utils/worker-events.js.map +1 -1
  160. package/dist/utils/worker-utils.d.ts +12 -13
  161. package/dist/utils/worker-utils.d.ts.map +1 -1
  162. package/dist/utils/worker-utils.js +12 -13
  163. package/dist/utils/worker-utils.js.map +1 -1
  164. package/dist/vitest-plugin.d.ts.map +1 -1
  165. package/dist/vitest-plugin.js +5 -7
  166. package/dist/vitest-plugin.js.map +1 -1
  167. package/dist/workers/client.worker.d.ts +8 -2
  168. package/dist/workers/client.worker.d.ts.map +1 -1
  169. package/dist/workers/client.worker.js +215 -6
  170. package/dist/workers/client.worker.js.map +1 -1
  171. package/dist/workers/library-build.worker.d.ts +1 -1
  172. package/dist/workers/library-build.worker.d.ts.map +1 -1
  173. package/dist/workers/library-build.worker.js +7 -7
  174. package/dist/workers/library-build.worker.js.map +1 -1
  175. package/dist/workers/lint.worker.d.ts +2 -2
  176. package/dist/workers/lint.worker.js +2 -2
  177. package/dist/workers/ngtsc-build.worker.js +30 -30
  178. package/dist/workers/ngtsc-build.worker.js.map +1 -1
  179. package/dist/workers/server-build.worker.d.ts +17 -17
  180. package/dist/workers/server-build.worker.d.ts.map +1 -1
  181. package/dist/workers/server-build.worker.js +46 -46
  182. package/dist/workers/server-build.worker.js.map +1 -1
  183. package/dist/workers/server-runtime.worker.d.ts +7 -7
  184. package/dist/workers/server-runtime.worker.d.ts.map +1 -1
  185. package/dist/workers/server-runtime.worker.js +17 -17
  186. package/dist/workers/server-runtime.worker.js.map +1 -1
  187. package/docs/config.md +340 -0
  188. package/docs/publish-configuration-types.md +87 -0
  189. package/docs/pwa-configuration-types.md +55 -0
  190. package/docs/vitest-plugin.md +47 -0
  191. package/package.json +9 -7
  192. package/src/angular/client-transform-stylesheet.ts +1 -1
  193. package/src/angular/vite-angular-plugin.ts +89 -39
  194. package/src/angular/vite-postcss-inline-plugin.ts +1 -1
  195. package/src/capacitor/capacitor.ts +185 -38
  196. package/src/commands/build.ts +3 -10
  197. package/src/commands/check.ts +3 -3
  198. package/src/commands/dev.ts +3 -9
  199. package/src/commands/device.ts +5 -5
  200. package/src/commands/publish.ts +30 -26
  201. package/src/commands/replace-deps.ts +3 -3
  202. package/src/commands/typecheck.ts +7 -13
  203. package/src/commands/watch.ts +9 -9
  204. package/src/electron/electron.ts +49 -4
  205. package/src/engines/BaseEngine.ts +4 -1
  206. package/src/engines/NgtscEngine.ts +7 -7
  207. package/src/engines/ServerEsbuildEngine.ts +7 -7
  208. package/src/engines/TscEngine.ts +7 -7
  209. package/src/engines/ViteEngine.ts +18 -13
  210. package/src/engines/index.ts +11 -5
  211. package/src/engines/types.ts +20 -20
  212. package/src/infra/ResultCollector.ts +9 -9
  213. package/src/infra/SignalHandler.ts +7 -7
  214. package/src/infra/WorkerManager.ts +14 -14
  215. package/src/orchestrators/BuildOrchestrator.ts +42 -38
  216. package/src/orchestrators/DevWatchOrchestrator.ts +36 -36
  217. package/src/sd-cli-entry.ts +15 -8
  218. package/src/sd-cli.ts +16 -16
  219. package/src/sd-config.types.ts +107 -107
  220. package/src/utils/angular-compiler.ts +5 -5
  221. package/src/utils/build-env.ts +1 -1
  222. package/src/utils/concurrency.ts +7 -7
  223. package/src/utils/copy-public.ts +17 -17
  224. package/src/utils/copy-src.ts +11 -11
  225. package/src/utils/engine-stop.ts +9 -10
  226. package/src/utils/esbuild-config.ts +29 -29
  227. package/src/utils/lint-with-program.ts +34 -34
  228. package/src/utils/ngtsc-build-core.ts +17 -17
  229. package/src/utils/output-path-rewriter.ts +18 -18
  230. package/src/utils/output-utils.ts +11 -11
  231. package/src/utils/package-utils.ts +57 -45
  232. package/src/utils/replace-deps.ts +92 -67
  233. package/src/utils/sd-config.ts +3 -3
  234. package/src/utils/tsc-build.ts +18 -18
  235. package/src/utils/tsconfig.ts +11 -9
  236. package/src/utils/typecheck-non-package.ts +7 -8
  237. package/src/utils/typecheck-serialization.ts +13 -15
  238. package/src/utils/vite-config.ts +108 -46
  239. package/src/utils/vite-scope-watch-plugin.ts +6 -1
  240. package/src/utils/worker-events.ts +16 -16
  241. package/src/utils/worker-utils.ts +12 -13
  242. package/src/vitest-plugin.ts +5 -8
  243. package/src/workers/client.worker.ts +246 -7
  244. package/src/workers/library-build.worker.ts +8 -8
  245. package/src/workers/lint.worker.ts +2 -2
  246. package/src/workers/ngtsc-build.worker.ts +31 -31
  247. package/src/workers/server-build.worker.ts +60 -60
  248. package/src/workers/server-runtime.worker.ts +22 -22
  249. package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +1 -0
  250. package/tests/angular/vite-angular-plugin-hmr.spec.ts +78 -0
  251. package/tests/angular/vite-angular-plugin.spec.ts +67 -0
  252. package/tests/capacitor/capacitor-build.spec.ts +93 -11
  253. package/tests/capacitor/capacitor-icon.spec.ts +7 -5
  254. package/tests/capacitor/capacitor-init.spec.ts +124 -10
  255. package/tests/capacitor/capacitor-run.spec.ts +14 -17
  256. package/tests/capacitor/capacitor-workspace.spec.ts +5 -3
  257. package/tests/commands/check.spec.ts +2 -2
  258. package/tests/commands/publish.spec.ts +2 -2
  259. package/tests/commands/typecheck.spec.ts +8 -0
  260. package/tests/electron/electron.spec.ts +12 -10
  261. package/tests/engines/base-engine.spec.ts +37 -0
  262. package/tests/engines/vite-engine.spec.ts +115 -3
  263. package/tests/utils/vite-config.spec.ts +162 -90
  264. package/tests/workers/client-worker.spec.ts +690 -0
  265. package/tests/workers/server-build-worker.spec.ts +3 -3
@@ -1,6 +1,5 @@
1
1
  import type { InlineConfig, PluginOption } from "vite";
2
2
  import path from "path";
3
- import { pathx } from "@simplysm/core-node";
4
3
  import tsconfigPaths from "vite-tsconfig-paths";
5
4
  import browserslistToEsbuild from "browserslist-to-esbuild";
6
5
  import { sdAngularPlugin } from "../angular/vite-angular-plugin.js";
@@ -36,7 +35,7 @@ export interface CreateClientViteConfigOptions {
36
35
  warnings?: string[];
37
36
  lint?: { success: boolean; errorCount: number; warningCount: number; formattedOutput: string };
38
37
  }) => void;
39
- /** Enable lint using ts.Program from compilation */
38
+ /** 컴파일의 ts.Program 사용하여 lint 실행 */
40
39
  enableLint?: boolean;
41
40
  /** replaceDeps 목록 (dev 모드에서 sdScopeWatchPlugin에 전달) */
42
41
  replaceDeps?: ScopeWatchReplaceDep[];
@@ -48,18 +47,25 @@ export interface CreateClientViteConfigOptions {
48
47
  postCssPlugins?: unknown[];
49
48
  /** polyfills 경로 배열 (transformIndexHtml로 주입) */
50
49
  polyfills?: string[];
51
- /** legacy module support (disables code splitting + replaces import.meta) */
50
+ /** 레거시 모듈 지원 (코드 스플리팅 비활성화) */
52
51
  legacyModule?: boolean;
53
52
  /** PWA 설정. false로 비활성화. 미설정 시 기본값으로 활성화 */
54
53
  pwa?: false | SdPwaConfig;
54
+ /** Vite optimizeDeps.exclude에 전달할 패키지 목록 */
55
+ exclude?: string[];
56
+ /** watch 모드 (build.watch 활성화, emptyOutDir: false) */
57
+ watch?: boolean;
58
+ /** 빌드 출력 경로 (미설정 시 pkgDir/dist) */
59
+ outDir?: string;
60
+ /** Vite base 경로 (미설정 시 /{pkgName}/) */
61
+ base?: string;
55
62
  }
56
63
 
57
64
  /**
58
65
  * Client Vite 설정을 생성한다. dev/build 모드에서 공용으로 사용한다.
59
66
  *
60
- * Feature 3.1 범위: sdAngularPlugin, tsconfigPaths, env define, server/build 기본 설정
61
- * Feature 5.1: browserslist, PostCSS, polyfills
62
- * Feature 1.1: legacyModule (import.meta 치환 + inlineDynamicImports)
67
+ * Angular AOT 플러그인, tsconfigPaths, env define, server/build 기본 설정,
68
+ * browserslist, PostCSS, polyfills, legacyModule (inlineDynamicImports) 등을 통합 구성한다.
63
69
  */
64
70
  export async function createClientViteConfig(
65
71
  options: CreateClientViteConfigOptions,
@@ -97,6 +103,7 @@ export async function createClientViteConfig(
97
103
  sdAngularPlugin({
98
104
  tsconfig: options.tsconfigPath,
99
105
  dev: options.mode === "dev",
106
+ sourcemap: options.mode === "dev" || options.watch === true,
100
107
  onBuildStart: options.onBuildStart,
101
108
  onBuild: options.onBuild,
102
109
  enableLint: options.enableLint,
@@ -112,8 +119,12 @@ export async function createClientViteConfig(
112
119
  );
113
120
  }
114
121
 
115
- // replaceDeps HMR (dev 모드만)
116
- if (options.mode === "dev" && options.replaceDeps != null && options.replaceDeps.length > 0) {
122
+ // replaceDeps HMR (dev 모드 또는 watch 모드)
123
+ if (
124
+ (options.mode === "dev" || options.watch === true) &&
125
+ options.replaceDeps != null &&
126
+ options.replaceDeps.length > 0
127
+ ) {
117
128
  plugins.push(
118
129
  sdScopeWatchPlugin({
119
130
  pkgDir: options.pkgDir,
@@ -127,7 +138,7 @@ export async function createClientViteConfig(
127
138
  const serverConfig =
128
139
  options.mode === "dev"
129
140
  ? {
130
- host: options.serverPort === 0 ? "127.0.0.1" : undefined,
141
+ host: options.serverPort === 0 ? "127.0.0.1" : "0.0.0.0",
131
142
  port: options.serverPort === 0 ? undefined : options.serverPort,
132
143
  strictPort: options.serverPort !== 0,
133
144
  }
@@ -139,9 +150,15 @@ export async function createClientViteConfig(
139
150
  ? { postcss: { plugins: options.postCssPlugins as import("postcss").AcceptedPlugin[] } }
140
151
  : undefined;
141
152
 
153
+ // optimizeDeps.exclude (사용자 지정 exclude)
154
+ const optimizeDepsConfig =
155
+ options.exclude != null && options.exclude.length > 0
156
+ ? { exclude: options.exclude }
157
+ : undefined;
158
+
142
159
  const config: InlineConfig = {
143
160
  root: options.pkgDir,
144
- base: `/${name}/`,
161
+ base: options.base ?? `/${name}/`,
145
162
  define: Object.keys(define).length > 0 ? define : undefined,
146
163
  plugins,
147
164
  server: serverConfig,
@@ -149,6 +166,15 @@ export async function createClientViteConfig(
149
166
  esbuild: {
150
167
  target: esbuildTarget,
151
168
  },
169
+ build: {
170
+ target: esbuildTarget,
171
+ },
172
+ optimizeDeps: {
173
+ ...optimizeDepsConfig,
174
+ esbuildOptions: {
175
+ target: esbuildTarget as string[],
176
+ },
177
+ },
152
178
  };
153
179
 
154
180
  // PWA (build 모드 + pwa !== false)
@@ -189,26 +215,59 @@ export async function createClientViteConfig(
189
215
  );
190
216
  }
191
217
 
192
- // polyfills plugin (transformIndexHtml)
218
+ // polyfills plugin
193
219
  if (options.polyfills != null && options.polyfills.length > 0) {
194
220
  const polyfillImports = options.polyfills;
195
- (config.plugins as PluginOption[]).push({
196
- name: "sd-polyfills",
197
- transformIndexHtml() {
198
- return [
199
- {
200
- tag: "script",
201
- attrs: { type: "module" },
202
- children: polyfillImports.map((p) => `import "${p}";`).join("\n"),
203
- injectTo: "head-prepend" as const,
204
- },
205
- ];
206
- },
207
- });
221
+ if (options.legacyModule === true) {
222
+ // legacyModule: 메인 엔트리의 transform에서 polyfill import를 상단에 주입한다.
223
+ // transformIndexHtml 인라인 <script type="module">은 Vite 빌드에서 번들링되지 않으므로,
224
+ // Rollup이 처리할 수 있도록 소스 코드 레벨에서 주입한다.
225
+ const mainEntryPath = path.resolve(options.pkgDir, "src/main.ts");
226
+ (config.plugins as PluginOption[]).push({
227
+ name: "sd-polyfills",
228
+ transform(code, id) {
229
+ if (path.normalize(id) !== path.normalize(mainEntryPath)) return null;
230
+ // polyfillImports는 pkgDir 기준 상대경로 (예: "./src/polyfills.ts")
231
+ // main.ts는 src/ 안에 있으므로, main.ts 기준 상대경로로 변환한다
232
+ const mainDir = path.dirname(mainEntryPath);
233
+ const polyfillCode = polyfillImports
234
+ .map((p) => {
235
+ const abs = path.resolve(options.pkgDir, p);
236
+ this.addWatchFile(abs);
237
+ const rel = path.relative(mainDir, abs);
238
+ const posixRel = rel.replace(/\\/g, "/");
239
+ return "import \"./" + posixRel + "\";";
240
+ })
241
+ .join("\n");
242
+ return { code: polyfillCode + "\n" + code, map: null };
243
+ },
244
+ });
245
+ } else {
246
+ // dev 모드: transformIndexHtml로 인라인 스크립트 주입 (Vite dev server가 처리)
247
+ (config.plugins as PluginOption[]).push({
248
+ name: "sd-polyfills",
249
+ transformIndexHtml() {
250
+ return [
251
+ {
252
+ tag: "script",
253
+ attrs: { type: "module" },
254
+ children: polyfillImports.map((p) => `import "${p}";`).join("\n"),
255
+ injectTo: "head-prepend" as const,
256
+ },
257
+ ];
258
+ },
259
+ });
260
+ }
208
261
  }
209
262
 
210
- // legacyModule: true → 단일 번들 + import.meta 치환
263
+ // legacyModule: true → 코드 스플리팅 비활성화 + esbuild import.meta 변환 + 잔여 import() 제거
211
264
  if (options.legacyModule === true) {
265
+ config.esbuild = {
266
+ ...config.esbuild,
267
+ supported: {
268
+ "import-meta": false,
269
+ },
270
+ };
212
271
  config.build = {
213
272
  ...config.build,
214
273
  rollupOptions: {
@@ -218,38 +277,41 @@ export async function createClientViteConfig(
218
277
  },
219
278
  };
220
279
 
221
- const pkgDir = options.pkgDir;
222
- const base = `/${name}/`;
223
-
280
+ // Rollup이 인라인하지 못한 잔여 dynamic import()를 제거한다.
281
+ // inlineDynamicImports가 정적 경로를 모두 인라인한 후에도,
282
+ // @vite-ignore나 런타임 계산 경로의 import()가 남을 수 있다.
283
+ // Chrome 61은 import() 구문을 파싱하지 못하므로 no-op 함수로 치환한다.
224
284
  (config.plugins as PluginOption[]).push({
225
- name: "sd-legacy-import-meta",
285
+ name: "sd-legacy-strip-dynamic-import",
226
286
  enforce: "post",
227
- transform(code: string, id: string) {
228
- if (!code.includes("import.meta")) return;
229
-
230
- // id(파일 경로)를 Vite 서빙 URL로 변환
231
- const relative = pathx.posix(path.relative(pkgDir, id));
232
- const moduleUrl = id.startsWith("/") || id.startsWith("\0")
233
- ? id // 가상 모듈(/@vite/client 등)은 그대로 사용
234
- : base + relative;
235
-
236
- const varName = "__sd_import_meta__";
237
- const injected = `const ${varName} = { url: new URL(${JSON.stringify(moduleUrl)}, document.baseURI).href };\n`;
238
- const replaced = code.replaceAll("import.meta", varName);
239
-
240
- return { code: injected + replaced, map: null };
287
+ renderChunk(code) {
288
+ if (!code.includes("import(")) return null;
289
+ return {
290
+ code: code.replace(
291
+ /\bimport\s*\(/g,
292
+ "(function(){return Promise.reject(new Error(\"Dynamic import not supported\"))})(",
293
+ ),
294
+ map: null,
295
+ };
241
296
  },
242
297
  });
243
298
  }
244
299
 
245
300
  // build 모드 설정
246
301
  if (options.mode === "build") {
247
- config.logLevel = "silent";
248
302
  config.build = {
249
303
  ...config.build,
250
- outDir: path.join(options.pkgDir, "dist"),
251
- emptyOutDir: true,
304
+ outDir: options.outDir ?? path.join(options.pkgDir, "dist"),
252
305
  };
306
+ if (options.watch === true) {
307
+ config.build.watch = {};
308
+ config.build.emptyOutDir = false;
309
+ config.build.minify = false;
310
+ config.build.sourcemap = true;
311
+ } else {
312
+ config.logLevel = "silent";
313
+ config.build.emptyOutDir = true;
314
+ }
253
315
  }
254
316
 
255
317
  return config;
@@ -44,7 +44,12 @@ export function sdScopeWatchPlugin(options: SdScopeWatchPluginOptions): Plugin {
44
44
 
45
45
  const watchPaths: string[] = [];
46
46
  for (const dep of options.replaceDeps) {
47
- const distDir = path.join(dep.sourcePath, "dist");
47
+ const distDir = path.join(
48
+ options.pkgDir,
49
+ "node_modules",
50
+ ...dep.packageName.split("/"),
51
+ "dist",
52
+ );
48
53
  if (fs.existsSync(distDir)) {
49
54
  watchPaths.push(distDir);
50
55
  }
@@ -6,24 +6,24 @@ import { formatBuildMessages } from "./output-utils";
6
6
 
7
7
  const workerEventsLogger = consola.withTag("sd:cli:worker-events");
8
8
 
9
- /** Worker build completion event data */
9
+ /** 워커 빌드 완료 이벤트 데이터 */
10
10
  export interface BuildEventData {
11
11
  success: boolean;
12
12
  errors?: string[];
13
13
  warnings?: string[];
14
14
  }
15
15
 
16
- /** Worker error event data */
16
+ /** 워커 에러 이벤트 데이터 */
17
17
  export interface ErrorEventData {
18
18
  message: string;
19
19
  }
20
20
 
21
- /** Worker server ready event data */
21
+ /** 워커 서버 준비 완료 이벤트 데이터 */
22
22
  export interface ServerReadyEventData {
23
23
  port: number;
24
24
  }
25
25
 
26
- /** Server Build completion event data */
26
+ /** Server 빌드 완료 이벤트 데이터 */
27
27
  export interface ServerBuildEventData {
28
28
  success: boolean;
29
29
  mainJsPath: string;
@@ -32,7 +32,7 @@ export interface ServerBuildEventData {
32
32
  }
33
33
 
34
34
  /**
35
- * Base Worker info type
35
+ * 기본 Worker 정보 타입
36
36
  */
37
37
  export interface BaseWorkerInfo<TEvents extends Record<string, unknown> = Record<string, unknown>> {
38
38
  name: string;
@@ -46,7 +46,7 @@ export interface BaseWorkerInfo<TEvents extends Record<string, unknown> = Record
46
46
  }
47
47
 
48
48
  /**
49
- * Worker event handler options
49
+ * 워커 이벤트 핸들러 옵션
50
50
  */
51
51
  export interface WorkerEventHandlerOptions {
52
52
  resultKey: string;
@@ -55,13 +55,13 @@ export interface WorkerEventHandlerOptions {
55
55
  }
56
56
 
57
57
  /**
58
- * Register common Worker event handlers (buildStart, build, error only - serverReady not included)
58
+ * 공통 Worker 이벤트 핸들러를 등록한다 (buildStart, build, error serverReady 미포함)
59
59
  *
60
- * @param workerInfo Worker info
61
- * @param opts Handler options
62
- * @param results Result map
63
- * @param rebuildManager Rebuild manager
64
- * @returns completeTask function (saves result and signals build completion)
60
+ * @param workerInfo 워커 정보
61
+ * @param opts 핸들러 옵션
62
+ * @param results 결과
63
+ * @param rebuildManager 재빌드 매니저
64
+ * @returns completeTask 함수 (결과 저장 빌드 완료 신호)
65
65
  */
66
66
  export function registerWorkerEventHandlers(
67
67
  workerInfo: {
@@ -85,18 +85,18 @@ export function registerWorkerEventHandlers(
85
85
  workerInfo.isInitialBuild = false;
86
86
  };
87
87
 
88
- // Build start (on rebuild)
88
+ // 빌드 시작 (재빌드 )
89
89
  workerInfo.worker.on("buildStart", () => {
90
90
  if (!workerInfo.isInitialBuild) {
91
91
  workerInfo.buildResolver = rebuildManager.registerBuild(opts.resultKey, opts.listrTitle);
92
92
  }
93
93
  });
94
94
 
95
- // Build completion
95
+ // 빌드 완료
96
96
  workerInfo.worker.on("build", (data) => {
97
97
  workerEventsLogger.debug(`[${workerInfo.name}] build: success=${String(data.success)}`);
98
98
 
99
- // Print warnings
99
+ // 경고 출력
100
100
  if (data.warnings != null && data.warnings.length > 0) {
101
101
  workerEventsLogger.warn(
102
102
  formatBuildMessages(workerInfo.name, workerInfo.config.target, data.warnings),
@@ -112,7 +112,7 @@ export function registerWorkerEventHandlers(
112
112
  });
113
113
  });
114
114
 
115
- // Error
115
+ // 에러
116
116
  workerInfo.worker.on("error", (data) => {
117
117
  workerEventsLogger.debug(`[${workerInfo.name}] error: ${data.message}`);
118
118
  completeTask({
@@ -2,11 +2,11 @@ import consola, { type ConsolaInstance, LogLevels } from "consola";
2
2
  import { SdCliReporter } from "./SdCliReporter";
3
3
 
4
4
  /**
5
- * Apply sd-cli reporter and debug log level in worker threads
5
+ * 워커 스레드에서 sd-cli 리포터와 디버그 로그 레벨을 적용한다.
6
6
  *
7
- * Checks the SD_DEBUG environment variable (set by --debug flag in main process)
8
- * and applies debug log level to consola in the current worker thread.
9
- * Must be called at worker module top level.
7
+ * SD_DEBUG 환경변수(메인 프로세스의 --debug 플래그로 설정)를 확인하고
8
+ * 현재 워커 스레드의 consola 디버그 로그 레벨을 적용한다.
9
+ * 워커 모듈 최상위에서 호출해야 한다.
10
10
  */
11
11
  export function applyDebugLevel(): void {
12
12
  consola.options.reporters = [new SdCliReporter()];
@@ -16,14 +16,13 @@ export function applyDebugLevel(): void {
16
16
  }
17
17
 
18
18
  /**
19
- * Register cleanup handlers for worker process shutdown signals
19
+ * 워커 프로세스 종료 시그널에 대한 정리 핸들러를 등록한다.
20
20
  *
21
- * Registers SIGINT and SIGTERM handlers to gracefully cleanup resources
22
- * before process exit. Both handlers execute the cleanup function and
23
- * exit with code 0.
21
+ * 프로세스 종료 리소스를 정상적으로 정리하기 위해 SIGINT와 SIGTERM 핸들러를 등록한다.
22
+ * 핸들러 모두 정리 함수를 실행하고 코드 0으로 종료한다.
24
23
  *
25
- * @param cleanup - Cleanup function to execute on shutdown (sync or async)
26
- * @param logger - Consola logger instance for error logging
24
+ * @param cleanup - 종료 실행할 정리 함수 (동기 또는 비동기)
25
+ * @param logger - 에러 로깅용 consola 로거 인스턴스
27
26
  */
28
27
  export function registerCleanupHandlers(
29
28
  cleanup: () => void | Promise<void>,
@@ -45,10 +44,10 @@ export function registerCleanupHandlers(
45
44
  }
46
45
 
47
46
  /**
48
- * Create guard to prevent duplicate calls to Worker function
47
+ * Worker 함수의 중복 호출을 방지하는 가드를 생성한다.
49
48
  *
50
- * @param label - Function name to use in error message
51
- * @returns Guard function that throws error if called twice
49
+ * @param label - 에러 메시지에 사용할 함수명
50
+ * @returns 호출되면 에러를 던지는 가드 함수
52
51
  */
53
52
  export function createOnceGuard(label: string): () => void {
54
53
  let called = false;
@@ -1,6 +1,7 @@
1
1
  import type { Plugin } from "vite";
2
2
  import path from "path";
3
3
  import ts from "typescript";
4
+ import { pathx } from "@simplysm/core-node";
4
5
  import { NgtscProgram, type AngularLibraryHostExtensions } from "./utils/angular-build";
5
6
  import { compileScssString, compileScssFile } from "./utils/scss-compiler";
6
7
 
@@ -48,7 +49,7 @@ export function angularVitestPlugin(options: AngularVitestPluginOptions): Plugin
48
49
 
49
50
  const host = ts.createCompilerHost(compilerOptions);
50
51
 
51
- // AngularLibraryHostExtensions duck-typing
52
+ // AngularLibraryHostExtensions 덕 타이핑
52
53
  const hostExt = host as ts.CompilerHost & AngularLibraryHostExtensions;
53
54
  hostExt.readResource = (fileName: string) => ts.sys.readFile(fileName) ?? "";
54
55
 
@@ -95,12 +96,12 @@ export function angularVitestPlugin(options: AngularVitestPluginOptions): Plugin
95
96
  const { transformers } = program.compiler.prepareEmit();
96
97
  const tsProgram = program.getTsProgram();
97
98
 
98
- // per-file emit
99
+ // 파일별 emit
99
100
  for (const filePath of sourceFiles) {
100
101
  const sf = tsProgram.getSourceFile(filePath);
101
102
  if (sf == null) continue;
102
103
 
103
- currentSourcePath = normalizePath(filePath);
104
+ currentSourcePath = pathx.posix(filePath);
104
105
  tsProgram.emit(sf, host.writeFile, undefined, false, transformers);
105
106
  }
106
107
  },
@@ -110,7 +111,7 @@ export function angularVitestPlugin(options: AngularVitestPluginOptions): Plugin
110
111
  return undefined;
111
112
  }
112
113
 
113
- const compiled = compiledFiles.get(normalizePath(id));
114
+ const compiled = compiledFiles.get(pathx.posix(id));
114
115
  if (compiled == null) {
115
116
  return undefined;
116
117
  }
@@ -119,7 +120,3 @@ export function angularVitestPlugin(options: AngularVitestPluginOptions): Plugin
119
120
  },
120
121
  };
121
122
  }
122
-
123
- function normalizePath(p: string): string {
124
- return p.replace(/\\/g, "/");
125
- }