@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.
- package/README.md +58 -253
- package/dist/angular/client-transform-stylesheet.js +1 -1
- package/dist/angular/client-transform-stylesheet.js.map +1 -1
- package/dist/angular/vite-angular-plugin.d.ts +4 -2
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +73 -36
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/angular/vite-postcss-inline-plugin.d.ts +1 -1
- package/dist/angular/vite-postcss-inline-plugin.js +1 -1
- package/dist/capacitor/capacitor.d.ts +20 -2
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +155 -28
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/build.d.ts +3 -10
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +3 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/check.js +3 -3
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/dev.d.ts +3 -9
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +3 -9
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/device.d.ts +3 -3
- package/dist/commands/device.js +5 -5
- package/dist/commands/device.js.map +1 -1
- package/dist/commands/publish.d.ts +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +24 -26
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/replace-deps.d.ts +3 -3
- package/dist/commands/replace-deps.d.ts.map +1 -1
- package/dist/commands/replace-deps.js +1 -1
- package/dist/commands/typecheck.d.ts +4 -3
- package/dist/commands/typecheck.d.ts.map +1 -1
- package/dist/commands/typecheck.js +5 -11
- package/dist/commands/typecheck.js.map +1 -1
- package/dist/commands/watch.d.ts +9 -9
- package/dist/commands/watch.js +9 -9
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +42 -3
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts +1 -1
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +3 -1
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/NgtscEngine.d.ts +7 -7
- package/dist/engines/NgtscEngine.d.ts.map +1 -1
- package/dist/engines/NgtscEngine.js +3 -3
- package/dist/engines/ServerEsbuildEngine.d.ts +7 -7
- package/dist/engines/ServerEsbuildEngine.d.ts.map +1 -1
- package/dist/engines/ServerEsbuildEngine.js +3 -3
- package/dist/engines/TscEngine.d.ts +7 -7
- package/dist/engines/TscEngine.d.ts.map +1 -1
- package/dist/engines/TscEngine.js +3 -3
- package/dist/engines/ViteEngine.d.ts +7 -1
- package/dist/engines/ViteEngine.d.ts.map +1 -1
- package/dist/engines/ViteEngine.js +13 -12
- package/dist/engines/ViteEngine.js.map +1 -1
- package/dist/engines/index.d.ts +9 -5
- package/dist/engines/index.d.ts.map +1 -1
- package/dist/engines/index.js +7 -5
- package/dist/engines/index.js.map +1 -1
- package/dist/engines/types.d.ts +20 -20
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/infra/ResultCollector.d.ts +9 -9
- package/dist/infra/ResultCollector.js +8 -8
- package/dist/infra/SignalHandler.d.ts +7 -7
- package/dist/infra/SignalHandler.js +7 -7
- package/dist/infra/WorkerManager.d.ts +14 -14
- package/dist/infra/WorkerManager.js +14 -14
- package/dist/orchestrators/BuildOrchestrator.d.ts +25 -25
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +34 -30
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.d.ts +7 -7
- package/dist/orchestrators/DevWatchOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/DevWatchOrchestrator.js +34 -34
- package/dist/orchestrators/DevWatchOrchestrator.js.map +1 -1
- package/dist/sd-cli-entry.d.ts +2 -2
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +15 -8
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.d.ts +3 -3
- package/dist/sd-cli.js +16 -16
- package/dist/sd-cli.js.map +1 -1
- package/dist/sd-config.types.d.ts +105 -105
- package/dist/sd-config.types.d.ts.map +1 -1
- package/dist/utils/angular-compiler.js +5 -5
- package/dist/utils/angular-compiler.js.map +1 -1
- package/dist/utils/build-env.d.ts +1 -1
- package/dist/utils/build-env.js +1 -1
- package/dist/utils/concurrency.d.ts +7 -7
- package/dist/utils/concurrency.js +7 -7
- package/dist/utils/copy-public.d.ts +9 -9
- package/dist/utils/copy-public.js +17 -17
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/copy-src.d.ts +9 -9
- package/dist/utils/copy-src.js +11 -11
- package/dist/utils/copy-src.js.map +1 -1
- package/dist/utils/engine-stop.d.ts +8 -9
- package/dist/utils/engine-stop.d.ts.map +1 -1
- package/dist/utils/engine-stop.js +9 -10
- package/dist/utils/engine-stop.js.map +1 -1
- package/dist/utils/esbuild-config.d.ts +23 -23
- package/dist/utils/esbuild-config.d.ts.map +1 -1
- package/dist/utils/esbuild-config.js +25 -25
- package/dist/utils/esbuild-config.js.map +1 -1
- package/dist/utils/lint-with-program.d.ts +15 -15
- package/dist/utils/lint-with-program.d.ts.map +1 -1
- package/dist/utils/lint-with-program.js +29 -29
- package/dist/utils/lint-with-program.js.map +1 -1
- package/dist/utils/ngtsc-build-core.d.ts +8 -8
- package/dist/utils/ngtsc-build-core.d.ts.map +1 -1
- package/dist/utils/ngtsc-build-core.js +14 -14
- package/dist/utils/ngtsc-build-core.js.map +1 -1
- package/dist/utils/output-path-rewriter.d.ts +14 -14
- package/dist/utils/output-path-rewriter.js +18 -18
- package/dist/utils/output-path-rewriter.js.map +1 -1
- package/dist/utils/output-utils.d.ts +6 -6
- package/dist/utils/output-utils.js +11 -11
- package/dist/utils/output-utils.js.map +1 -1
- package/dist/utils/package-utils.d.ts +21 -21
- package/dist/utils/package-utils.d.ts.map +1 -1
- package/dist/utils/package-utils.js +56 -45
- package/dist/utils/package-utils.js.map +1 -1
- package/dist/utils/replace-deps.d.ts +25 -25
- package/dist/utils/replace-deps.d.ts.map +1 -1
- package/dist/utils/replace-deps.js +84 -65
- package/dist/utils/replace-deps.js.map +1 -1
- package/dist/utils/sd-config.d.ts +3 -3
- package/dist/utils/sd-config.js +3 -3
- package/dist/utils/tsc-build.d.ts +13 -13
- package/dist/utils/tsc-build.d.ts.map +1 -1
- package/dist/utils/tsc-build.js +9 -9
- package/dist/utils/tsc-build.js.map +1 -1
- package/dist/utils/tsconfig.d.ts +11 -9
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js +11 -9
- package/dist/utils/tsconfig.js.map +1 -1
- package/dist/utils/typecheck-non-package.d.ts +5 -6
- package/dist/utils/typecheck-non-package.d.ts.map +1 -1
- package/dist/utils/typecheck-non-package.js +7 -8
- package/dist/utils/typecheck-non-package.js.map +1 -1
- package/dist/utils/typecheck-serialization.d.ts +8 -8
- package/dist/utils/typecheck-serialization.d.ts.map +1 -1
- package/dist/utils/typecheck-serialization.js +12 -16
- package/dist/utils/typecheck-serialization.js.map +1 -1
- package/dist/utils/vite-config.d.ts +12 -5
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +95 -41
- package/dist/utils/vite-config.js.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.d.ts.map +1 -1
- package/dist/utils/vite-scope-watch-plugin.js +1 -1
- package/dist/utils/vite-scope-watch-plugin.js.map +1 -1
- package/dist/utils/worker-events.d.ts +12 -12
- package/dist/utils/worker-events.d.ts.map +1 -1
- package/dist/utils/worker-events.js +10 -10
- package/dist/utils/worker-events.js.map +1 -1
- package/dist/utils/worker-utils.d.ts +12 -13
- package/dist/utils/worker-utils.d.ts.map +1 -1
- package/dist/utils/worker-utils.js +12 -13
- package/dist/utils/worker-utils.js.map +1 -1
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +5 -7
- package/dist/vitest-plugin.js.map +1 -1
- package/dist/workers/client.worker.d.ts +8 -2
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +215 -6
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/library-build.worker.d.ts +1 -1
- package/dist/workers/library-build.worker.d.ts.map +1 -1
- package/dist/workers/library-build.worker.js +7 -7
- package/dist/workers/library-build.worker.js.map +1 -1
- package/dist/workers/lint.worker.d.ts +2 -2
- package/dist/workers/lint.worker.js +2 -2
- package/dist/workers/ngtsc-build.worker.js +30 -30
- package/dist/workers/ngtsc-build.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts +17 -17
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +46 -46
- package/dist/workers/server-build.worker.js.map +1 -1
- package/dist/workers/server-runtime.worker.d.ts +7 -7
- package/dist/workers/server-runtime.worker.d.ts.map +1 -1
- package/dist/workers/server-runtime.worker.js +17 -17
- package/dist/workers/server-runtime.worker.js.map +1 -1
- package/docs/config.md +340 -0
- package/docs/publish-configuration-types.md +87 -0
- package/docs/pwa-configuration-types.md +55 -0
- package/docs/vitest-plugin.md +47 -0
- package/package.json +9 -7
- package/src/angular/client-transform-stylesheet.ts +1 -1
- package/src/angular/vite-angular-plugin.ts +89 -39
- package/src/angular/vite-postcss-inline-plugin.ts +1 -1
- package/src/capacitor/capacitor.ts +185 -38
- package/src/commands/build.ts +3 -10
- package/src/commands/check.ts +3 -3
- package/src/commands/dev.ts +3 -9
- package/src/commands/device.ts +5 -5
- package/src/commands/publish.ts +30 -26
- package/src/commands/replace-deps.ts +3 -3
- package/src/commands/typecheck.ts +7 -13
- package/src/commands/watch.ts +9 -9
- package/src/electron/electron.ts +49 -4
- package/src/engines/BaseEngine.ts +4 -1
- package/src/engines/NgtscEngine.ts +7 -7
- package/src/engines/ServerEsbuildEngine.ts +7 -7
- package/src/engines/TscEngine.ts +7 -7
- package/src/engines/ViteEngine.ts +18 -13
- package/src/engines/index.ts +11 -5
- package/src/engines/types.ts +20 -20
- package/src/infra/ResultCollector.ts +9 -9
- package/src/infra/SignalHandler.ts +7 -7
- package/src/infra/WorkerManager.ts +14 -14
- package/src/orchestrators/BuildOrchestrator.ts +42 -38
- package/src/orchestrators/DevWatchOrchestrator.ts +36 -36
- package/src/sd-cli-entry.ts +15 -8
- package/src/sd-cli.ts +16 -16
- package/src/sd-config.types.ts +107 -107
- package/src/utils/angular-compiler.ts +5 -5
- package/src/utils/build-env.ts +1 -1
- package/src/utils/concurrency.ts +7 -7
- package/src/utils/copy-public.ts +17 -17
- package/src/utils/copy-src.ts +11 -11
- package/src/utils/engine-stop.ts +9 -10
- package/src/utils/esbuild-config.ts +29 -29
- package/src/utils/lint-with-program.ts +34 -34
- package/src/utils/ngtsc-build-core.ts +17 -17
- package/src/utils/output-path-rewriter.ts +18 -18
- package/src/utils/output-utils.ts +11 -11
- package/src/utils/package-utils.ts +57 -45
- package/src/utils/replace-deps.ts +92 -67
- package/src/utils/sd-config.ts +3 -3
- package/src/utils/tsc-build.ts +18 -18
- package/src/utils/tsconfig.ts +11 -9
- package/src/utils/typecheck-non-package.ts +7 -8
- package/src/utils/typecheck-serialization.ts +13 -15
- package/src/utils/vite-config.ts +108 -46
- package/src/utils/vite-scope-watch-plugin.ts +6 -1
- package/src/utils/worker-events.ts +16 -16
- package/src/utils/worker-utils.ts +12 -13
- package/src/vitest-plugin.ts +5 -8
- package/src/workers/client.worker.ts +246 -7
- package/src/workers/library-build.worker.ts +8 -8
- package/src/workers/lint.worker.ts +2 -2
- package/src/workers/ngtsc-build.worker.ts +31 -31
- package/src/workers/server-build.worker.ts +60 -60
- package/src/workers/server-runtime.worker.ts +22 -22
- package/tests/angular/vite-angular-plugin-hmr-fallback.spec.ts +1 -0
- package/tests/angular/vite-angular-plugin-hmr.spec.ts +78 -0
- package/tests/angular/vite-angular-plugin.spec.ts +67 -0
- package/tests/capacitor/capacitor-build.spec.ts +93 -11
- package/tests/capacitor/capacitor-icon.spec.ts +7 -5
- package/tests/capacitor/capacitor-init.spec.ts +124 -10
- package/tests/capacitor/capacitor-run.spec.ts +14 -17
- package/tests/capacitor/capacitor-workspace.spec.ts +5 -3
- package/tests/commands/check.spec.ts +2 -2
- package/tests/commands/publish.spec.ts +2 -2
- package/tests/commands/typecheck.spec.ts +8 -0
- package/tests/electron/electron.spec.ts +12 -10
- package/tests/engines/base-engine.spec.ts +37 -0
- package/tests/engines/vite-engine.spec.ts +115 -3
- package/tests/utils/vite-config.spec.ts +162 -90
- package/tests/workers/client-worker.spec.ts +690 -0
- package/tests/workers/server-build-worker.spec.ts +3 -3
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createServer, build as viteBuild, type ViteDevServer } from "vite";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
+
import http from "node:http";
|
|
5
|
+
import mime from "mime";
|
|
4
6
|
import { createWorker } from "@simplysm/core-node";
|
|
5
7
|
import { err as errNs } from "@simplysm/core-common";
|
|
6
8
|
import { consola } from "consola";
|
|
@@ -31,8 +33,14 @@ export interface ClientBuildInfo {
|
|
|
31
33
|
browserSupport?: SdBrowserSupportConfig;
|
|
32
34
|
/** PWA 설정. false로 비활성화. 미설정 시 기본값으로 활성화 */
|
|
33
35
|
pwa?: false | SdPwaConfig;
|
|
34
|
-
/**
|
|
36
|
+
/** 컴파일의 ts.Program을 사용하여 lint 실행 */
|
|
35
37
|
enableLint?: boolean;
|
|
38
|
+
/** Vite optimizeDeps.exclude에 전달할 패키지 목록 */
|
|
39
|
+
exclude?: string[];
|
|
40
|
+
/** 빌드 출력 경로 (미설정 시 pkgDir/dist) */
|
|
41
|
+
outDir?: string;
|
|
42
|
+
/** Vite base 경로 (미설정 시 /{pkgName}/) */
|
|
43
|
+
base?: string;
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
/** Client 빌드 결과 */
|
|
@@ -58,7 +66,113 @@ export interface ClientWorkerEvents extends Record<string, unknown> {
|
|
|
58
66
|
|
|
59
67
|
const logger = consola.withTag("sd:cli:client:worker");
|
|
60
68
|
|
|
69
|
+
/** viteBuild({ build: { watch: {} } }) 반환 타입의 최소 인터페이스 */
|
|
70
|
+
interface WatcherHandle {
|
|
71
|
+
on(event: string, handler: (event: { code: string; error?: { message: string } }) => void): void;
|
|
72
|
+
close(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
let viteServer: ViteDevServer | undefined;
|
|
76
|
+
let rollupWatcher: WatcherHandle | undefined;
|
|
77
|
+
let legacyHttpServer: http.Server | undefined;
|
|
78
|
+
|
|
79
|
+
/** SSE 연결된 클라이언트 목록 (live reload용) */
|
|
80
|
+
const sseClients = new Set<http.ServerResponse>();
|
|
81
|
+
|
|
82
|
+
/** SSE 연결된 모든 클라이언트에 reload 신호를 전송한다 */
|
|
83
|
+
function notifyLiveReload(): void {
|
|
84
|
+
for (const client of sseClients) {
|
|
85
|
+
client.write("data: reload\n\n");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
/** live reload 클라이언트 스크립트 (HTML에 주입) */
|
|
91
|
+
const LIVE_RELOAD_SCRIPT = `<script>(function(){var s=new EventSource("__live-reload");s.onmessage=function(){location.reload();};})()</script>`;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* HTML 응답 시 live reload 스크립트를 </body> 직전에 주입한다.
|
|
95
|
+
*/
|
|
96
|
+
function injectLiveReloadScript(html: string): string {
|
|
97
|
+
const idx = html.lastIndexOf("</body>");
|
|
98
|
+
if (idx !== -1) {
|
|
99
|
+
return html.slice(0, idx) + LIVE_RELOAD_SCRIPT + html.slice(idx);
|
|
100
|
+
}
|
|
101
|
+
return html + LIVE_RELOAD_SCRIPT;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* legacy dev 모드용 HTTP 정적 파일 서버를 생성한다.
|
|
106
|
+
* dist/ 디렉토리의 파일을 서빙하고, SPA fallback + SSE live reload를 지원한다.
|
|
107
|
+
*/
|
|
108
|
+
function createLegacyHttpServer(distDir: string, basePath: string): http.Server {
|
|
109
|
+
return http.createServer((req, res) => {
|
|
110
|
+
const url = (req.url ?? "/").split("?")[0];
|
|
111
|
+
|
|
112
|
+
// basePath prefix 제거
|
|
113
|
+
let relativePath: string;
|
|
114
|
+
if (url.startsWith(basePath)) {
|
|
115
|
+
relativePath = url.slice(basePath.length);
|
|
116
|
+
} else {
|
|
117
|
+
res.writeHead(404);
|
|
118
|
+
res.end("Not Found");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// SSE live reload 엔드포인트
|
|
123
|
+
if (relativePath === "__live-reload" || relativePath === "/__live-reload") {
|
|
124
|
+
res.writeHead(200, {
|
|
125
|
+
"Content-Type": "text/event-stream",
|
|
126
|
+
"Cache-Control": "no-cache",
|
|
127
|
+
"Connection": "keep-alive",
|
|
128
|
+
});
|
|
129
|
+
sseClients.add(res);
|
|
130
|
+
req.on("close", () => {
|
|
131
|
+
sseClients.delete(res);
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 빈 경로 또는 / → index.html
|
|
137
|
+
if (relativePath === "" || relativePath === "/") {
|
|
138
|
+
relativePath = "index.html";
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 선행 슬래시 제거
|
|
142
|
+
if (relativePath.startsWith("/")) {
|
|
143
|
+
relativePath = relativePath.slice(1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const filePath = path.join(distDir, relativePath);
|
|
147
|
+
const ext = path.extname(filePath);
|
|
148
|
+
|
|
149
|
+
// 파일 존재 확인
|
|
150
|
+
if (fs.existsSync(filePath) && !fs.statSync(filePath).isDirectory()) {
|
|
151
|
+
const contentType = mime.getType(ext) ?? "application/octet-stream";
|
|
152
|
+
if (ext === ".html") {
|
|
153
|
+
// HTML: live reload 스크립트 주입
|
|
154
|
+
const content = injectLiveReloadScript(fs.readFileSync(filePath, "utf-8"));
|
|
155
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
156
|
+
res.end(content);
|
|
157
|
+
} else {
|
|
158
|
+
const content = fs.readFileSync(filePath);
|
|
159
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
160
|
+
res.end(content);
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
// SPA fallback: index.html 반환 (live reload 스크립트 주입)
|
|
164
|
+
const indexPath = path.join(distDir, "index.html");
|
|
165
|
+
if (fs.existsSync(indexPath)) {
|
|
166
|
+
const content = injectLiveReloadScript(fs.readFileSync(indexPath, "utf-8"));
|
|
167
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
168
|
+
res.end(content);
|
|
169
|
+
} else {
|
|
170
|
+
res.writeHead(404);
|
|
171
|
+
res.end("Not Found");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
62
176
|
|
|
63
177
|
function resolvePackageInfo(info: ClientBuildInfo): {
|
|
64
178
|
tsconfigPath: string;
|
|
@@ -77,6 +191,9 @@ function resolvePackageInfo(info: ClientBuildInfo): {
|
|
|
77
191
|
* 서버가 준비되면 serverReady 이벤트로 포트를 알린다.
|
|
78
192
|
*/
|
|
79
193
|
async function startWatch(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
194
|
+
if (info.browserSupport?.legacyModule === true) {
|
|
195
|
+
return startLegacyWatch(info);
|
|
196
|
+
}
|
|
80
197
|
logger.debug(`[${info.name}] client worker startWatch 시작 (port: ${info.port ?? "auto"})`);
|
|
81
198
|
try {
|
|
82
199
|
const { tsconfigPath, pkgName } = resolvePackageInfo(info);
|
|
@@ -102,6 +219,7 @@ async function startWatch(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
102
219
|
legacyModule: info.browserSupport?.legacyModule,
|
|
103
220
|
polyfills,
|
|
104
221
|
pwa: info.pwa,
|
|
222
|
+
exclude: info.exclude,
|
|
105
223
|
});
|
|
106
224
|
|
|
107
225
|
logger.debug(`[${info.name}] Vite server 생성 시작`);
|
|
@@ -138,15 +256,134 @@ async function startWatch(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
138
256
|
}
|
|
139
257
|
|
|
140
258
|
/**
|
|
141
|
-
*
|
|
259
|
+
* legacy watch 시작. Vite build --watch로 파일 변경을 감시한다.
|
|
260
|
+
* legacyModule: true일 때 createServer 대신 사용한다.
|
|
261
|
+
*/
|
|
262
|
+
async function startLegacyWatch(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
263
|
+
logger.debug(`[${info.name}] client worker startLegacyWatch 시작`);
|
|
264
|
+
try {
|
|
265
|
+
const { tsconfigPath, pkgName } = resolvePackageInfo(info);
|
|
266
|
+
|
|
267
|
+
// dist 초기화 (첫 빌드만 비움)
|
|
268
|
+
const distDir = path.join(info.pkgDir, "dist");
|
|
269
|
+
fs.rmSync(distDir, { recursive: true, force: true });
|
|
270
|
+
|
|
271
|
+
// polyfills.ts 자동 감지
|
|
272
|
+
const polyfillsPath = path.join(info.pkgDir, "src", "polyfills.ts");
|
|
273
|
+
const polyfills = fs.existsSync(polyfillsPath) ? ["./src/polyfills.ts"] : undefined;
|
|
274
|
+
|
|
275
|
+
const viteConfig = await createClientViteConfig({
|
|
276
|
+
pkgDir: info.pkgDir,
|
|
277
|
+
pkgName,
|
|
278
|
+
mode: "build",
|
|
279
|
+
tsconfigPath,
|
|
280
|
+
serverPort: 0,
|
|
281
|
+
env: info.env,
|
|
282
|
+
watch: true,
|
|
283
|
+
onBuildStart: () => sender.send("buildStart", {}),
|
|
284
|
+
onBuild: (result) => sender.send("build", result),
|
|
285
|
+
enableLint: info.enableLint,
|
|
286
|
+
replaceDeps: info.replaceDeps,
|
|
287
|
+
onScopeRebuild: () => sender.send("scopeRebuild", {}),
|
|
288
|
+
browserslist: info.browserSupport?.browserslist,
|
|
289
|
+
postCssPlugins: info.browserSupport?.postCss?.plugins,
|
|
290
|
+
legacyModule: info.browserSupport?.legacyModule,
|
|
291
|
+
polyfills,
|
|
292
|
+
pwa: false,
|
|
293
|
+
exclude: info.exclude,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
const watcher = (await viteBuild(viteConfig)) as WatcherHandle;
|
|
297
|
+
rollupWatcher = watcher;
|
|
298
|
+
|
|
299
|
+
// .config.json 생성
|
|
300
|
+
writeConfigJson(info.pkgDir, info.configs);
|
|
301
|
+
|
|
302
|
+
// HTTP 정적 파일 서버 시작
|
|
303
|
+
const name = pkgName.replace(/^@[^/]+\//, "");
|
|
304
|
+
const basePath = `/${name}/`;
|
|
305
|
+
const httpServer = createLegacyHttpServer(distDir, basePath);
|
|
306
|
+
legacyHttpServer = httpServer;
|
|
307
|
+
|
|
308
|
+
const serverPort = await new Promise<number>((resolve, reject) => {
|
|
309
|
+
httpServer.listen(info.port ?? 0, "0.0.0.0", () => {
|
|
310
|
+
const addr = httpServer.address();
|
|
311
|
+
if (typeof addr === "object" && addr != null) {
|
|
312
|
+
resolve(addr.port);
|
|
313
|
+
} else {
|
|
314
|
+
reject(new Error("HTTP 서버 포트를 감지할 수 없습니다."));
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
httpServer.on("error", reject);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
sender.send("serverReady", { port: serverPort });
|
|
321
|
+
|
|
322
|
+
// 첫 빌드 완료 대기
|
|
323
|
+
return await new Promise<ClientBuildResult>((resolve) => {
|
|
324
|
+
let firstBuildResolved = false;
|
|
325
|
+
|
|
326
|
+
watcher.on("event", (event: { code: string; error?: { message: string } }) => {
|
|
327
|
+
if (event.code === "END") {
|
|
328
|
+
if (!firstBuildResolved) {
|
|
329
|
+
firstBuildResolved = true;
|
|
330
|
+
resolve({ success: true });
|
|
331
|
+
} else {
|
|
332
|
+
// 재빌드 완료 → 브라우저 live reload
|
|
333
|
+
notifyLiveReload();
|
|
334
|
+
}
|
|
335
|
+
} else if (event.code === "ERROR") {
|
|
336
|
+
const message = event.error?.message ?? "Unknown build error";
|
|
337
|
+
sender.send("error", { message });
|
|
338
|
+
if (!firstBuildResolved) {
|
|
339
|
+
firstBuildResolved = true;
|
|
340
|
+
resolve({ success: false, errors: [message] });
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
} catch (err) {
|
|
346
|
+
const message = errNs.message(err);
|
|
347
|
+
sender.send("error", { message });
|
|
348
|
+
return { success: false, errors: [message] };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* dev server 중지. Vite server 또는 RollupWatcher를 정리한다.
|
|
142
354
|
*/
|
|
143
355
|
async function stopWatch(): Promise<void> {
|
|
144
356
|
logger.debug("Vite server 정리 시작");
|
|
357
|
+
|
|
358
|
+
const watcherToClose = rollupWatcher;
|
|
359
|
+
rollupWatcher = undefined;
|
|
360
|
+
if (watcherToClose != null) {
|
|
361
|
+
await watcherToClose.close();
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// SSE 클라이언트 정리
|
|
365
|
+
for (const client of sseClients) {
|
|
366
|
+
client.end();
|
|
367
|
+
}
|
|
368
|
+
sseClients.clear();
|
|
369
|
+
|
|
370
|
+
const httpServerToClose = legacyHttpServer;
|
|
371
|
+
legacyHttpServer = undefined;
|
|
372
|
+
if (httpServerToClose != null) {
|
|
373
|
+
await new Promise<void>((resolve, reject) => {
|
|
374
|
+
httpServerToClose.close((err) => {
|
|
375
|
+
if (err != null) reject(err);
|
|
376
|
+
else resolve();
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
145
381
|
const serverToClose = viteServer;
|
|
146
382
|
viteServer = undefined;
|
|
147
383
|
if (serverToClose != null) {
|
|
148
384
|
await serverToClose.close();
|
|
149
385
|
}
|
|
386
|
+
|
|
150
387
|
logger.debug("Vite server 정리 완료");
|
|
151
388
|
}
|
|
152
389
|
|
|
@@ -182,12 +419,15 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
182
419
|
legacyModule: info.browserSupport?.legacyModule,
|
|
183
420
|
polyfills,
|
|
184
421
|
pwa: info.pwa,
|
|
422
|
+
exclude: info.exclude,
|
|
423
|
+
outDir: info.outDir,
|
|
424
|
+
base: info.base,
|
|
185
425
|
});
|
|
186
426
|
|
|
187
427
|
await viteBuild(viteConfig);
|
|
188
428
|
|
|
189
|
-
// .config.json 생성
|
|
190
|
-
writeConfigJson(info.pkgDir, info.configs);
|
|
429
|
+
// .config.json 생성 (항상 dist/에 기록 — outDir과 무관)
|
|
430
|
+
writeConfigJson(path.join(info.pkgDir, "dist"), info.configs);
|
|
191
431
|
|
|
192
432
|
logger.debug(`[${info.name}] client worker build 완료`);
|
|
193
433
|
return { success: true, lint: lintResult };
|
|
@@ -198,12 +438,11 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
198
438
|
}
|
|
199
439
|
}
|
|
200
440
|
|
|
201
|
-
/**
|
|
441
|
+
/** .config.json 생성 */
|
|
202
442
|
function writeConfigJson(
|
|
203
|
-
|
|
443
|
+
distDir: string,
|
|
204
444
|
configs?: Record<string, unknown>,
|
|
205
445
|
): void {
|
|
206
|
-
const distDir = path.join(pkgDir, "dist");
|
|
207
446
|
fs.mkdirSync(distDir, { recursive: true });
|
|
208
447
|
fs.writeFileSync(
|
|
209
448
|
path.join(distDir, ".config.json"),
|
|
@@ -21,7 +21,7 @@ export interface LibraryBuildInfo {
|
|
|
21
21
|
cwd: string;
|
|
22
22
|
pkgDir: string;
|
|
23
23
|
output: BuildOutput;
|
|
24
|
-
/**
|
|
24
|
+
/** sd.config.ts의 replaceDeps 설정 */
|
|
25
25
|
replaceDeps?: Record<string, string>;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -73,7 +73,7 @@ async function build(info: LibraryBuildInfo): Promise<LibraryBuildResult> {
|
|
|
73
73
|
});
|
|
74
74
|
logger.debug(`[${info.name}] library worker build 완료 (success: ${tscResult.success})`);
|
|
75
75
|
|
|
76
|
-
//
|
|
76
|
+
// lint 실행 (활성화 + program 사용 가능 시)
|
|
77
77
|
let lint: LintWithProgramResult | undefined;
|
|
78
78
|
if (info.output.lint === true && tscResult.program != null) {
|
|
79
79
|
logger.debug(`[${info.name}] lint 시작`);
|
|
@@ -102,7 +102,7 @@ async function build(info: LibraryBuildInfo): Promise<LibraryBuildResult> {
|
|
|
102
102
|
|
|
103
103
|
const guardStartWatch = createOnceGuard("startWatch");
|
|
104
104
|
|
|
105
|
-
//
|
|
105
|
+
// watch 모드용 가변 상태
|
|
106
106
|
let watchInfo: LibraryBuildInfo | undefined;
|
|
107
107
|
let watchLintRunner: LintWithProgramRunner | undefined;
|
|
108
108
|
let lastSourceFilePaths: Set<string> | undefined;
|
|
@@ -128,10 +128,10 @@ async function rebuildAll(): Promise<CombinedBuildEvent> {
|
|
|
128
128
|
includeTests: info.output.includeTests,
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
//
|
|
131
|
+
// 의존성 필터링을 위한 소스 파일 경로 업데이트
|
|
132
132
|
lastSourceFilePaths = extractSourceFilePaths(tscResult.program) ?? lastSourceFilePaths;
|
|
133
133
|
|
|
134
|
-
//
|
|
134
|
+
// lint 실행 (활성화 + program 사용 가능 시)
|
|
135
135
|
let lint: LintWithProgramResult | undefined;
|
|
136
136
|
if (info.output.lint === true && tscResult.program != null) {
|
|
137
137
|
logger.debug(`[${info.name}] lint 시작`);
|
|
@@ -160,14 +160,14 @@ async function startWatch(info: LibraryBuildInfo): Promise<void> {
|
|
|
160
160
|
watchInfo = info;
|
|
161
161
|
|
|
162
162
|
try {
|
|
163
|
-
//
|
|
163
|
+
// 초기 빌드
|
|
164
164
|
const initialResult = await rebuildAll();
|
|
165
165
|
sender.send("build", initialResult);
|
|
166
166
|
|
|
167
|
-
//
|
|
167
|
+
// workspace 의존성 경로 + replaceDeps 수집
|
|
168
168
|
const { workspaceDeps, replaceDeps } = collectDeps(info.pkgDir, info.cwd, info.replaceDeps);
|
|
169
169
|
|
|
170
|
-
//
|
|
170
|
+
// FsWatcher 시작 — 자체 src/ + workspace 의존성 src/ + replaceDeps dist/
|
|
171
171
|
logger.debug(`[${info.name}] FsWatcher 시작`);
|
|
172
172
|
const watchPaths = [
|
|
173
173
|
pathx.posixResolve(info.pkgDir, "src", "**", "*.ts"),
|
|
@@ -4,8 +4,8 @@ import { executeLint, type LintOptions, type LintResult } from "../commands/lint
|
|
|
4
4
|
//#region Worker
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* lint 워커.
|
|
8
|
+
* check 명령어와 BuildOrchestrator에서 별도 스레드로 lint를 실행하는 워커
|
|
9
9
|
*/
|
|
10
10
|
async function lint(options: LintOptions): Promise<LintResult> {
|
|
11
11
|
return executeLint(options);
|
|
@@ -30,7 +30,7 @@ import { collectDeps } from "../utils/package-utils";
|
|
|
30
30
|
|
|
31
31
|
applyDebugLevel();
|
|
32
32
|
|
|
33
|
-
//#region
|
|
33
|
+
//#region 타입 (워커 인터페이스용 re-export)
|
|
34
34
|
|
|
35
35
|
export type { NgtscBuildInfo, NgtscBuildResult, NgtscCombinedBuildEvent };
|
|
36
36
|
|
|
@@ -69,7 +69,7 @@ async function build(info: NgtscBuildInfo): Promise<NgtscBuildResult> {
|
|
|
69
69
|
const { program, ...result } = await runNgtscBuild({ ...info, env: info.output.env });
|
|
70
70
|
logger.debug(`[${info.name}] ngtsc worker build 완료 (build.success: ${result.build.success})`);
|
|
71
71
|
|
|
72
|
-
//
|
|
72
|
+
// lint 실행 (활성화 + program 사용 가능 시)
|
|
73
73
|
if (info.output.lint === true && program != null) {
|
|
74
74
|
logger.debug(`[${info.name}] lint 시작`);
|
|
75
75
|
const lintRunner = new LintWithProgramRunner({
|
|
@@ -104,11 +104,11 @@ function extractSourceFilePaths(program: ReturnType<AngularCompiler["getTsProgra
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
107
|
+
* AngularCompiler를 사용하여 watch 빌드(초기 또는 증분)를 수행한다.
|
|
108
|
+
* 엔진에 전송할 NgtscCombinedBuildEvent를 반환한다.
|
|
109
109
|
*
|
|
110
|
-
* @param affectedFileNames -
|
|
111
|
-
*
|
|
110
|
+
* @param affectedFileNames - 제공 시(watch 재빌드) 해당 파일만 lint 수행.
|
|
111
|
+
* 미제공 시(초기 빌드) workspace 전체 파일을 lint 수행.
|
|
112
112
|
*/
|
|
113
113
|
async function performWatchBuild(
|
|
114
114
|
info: NgtscBuildInfo,
|
|
@@ -122,7 +122,7 @@ async function performWatchBuild(
|
|
|
122
122
|
const pkgSrcDir = path.join(info.pkgDir, "src");
|
|
123
123
|
const normalizedSrcDir = pathx.posix(pkgSrcDir);
|
|
124
124
|
|
|
125
|
-
//
|
|
125
|
+
// 진단 수집 — workspace 스코프 (패키지 단위 필터링 없음)
|
|
126
126
|
const allDiagnostics = [...compiler.collectDiagnostics()].filter(
|
|
127
127
|
(d) => isWorkspaceDiagnostic(d, info.cwd),
|
|
128
128
|
);
|
|
@@ -134,7 +134,7 @@ async function performWatchBuild(
|
|
|
134
134
|
.filter((d) => d.category === ts.DiagnosticCategory.Error)
|
|
135
135
|
.map(formatDiagnosticError);
|
|
136
136
|
|
|
137
|
-
//
|
|
137
|
+
// AngularCompiler로 emit + output-path-rewriting 적용
|
|
138
138
|
const loadPaths = buildScssLoadPaths(info);
|
|
139
139
|
const emitResults = compiler.emitAffectedFiles({
|
|
140
140
|
sourceFilter: (fileName: string) =>
|
|
@@ -147,17 +147,17 @@ async function performWatchBuild(
|
|
|
147
147
|
registry: sideEffectScssRegistry,
|
|
148
148
|
});
|
|
149
149
|
|
|
150
|
-
//
|
|
150
|
+
// 사이드 이펙트 SCSS 컴파일 (.scss/.css 파일 변경 없으면 건너뜀)
|
|
151
151
|
if (hasScssChanges) {
|
|
152
152
|
compileSideEffectScss(sideEffectScssRegistry, loadPaths, scssErrors, scssDependencies);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
//
|
|
155
|
+
// 전역 SCSS 컴파일
|
|
156
156
|
const globalScssErrors = compileGlobalScss(info.pkgDir, loadPaths);
|
|
157
157
|
|
|
158
158
|
const allErrors = [...errors, ...scssErrors, ...globalScssErrors];
|
|
159
159
|
|
|
160
|
-
//
|
|
160
|
+
// lint 실행 (활성화 시)
|
|
161
161
|
let lint: LintWithProgramResult | undefined;
|
|
162
162
|
if (info.output.lint === true) {
|
|
163
163
|
logger.debug(`[${info.name}] lint 시작`);
|
|
@@ -189,7 +189,7 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
189
189
|
watchInfo = { ...info, env: info.output.env };
|
|
190
190
|
|
|
191
191
|
try {
|
|
192
|
-
//
|
|
192
|
+
// tsconfig 파싱 및 컴파일러 옵션 준비
|
|
193
193
|
const parsedConfig = parseTsconfig(watchInfo.pkgDir);
|
|
194
194
|
const sourceFiles = watchInfo.output.includeTests === true
|
|
195
195
|
? getPackageFiles(watchInfo.pkgDir, parsedConfig)
|
|
@@ -202,13 +202,13 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
202
202
|
|
|
203
203
|
const angularOptions = (parsedConfig.raw?.angularCompilerOptions ?? {}) as Record<string, unknown>;
|
|
204
204
|
|
|
205
|
-
// SCSS
|
|
205
|
+
// SCSS 클로저 변수
|
|
206
206
|
const scssErrors: string[] = [];
|
|
207
207
|
const scssDependencies = new Map<string, Set<string>>();
|
|
208
208
|
const loadPaths = buildScssLoadPaths(watchInfo);
|
|
209
209
|
currentScssDependencies = scssDependencies;
|
|
210
210
|
|
|
211
|
-
//
|
|
211
|
+
// AngularSourceFileCache + AngularCompiler 생성
|
|
212
212
|
const sourceFileCache = new AngularSourceFileCache();
|
|
213
213
|
const compiler = new AngularCompiler({
|
|
214
214
|
rootNames: sourceFiles,
|
|
@@ -217,34 +217,34 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
217
217
|
sourceFileCache,
|
|
218
218
|
transformStylesheet: createLibraryTransformStylesheet(loadPaths, scssErrors, scssDependencies),
|
|
219
219
|
});
|
|
220
|
-
//
|
|
220
|
+
// 초기 빌드
|
|
221
221
|
await compiler.initialize();
|
|
222
222
|
lastSourceFilePaths = extractSourceFilePaths(compiler.getTsProgram());
|
|
223
223
|
const initialResult = await performWatchBuild(watchInfo, compiler, scssDependencies, scssErrors);
|
|
224
224
|
sender.send("build", initialResult);
|
|
225
225
|
|
|
226
|
-
//
|
|
226
|
+
// workspace 의존성 경로 + replaceDeps 수집
|
|
227
227
|
const { workspaceDeps, replaceDeps } = collectDeps(
|
|
228
228
|
watchInfo.pkgDir,
|
|
229
229
|
watchInfo.cwd,
|
|
230
230
|
watchInfo.replaceDeps,
|
|
231
231
|
);
|
|
232
232
|
|
|
233
|
-
//
|
|
233
|
+
// FsWatcher 시작
|
|
234
234
|
logger.debug(`[${watchInfo.name}] FsWatcher 시작`);
|
|
235
235
|
const watchPaths = [
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
pathx.posixResolve(watchInfo.pkgDir, "src", "**", "*.{ts,scss,css}"),
|
|
237
|
+
pathx.posixResolve(watchInfo.pkgDir, "scss", "**", "*.{scss,css}"),
|
|
238
238
|
...workspaceDeps.flatMap((d) => {
|
|
239
|
-
const depDir =
|
|
239
|
+
const depDir = pathx.posixResolve(watchInfo!.cwd, "packages", d);
|
|
240
240
|
return [
|
|
241
|
-
|
|
242
|
-
|
|
241
|
+
pathx.posixResolve(depDir, "src", "**", "*.{ts,scss,css}"),
|
|
242
|
+
pathx.posixResolve(depDir, "scss", "**", "*.{scss,css}"),
|
|
243
243
|
];
|
|
244
244
|
}),
|
|
245
245
|
...replaceDeps.flatMap((pkg) => [
|
|
246
|
-
|
|
247
|
-
|
|
246
|
+
pathx.posixResolve(watchInfo!.cwd, "node_modules", ...pkg.split("/"), "dist", "**", "*.{js,mjs,cjs}"),
|
|
247
|
+
pathx.posixResolve(watchInfo!.pkgDir, "node_modules", ...pkg.split("/"), "dist", "**", "*.{js,mjs,cjs}"),
|
|
248
248
|
]),
|
|
249
249
|
];
|
|
250
250
|
fsWatcher = await FsWatcher.watch(watchPaths);
|
|
@@ -255,12 +255,12 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
255
255
|
(c) => c.event === "add" || c.event === "unlink",
|
|
256
256
|
);
|
|
257
257
|
|
|
258
|
-
//
|
|
258
|
+
// 변경된 파일 수집 (전체 변경 + SCSS 의존성 역방향 탐색)
|
|
259
259
|
const modifiedFiles = new Set<string>();
|
|
260
260
|
for (const f of changedFiles) {
|
|
261
261
|
modifiedFiles.add(f.path);
|
|
262
262
|
|
|
263
|
-
// SCSS
|
|
263
|
+
// SCSS 의존성 역방향 탐색
|
|
264
264
|
if (
|
|
265
265
|
(f.path.endsWith(".scss") || f.path.endsWith(".css")) &&
|
|
266
266
|
currentScssDependencies != null
|
|
@@ -273,7 +273,7 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
//
|
|
276
|
+
// 의존성 필터: 관련 변경이 없으면 리빌드 건너뜀
|
|
277
277
|
if (!hasFileAddOrRemove && lastSourceFilePaths != null) {
|
|
278
278
|
const hasRelevantChange = [...modifiedFiles].some((p) =>
|
|
279
279
|
lastSourceFilePaths!.has(p),
|
|
@@ -286,17 +286,17 @@ async function startWatch(info: NgtscBuildInfo): Promise<void> {
|
|
|
286
286
|
|
|
287
287
|
sender.send("buildStart", {});
|
|
288
288
|
|
|
289
|
-
//
|
|
289
|
+
// 새 리빌드를 위해 SCSS 에러 초기화
|
|
290
290
|
scssErrors.length = 0;
|
|
291
291
|
scssDependencies.clear();
|
|
292
292
|
|
|
293
|
-
//
|
|
293
|
+
// AngularCompiler.update()를 통한 증분 리빌드
|
|
294
294
|
const updateResult = await compiler.update(modifiedFiles);
|
|
295
295
|
|
|
296
|
-
//
|
|
296
|
+
// 리빌드 후 소스 파일 경로 업데이트
|
|
297
297
|
lastSourceFilePaths = extractSourceFilePaths(compiler.getTsProgram());
|
|
298
298
|
|
|
299
|
-
//
|
|
299
|
+
// 증분 lint를 위해 영향받은 ts.SourceFile 집합을 파일명 문자열로 변환
|
|
300
300
|
const affectedFileNames = new Set<string>();
|
|
301
301
|
for (const sf of updateResult.affectedFiles) {
|
|
302
302
|
affectedFileNames.add(pathx.posix(sf.fileName));
|