@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.
- 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 +1 -1
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +60 -34
- 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 +14 -2
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +131 -17
- 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 +18 -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 +1 -1
- package/dist/engines/ViteEngine.d.ts.map +1 -1
- package/dist/engines/ViteEngine.js +7 -12
- package/dist/engines/ViteEngine.js.map +1 -1
- package/dist/engines/index.d.ts +5 -5
- package/dist/engines/index.js +5 -5
- 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 +29 -29
- 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 +8 -5
- package/dist/utils/vite-config.d.ts.map +1 -1
- package/dist/utils/vite-config.js +36 -29
- 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 +4 -2
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +209 -1
- 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 +70 -37
- package/src/angular/vite-postcss-inline-plugin.ts +1 -1
- package/src/capacitor/capacitor.ts +159 -23
- 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 +8 -13
- package/src/engines/index.ts +5 -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 +37 -37
- 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 +45 -35
- 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 +236 -2
- 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 +6 -4
- package/tests/capacitor/capacitor-icon.spec.ts +7 -5
- package/tests/capacitor/capacitor-init.spec.ts +120 -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 +144 -90
- package/tests/workers/client-worker.spec.ts +690 -0
- package/tests/workers/server-build-worker.spec.ts +3 -3
|
@@ -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));
|
|
@@ -25,48 +25,48 @@ import { copyPublicFiles, watchPublicFiles } from "../utils/copy-public";
|
|
|
25
25
|
//#region Types
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* 서버 빌드 정보 (일회성 빌드)
|
|
29
29
|
*/
|
|
30
30
|
export interface ServerBuildInfo {
|
|
31
31
|
name: string;
|
|
32
32
|
cwd: string;
|
|
33
33
|
pkgDir: string;
|
|
34
34
|
output: BuildOutput;
|
|
35
|
-
/**
|
|
35
|
+
/** 빌드 시 치환할 환경변수 */
|
|
36
36
|
env?: Record<string, string>;
|
|
37
|
-
/**
|
|
37
|
+
/** 런타임 설정 (dist/.config.json에 기록) */
|
|
38
38
|
configs?: Record<string, unknown>;
|
|
39
|
-
/**
|
|
39
|
+
/** sd.config.ts에서 수동 지정한 외부 모듈 */
|
|
40
40
|
externals?: string[];
|
|
41
|
-
/** PM2
|
|
41
|
+
/** PM2 설정 (지정 시 dist/pm2.config.cjs 생성) */
|
|
42
42
|
pm2?: {
|
|
43
43
|
name?: string;
|
|
44
44
|
ignoreWatchPaths?: string[];
|
|
45
45
|
};
|
|
46
|
-
/**
|
|
46
|
+
/** 사용할 패키지 매니저 (mise.toml 또는 volta 설정 생성에 영향) */
|
|
47
47
|
packageManager?: "volta" | "mise";
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
51
|
+
* 서버 watch 정보
|
|
52
52
|
*/
|
|
53
53
|
export interface ServerWatchInfo {
|
|
54
54
|
name: string;
|
|
55
55
|
cwd: string;
|
|
56
56
|
pkgDir: string;
|
|
57
57
|
output: BuildOutput;
|
|
58
|
-
/**
|
|
58
|
+
/** 빌드 시 치환할 환경변수 */
|
|
59
59
|
env?: Record<string, string>;
|
|
60
|
-
/**
|
|
60
|
+
/** 런타임 설정 (dist/.config.json에 기록) */
|
|
61
61
|
configs?: Record<string, unknown>;
|
|
62
|
-
/**
|
|
62
|
+
/** sd.config.ts에서 수동 지정한 외부 모듈 */
|
|
63
63
|
externals?: string[];
|
|
64
|
-
/**
|
|
64
|
+
/** sd.config.ts의 replaceDeps 설정 */
|
|
65
65
|
replaceDeps?: Record<string, string>;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* 서버 빌드 결과 (LibraryBuildResult + mainJsPath 형태)
|
|
70
70
|
*/
|
|
71
71
|
export interface ServerBuildResult {
|
|
72
72
|
build: { success: boolean; errors?: string[]; warnings?: string[]; diagnostics: SerializedDiagnostic[] };
|
|
@@ -75,7 +75,7 @@ export interface ServerBuildResult {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* watch 모드용 통합 빌드 이벤트
|
|
79
79
|
*/
|
|
80
80
|
export interface ServerCombinedBuildEvent {
|
|
81
81
|
build: { success: boolean; errors?: string[]; warnings?: string[] };
|
|
@@ -84,7 +84,7 @@ export interface ServerCombinedBuildEvent {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
87
|
+
* 워커 이벤트 타입
|
|
88
88
|
*/
|
|
89
89
|
export interface ServerBuildWorkerEvents extends Record<string, unknown> {
|
|
90
90
|
buildStart: Record<string, never>;
|
|
@@ -100,16 +100,16 @@ applyDebugLevel();
|
|
|
100
100
|
|
|
101
101
|
const logger = consola.withTag("sd:cli:server-build:worker");
|
|
102
102
|
|
|
103
|
-
/** esbuild
|
|
103
|
+
/** esbuild 빌드 컨텍스트 (정리 대상) */
|
|
104
104
|
let esbuildContext: esbuild.BuildContext | undefined;
|
|
105
105
|
|
|
106
|
-
/**
|
|
106
|
+
/** 마지막 빌드 metafile (리빌드 시 변경 파일 필터링용) */
|
|
107
107
|
let lastMetafile: esbuild.Metafile | undefined;
|
|
108
108
|
|
|
109
|
-
/**
|
|
109
|
+
/** public 파일 감시자 (정리 대상) */
|
|
110
110
|
let publicWatcher: FsWatcher | undefined;
|
|
111
111
|
|
|
112
|
-
/**
|
|
112
|
+
/** 소스 + 스코프 패키지 감시자 (정리 대상) */
|
|
113
113
|
let srcWatcher: FsWatcher | undefined;
|
|
114
114
|
|
|
115
115
|
async function cleanup(): Promise<void> {
|
|
@@ -135,8 +135,8 @@ async function cleanup(): Promise<void> {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
/**
|
|
138
|
-
*
|
|
139
|
-
*
|
|
138
|
+
* 세 가지 소스에서 외부 모듈을 수집하고 병합한다.
|
|
139
|
+
* collectAllDependencyExternals를 통한 단일 패스 의존성 트리 순회를 사용한다.
|
|
140
140
|
*/
|
|
141
141
|
function collectAllExternals(pkgDir: string, manualExternals?: string[]): string[] {
|
|
142
142
|
logger.debug("의존성 트리 스캔 중...");
|
|
@@ -147,9 +147,9 @@ function collectAllExternals(pkgDir: string, manualExternals?: string[]): string
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
|
-
*
|
|
151
|
-
* Lockfile v9
|
|
152
|
-
*
|
|
150
|
+
* pnpm-lock.yaml의 packages 섹션을 파싱하여 name→version 맵을 생성한다.
|
|
151
|
+
* Lockfile v9 형식: `packages:` 섹션의 `'name@version':` 키를 파싱한다.
|
|
152
|
+
* YAML 파서 의존성을 피하기 위해 단순 라인 기반 파싱을 사용한다.
|
|
153
153
|
*/
|
|
154
154
|
function parseLockfileVersions(cwd: string): Map<string, string> {
|
|
155
155
|
const lockfilePath = path.join(cwd, "pnpm-lock.yaml");
|
|
@@ -160,7 +160,7 @@ function parseLockfileVersions(cwd: string): Map<string, string> {
|
|
|
160
160
|
const content = fs.readFileSync(lockfilePath, "utf-8");
|
|
161
161
|
const map = new Map<string, string>();
|
|
162
162
|
|
|
163
|
-
//
|
|
163
|
+
// "packages:" 섹션을 찾고 "'@scope/name@1.2.3':" 또는 "'name@1.2.3':" 형태의 항목을 파싱
|
|
164
164
|
const lines = content.split("\n");
|
|
165
165
|
let inPackages = false;
|
|
166
166
|
for (const line of lines) {
|
|
@@ -169,16 +169,16 @@ function parseLockfileVersions(cwd: string): Map<string, string> {
|
|
|
169
169
|
continue;
|
|
170
170
|
}
|
|
171
171
|
if (inPackages && line.length > 0 && !line.startsWith(" ") && !line.startsWith("'")) {
|
|
172
|
-
break; //
|
|
172
|
+
break; // 다음 최상위 섹션
|
|
173
173
|
}
|
|
174
174
|
if (!inPackages) continue;
|
|
175
175
|
|
|
176
|
-
//
|
|
176
|
+
// "'@scope/name@version':" 또는 "'name@version':" 매칭
|
|
177
177
|
const match = /^\s{2}'(.+)@(\d[^']*)':\s*$/.exec(line);
|
|
178
178
|
if (match != null) {
|
|
179
179
|
const name = match[1];
|
|
180
180
|
const version = match[2];
|
|
181
|
-
//
|
|
181
|
+
// 첫 번째 항목 유지 (lockfile은 각 버전을 한 번만 기록)
|
|
182
182
|
if (!map.has(name)) {
|
|
183
183
|
map.set(name, version);
|
|
184
184
|
}
|
|
@@ -189,8 +189,8 @@ function parseLockfileVersions(cwd: string): Map<string, string> {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
192
|
+
* pnpm-lock.yaml에서 주어진 모든 패키지의 잠긴 버전을 확인한다.
|
|
193
|
+
* lockfile에서 패키지를 찾을 수 없으면 에러를 던진다.
|
|
194
194
|
*/
|
|
195
195
|
function resolveLockedVersions(cwd: string, pkgNames: string[]): Record<string, string> {
|
|
196
196
|
const versionMap = parseLockfileVersions(cwd);
|
|
@@ -209,7 +209,7 @@ function resolveLockedVersions(cwd: string, pkgNames: string[]): Record<string,
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
/**
|
|
212
|
-
*
|
|
212
|
+
* 프로덕션 배포용 파일을 생성한다
|
|
213
213
|
*/
|
|
214
214
|
function generateProductionFiles(
|
|
215
215
|
info: ServerBuildInfo,
|
|
@@ -228,7 +228,7 @@ function generateProductionFiles(
|
|
|
228
228
|
distPkgJson["dependencies"] = resolveLockedVersions(info.cwd, externals);
|
|
229
229
|
}
|
|
230
230
|
if (info.packageManager === "volta") {
|
|
231
|
-
const nodeVersion = cpx.
|
|
231
|
+
const nodeVersion = cpx.spawnSync("node", ["-v"]).stdout.trim();
|
|
232
232
|
distPkgJson["volta"] = { node: nodeVersion };
|
|
233
233
|
}
|
|
234
234
|
fs.writeFileSync(path.join(distDir, "package.json"), JSON.stringify(distPkgJson, undefined, 2));
|
|
@@ -319,21 +319,21 @@ registerCleanupHandlers(cleanup, logger);
|
|
|
319
319
|
//#region Worker
|
|
320
320
|
|
|
321
321
|
/**
|
|
322
|
-
*
|
|
322
|
+
* 일회성 빌드 (프로덕션)
|
|
323
323
|
*/
|
|
324
324
|
async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
325
325
|
const mainJsPath = pathx.posixResolve(info.pkgDir, "dist", "main.js");
|
|
326
326
|
logger.debug(`[${info.name}] server worker build 시작 (js: ${info.output.js}, dts: ${info.output.dts})`);
|
|
327
327
|
|
|
328
328
|
try {
|
|
329
|
-
//
|
|
329
|
+
// tsconfig 파싱
|
|
330
330
|
const parsedConfig = parseTsconfig(info.pkgDir);
|
|
331
331
|
const entryPoints = getPackageSourceFiles(info.pkgDir, parsedConfig);
|
|
332
332
|
|
|
333
|
-
//
|
|
333
|
+
// 외부 모듈 수집
|
|
334
334
|
const external = collectAllExternals(info.pkgDir, info.externals);
|
|
335
335
|
|
|
336
|
-
// esbuild (
|
|
336
|
+
// esbuild (비동기) ‖ tsc (동기) 병렬 실행
|
|
337
337
|
const esbuildOptions = createServerEsbuildOptions({
|
|
338
338
|
pkgDir: info.pkgDir,
|
|
339
339
|
entryPoints,
|
|
@@ -360,7 +360,7 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
360
360
|
}))
|
|
361
361
|
: null;
|
|
362
362
|
|
|
363
|
-
// tsc
|
|
363
|
+
// tsc 타입체크 (항상 실행, emit은 output.dts로 제어)
|
|
364
364
|
const tscResult = runTscPackageBuild({
|
|
365
365
|
pkgDir: info.pkgDir,
|
|
366
366
|
cwd: info.cwd,
|
|
@@ -374,7 +374,7 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
374
374
|
? await esbuildPromise
|
|
375
375
|
: { success: true, errors: undefined, warnings: undefined };
|
|
376
376
|
|
|
377
|
-
//
|
|
377
|
+
// lint 실행 (활성화 + program 사용 가능 시)
|
|
378
378
|
let lint: LintWithProgramResult | undefined;
|
|
379
379
|
if (info.output.lint === true && tscResult.program != null) {
|
|
380
380
|
logger.debug(`[${info.name}] lint 시작`);
|
|
@@ -386,7 +386,7 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
386
386
|
logger.debug(`[${info.name}] lint 완료`);
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
-
//
|
|
389
|
+
// JS 출력이 요청된 경우에만 프로덕션 아티팩트 생성
|
|
390
390
|
if (info.output.js) {
|
|
391
391
|
const confDistPath = path.join(info.pkgDir, "dist", ".config.json");
|
|
392
392
|
fs.writeFileSync(confDistPath, JSON.stringify(info.configs ?? {}, undefined, 2));
|
|
@@ -424,12 +424,12 @@ async function build(info: ServerBuildInfo): Promise<ServerBuildResult> {
|
|
|
424
424
|
|
|
425
425
|
const guardStartWatch = createOnceGuard("startWatch");
|
|
426
426
|
|
|
427
|
-
//
|
|
427
|
+
// watch 모드용 가변 상태
|
|
428
428
|
let watchInfo: ServerWatchInfo | undefined;
|
|
429
429
|
let watchLintRunner: LintWithProgramRunner | undefined;
|
|
430
430
|
|
|
431
431
|
/**
|
|
432
|
-
*
|
|
432
|
+
* esbuild + tsc 병렬 리빌드 (watch 모드)
|
|
433
433
|
*/
|
|
434
434
|
async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
435
435
|
const info = watchInfo!;
|
|
@@ -437,11 +437,11 @@ async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
|
437
437
|
const mainJsPath = pathx.posixResolve(info.pkgDir, "dist", "main.js");
|
|
438
438
|
const parsedConfig = parseTsconfig(info.pkgDir);
|
|
439
439
|
|
|
440
|
-
// esbuild
|
|
440
|
+
// esbuild 리빌드 (비동기)
|
|
441
441
|
let esbuildPromise: Promise<{ success: boolean; errors?: string[]; warnings?: string[] }> | null = null;
|
|
442
442
|
if (info.output.js && esbuildContext != null) {
|
|
443
443
|
esbuildPromise = esbuildContext.rebuild().then(async (result) => {
|
|
444
|
-
//
|
|
444
|
+
// metafile 저장
|
|
445
445
|
if (result.metafile != null) {
|
|
446
446
|
lastMetafile = result.metafile;
|
|
447
447
|
}
|
|
@@ -459,7 +459,7 @@ async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
|
459
459
|
});
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
-
// tsc
|
|
462
|
+
// tsc 리빌드 (동기, 증분)
|
|
463
463
|
const tscResult = runTscPackageBuild({
|
|
464
464
|
pkgDir: info.pkgDir,
|
|
465
465
|
cwd: info.cwd,
|
|
@@ -469,7 +469,7 @@ async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
|
469
469
|
includeTests: info.output.includeTests,
|
|
470
470
|
});
|
|
471
471
|
|
|
472
|
-
//
|
|
472
|
+
// lint 실행 (활성화 + program 사용 가능 시)
|
|
473
473
|
let lint: LintWithProgramResult | undefined;
|
|
474
474
|
if (info.output.lint === true && tscResult.program != null) {
|
|
475
475
|
logger.debug(`[${info.name}] lint 시작`);
|
|
@@ -504,7 +504,7 @@ async function rebuildAll(): Promise<ServerCombinedBuildEvent> {
|
|
|
504
504
|
}
|
|
505
505
|
|
|
506
506
|
/**
|
|
507
|
-
*
|
|
507
|
+
* watch 모드용 esbuild 컨텍스트를 생성한다
|
|
508
508
|
*/
|
|
509
509
|
async function createEsbuildWatchContext(
|
|
510
510
|
info: ServerWatchInfo,
|
|
@@ -527,7 +527,7 @@ async function createEsbuildWatchContext(
|
|
|
527
527
|
}
|
|
528
528
|
|
|
529
529
|
/**
|
|
530
|
-
*
|
|
530
|
+
* watch 모드 시작
|
|
531
531
|
*/
|
|
532
532
|
async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
533
533
|
guardStartWatch();
|
|
@@ -538,33 +538,33 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
538
538
|
const parsedConfig = parseTsconfig(info.pkgDir);
|
|
539
539
|
const entryPoints = getPackageSourceFiles(info.pkgDir, parsedConfig);
|
|
540
540
|
|
|
541
|
-
//
|
|
541
|
+
// 외부 모듈 수집 (watch 모드용 캐시)
|
|
542
542
|
let cachedExternal = collectAllExternals(info.pkgDir, info.externals);
|
|
543
543
|
|
|
544
|
-
//
|
|
544
|
+
// esbuild 컨텍스트 생성 (JS 출력 필요 시)
|
|
545
545
|
if (info.output.js) {
|
|
546
546
|
esbuildContext = await createEsbuildWatchContext(info, entryPoints, cachedExternal);
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
-
//
|
|
549
|
+
// 초기 빌드: esbuild + tsc 병렬
|
|
550
550
|
sender.send("buildStart", {});
|
|
551
551
|
const initialResult = await rebuildAll();
|
|
552
552
|
|
|
553
|
-
//
|
|
553
|
+
// 첫 빌드 시 .config.json 작성
|
|
554
554
|
const confDistPath = path.join(info.pkgDir, "dist", ".config.json");
|
|
555
555
|
fs.writeFileSync(confDistPath, JSON.stringify(info.configs ?? {}, undefined, 2));
|
|
556
556
|
|
|
557
557
|
sender.send("build", initialResult);
|
|
558
558
|
|
|
559
|
-
//
|
|
559
|
+
// public/ + public-dev/ 감시
|
|
560
560
|
publicWatcher = await watchPublicFiles(info.pkgDir, true);
|
|
561
561
|
|
|
562
|
-
//
|
|
562
|
+
// 의존성 기반 감시 경로 수집
|
|
563
563
|
const { workspaceDeps, replaceDeps } = collectDeps(info.pkgDir, info.cwd, info.replaceDeps);
|
|
564
564
|
|
|
565
565
|
const watchPaths: string[] = [];
|
|
566
566
|
|
|
567
|
-
//
|
|
567
|
+
// 서버 패키지 자체 + workspace 의존성 패키지 소스
|
|
568
568
|
const watchDirs = [
|
|
569
569
|
info.pkgDir,
|
|
570
570
|
...workspaceDeps.map((d) => pathx.posixResolve(info.cwd, "packages", d)),
|
|
@@ -573,7 +573,7 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
573
573
|
watchPaths.push(pathx.posixResolve(dir, "src", "**", "*"));
|
|
574
574
|
}
|
|
575
575
|
|
|
576
|
-
//
|
|
576
|
+
// replaceDeps 의존성 패키지 dist
|
|
577
577
|
for (const pkg of replaceDeps) {
|
|
578
578
|
watchPaths.push(pathx.posixResolve(info.cwd, "node_modules", ...pkg.split("/"), "dist", "**", "*.{js,mjs,cjs}"));
|
|
579
579
|
watchPaths.push(
|
|
@@ -581,7 +581,7 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
581
581
|
);
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
-
//
|
|
584
|
+
// FsWatcher 시작
|
|
585
585
|
srcWatcher = await FsWatcher.watch(watchPaths);
|
|
586
586
|
|
|
587
587
|
srcWatcher.onChange({ delay: 300 }, async (changes) => {
|
|
@@ -591,11 +591,11 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
591
591
|
if (hasFileAddOrRemove) {
|
|
592
592
|
sender.send("buildStart", {});
|
|
593
593
|
|
|
594
|
-
//
|
|
594
|
+
// 파일 추가/삭제 시 컨텍스트 재생성
|
|
595
595
|
const newParsedConfig = parseTsconfig(info.pkgDir);
|
|
596
596
|
const newEntryPoints = getPackageSourceFiles(info.pkgDir, newParsedConfig);
|
|
597
597
|
|
|
598
|
-
//
|
|
598
|
+
// package.json이 변경된 경우에만 외부 모듈 재수집
|
|
599
599
|
const hasPackageJsonChange = changes.some((c) =>
|
|
600
600
|
c.path.endsWith("package.json"),
|
|
601
601
|
);
|
|
@@ -617,7 +617,7 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
617
617
|
return;
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
-
//
|
|
620
|
+
// 파일 변경만 있는 경우: metafile로 필터링
|
|
621
621
|
if (esbuildContext == null) {
|
|
622
622
|
sender.send("buildStart", {});
|
|
623
623
|
const result = await rebuildAll();
|
|
@@ -632,7 +632,7 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
632
632
|
return;
|
|
633
633
|
}
|
|
634
634
|
|
|
635
|
-
//
|
|
635
|
+
// metafile 입력 기반 필터링
|
|
636
636
|
const metafileAbsPaths = new Set(
|
|
637
637
|
Object.keys(lastMetafile.inputs).map((key) => pathx.posixResolve(info.cwd, key)),
|
|
638
638
|
);
|
|
@@ -656,7 +656,7 @@ async function startWatch(info: ServerWatchInfo): Promise<void> {
|
|
|
656
656
|
}
|
|
657
657
|
|
|
658
658
|
/**
|
|
659
|
-
*
|
|
659
|
+
* watch 중지
|
|
660
660
|
*/
|
|
661
661
|
async function stopWatch(): Promise<void> {
|
|
662
662
|
await cleanup();
|