@simplysm/sd-cli 14.0.48 → 14.0.51
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 +22 -679
- package/dist/engines/EsbuildClientEngine.d.ts.map +1 -1
- package/dist/engines/EsbuildClientEngine.js +1 -2
- package/dist/engines/EsbuildClientEngine.js.map +1 -1
- package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -1
- package/dist/lint/lint-core.js.map +1 -1
- package/dist/orchestrators/DevOrchestrator.js.map +1 -1
- package/dist/orchestrators/ServerRuntimeManager.d.ts.map +1 -1
- package/dist/orchestrators/ServerRuntimeManager.js +2 -4
- package/dist/orchestrators/ServerRuntimeManager.js.map +1 -1
- package/dist/ts-compiler/SdTsCompiler.d.ts +1 -7
- package/dist/ts-compiler/SdTsCompiler.d.ts.map +1 -1
- package/dist/ts-compiler/SdTsCompiler.js +109 -116
- package/dist/ts-compiler/SdTsCompiler.js.map +1 -1
- package/dist/utils/package-utils.d.ts.map +1 -1
- package/dist/utils/package-utils.js.map +1 -1
- package/docs/angular-vite-plugin/sd-angular-plugin.md +54 -0
- package/docs/config/build-target.md +31 -0
- package/docs/config/npm-config.md +27 -0
- package/docs/config/sd-browser-support-config.md +19 -0
- package/docs/config/sd-build-package-config.md +21 -0
- package/docs/config/sd-capacitor-config.md +109 -0
- package/docs/config/sd-client-package-config.md +33 -0
- package/docs/config/sd-config.md +73 -0
- package/docs/config/sd-electron-config.md +27 -0
- package/docs/config/sd-package-config.md +18 -0
- package/docs/config/sd-post-publish-script-config.md +19 -0
- package/docs/config/sd-publish-config.md +72 -0
- package/docs/config/sd-pwa-config.md +41 -0
- package/docs/config/sd-scripts-package-config.md +19 -0
- package/docs/config/sd-server-package-config.md +32 -0
- package/docs/config/sd-watch-hook-config.md +19 -0
- package/docs/ts-compiler/sd-ts-compiler.md +152 -0
- package/package.json +7 -6
- package/src/engines/EsbuildClientEngine.ts +1 -2
- package/src/esbuild/esbuild-angular-compiler-plugin.ts +1 -1
- package/src/lint/lint-core.ts +1 -1
- package/src/orchestrators/DevOrchestrator.ts +3 -3
- package/src/orchestrators/ServerRuntimeManager.ts +2 -5
- package/src/ts-compiler/SdTsCompiler.ts +136 -154
- package/src/utils/package-utils.ts +1 -2
- package/tests/angular/angular-compiler-hmr-removal.verify.md +12 -12
- package/tests/angular/onbuild-lint-removal.verify.md +4 -4
- package/tests/angular/vite-angular-plugin-sdtscompiler.verify.md +9 -9
- package/tests/angular/vite-angular-plugin-vitest.verify.md +16 -16
- package/tests/capacitor/capacitor-android-exports.verify.md +7 -7
- package/tests/commands/publish-npm-local-split.verify.md +5 -5
- package/tests/commands/publish-responsibility-split.verify.md +9 -9
- package/tests/commands/publish-set.verify.md +3 -3
- package/tests/commands/publish-storage-split.verify.md +4 -4
- package/tests/commands/slice3-severity-cleanup.verify.md +8 -8
- package/tests/deps/deps-directory-separation.verify.md +11 -11
- package/tests/deps/replace-deps/replace-deps-perf.verify.md +6 -6
- package/tests/deps/server-externals/mise-toml-parse-intent.verify.md +8 -8
- package/tests/electron/electron-symlink-cleanup.verify.md +4 -4
- package/tests/engines/engine-duplicate-output-removal.verify.md +6 -6
- package/tests/engines/engine-typecheck-selection.verify.md +4 -4
- package/tests/engines/esbuild-client-engine.verify.md +11 -11
- package/tests/engines/normalize-result.verify.md +5 -5
- package/tests/engines/vite-dependency-cleanup.verify.md +11 -11
- package/tests/esbuild/esbuild-angular-compiler-plugin-hmr.verify.md +10 -10
- package/tests/esbuild/esbuild-angular-compiler-plugin-onload.verify.md +17 -17
- package/tests/esbuild/esbuild-angular-compiler-plugin-onstart-extraction.verify.md +12 -12
- package/tests/esbuild/esbuild-angular-compiler-plugin-sdtscompiler.verify.md +11 -11
- package/tests/esbuild/esbuild-angular-compiler-plugin-stylesheet.verify.md +13 -13
- package/tests/esbuild/esbuild-angular-compiler-plugin-worker.verify.md +32 -32
- package/tests/esbuild/esbuild-angular-compiler-plugin.spec.ts +1 -1
- package/tests/esbuild/esbuild-angular-compiler-plugin.verify.md +9 -9
- package/tests/esbuild/esbuild-postcss-plugin-chunking.verify.md +3 -3
- package/tests/esbuild/esbuild-postcss-plugin.acc.spec.ts +1 -1
- package/tests/esbuild/esbuild-tsc-plugin-imports.verify.md +9 -9
- package/tests/esbuild/esbuild-tsc-plugin.acc.spec.ts +2 -2
- package/tests/esbuild/esbuild-tsc-plugin.spec.ts +3 -3
- package/tests/esbuild/esbuild-worker-plugin-node.verify.md +7 -7
- package/tests/esbuild/esbuild-worker-plugin.spec.ts +1 -1
- package/tests/esbuild/esbuild-worker-plugin.verify.md +3 -3
- package/tests/orchestrators/build-orchestrator.spec.ts +9 -9
- package/tests/orchestrators/dev-orchestrator.spec.ts +4 -4
- package/tests/orchestrators/dist-delete-watcher.verify.md +6 -6
- package/tests/orchestrators/orchestrator-baseenv.verify.md +6 -6
- package/tests/orchestrators/orchestrator-diagnostic-formatting.verify.md +6 -6
- package/tests/orchestrators/orchestrator-initializemode-signature.verify.md +5 -5
- package/tests/orchestrators/slice1-stdout-to-consola.verify.md +6 -6
- package/tests/orchestrators/watch-orchestrator.spec.ts +2 -2
- package/tests/sd-cli-catch-all.verify.md +3 -3
- package/tests/sd-cli-log-tag.verify.md +7 -7
- package/tests/ts-compiler/SdTsCompiler-affected-files.verify.md +4 -4
- package/tests/ts-compiler/SdTsCompiler-crash-handling.verify.md +24 -0
- package/tests/ts-compiler/SdTsCompiler-diagnostics.verify.md +8 -8
- package/tests/ts-compiler/SdTsCompiler-emit.verify.md +5 -5
- package/tests/ts-compiler/SdTsCompiler.verify.md +20 -20
- package/tests/ts-compiler/scss-lint-integration.verify.md +10 -10
- package/tests/utils/copy-public-outdir.verify.md +4 -4
- package/tests/utils/copy-src.spec.ts +5 -5
- package/tests/utils/dev-http-server.verify.md +4 -4
- package/tests/utils/engine-watch-events.verify.md +8 -8
- package/tests/utils/esbuild-client-config-integration.verify.md +5 -5
- package/tests/utils/esbuild-client-config-postcss.verify.md +2 -2
- package/tests/utils/esbuild-client-config.acc.spec.ts +1 -1
- package/tests/utils/esbuild-client-config.spec.ts +4 -4
- package/tests/utils/esbuild-client-config.verify.md +16 -16
- package/tests/utils/esbuild-config.spec.ts +3 -3
- package/tests/utils/esbuild-index-html.verify.md +6 -6
- package/tests/utils/esbuild-postcss-plugin.spec.ts +1 -1
- package/tests/utils/esbuild-pwa.verify.md +5 -5
- package/tests/utils/esbuild-scss-plugin.verify.md +4 -4
- package/tests/utils/hmr-client-script.acc.spec.ts +1 -1
- package/tests/utils/hmr-service.verify.md +10 -10
- package/tests/utils/lint-core-import-paths.verify.md +6 -6
- package/tests/utils/ngtsc-build-core.spec.ts +1 -1
- package/tests/utils/package-utils.spec.ts +6 -6
- package/tests/utils/replace-deps-split.verify.md +11 -11
- package/tests/utils/replace-deps-watch.verify.md +5 -5
- package/tests/utils/server-production-files-import-paths.verify.md +10 -10
- package/tests/utils/vite-config-cleanup.verify.md +3 -3
- package/tests/workers/build-watch-paths-library.verify.md +6 -6
- package/tests/workers/build-watch-paths-ngtsc-server.verify.md +8 -8
- package/tests/workers/client-worker-browser-support.verify.md +3 -3
- package/tests/workers/client-worker-cleanup.verify.md +4 -4
- package/tests/workers/client-worker-initial-build-error.verify.md +3 -3
- package/tests/workers/client-worker-initial-build-warnings.verify.md +3 -3
- package/tests/workers/client-worker-mtime-incremental.verify.md +6 -6
- package/tests/workers/client-worker-onend-sync.verify.md +3 -3
- package/tests/workers/client-worker-refactor.verify.md +18 -18
- package/tests/workers/client-worker-ts-cache-invalidation.verify.md +8 -8
- package/tests/workers/dev-port-file.verify.md +3 -3
- package/tests/workers/ngtsc-build-rootnames-refresh.verify.md +4 -4
- package/tests/workers/server-build-context-dispose.verify.md +4 -4
- package/tests/workers/server-build-worker-plugin.verify.md +5 -5
- package/tests/workers/server-build-worker-refactoring.verify.md +10 -10
- package/tests/workers/server-build-worker.spec.ts +1 -1
- package/tests/workers/server-esbuild-context-integration.verify.md +6 -6
- package/tests/workers/server-esbuild-context-tsc.verify.md +3 -3
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
5
|
+
- `@angular/build/private`에서 `createCompilerPlugin`, `SourceFileCache`, `CompilerPluginOptions`, `BundleStylesheetOptions` import가 없다: grep 결과 `@angular/build/private` 매치 없음
|
|
6
|
+
- `createAngularCompilerPlugin`이 `./esbuild-angular-compiler-plugin.js`에서 import되어 있다: line 10에서 import, line 119에서 호출 확인
|
|
7
|
+
- `ClientSourceFileCache`가 `AngularSourceFileCache`를 확장하고 `typeScriptFileCache`, `loadResultCache` 프로퍼티를 가진다: line 46-49에서 `extends AngularSourceFileCache` + 두 프로퍼티 확인
|
|
8
|
+
- `ClientEsbuildResult.sourceFileCache` 타입이 `ClientSourceFileCache`이다: line 53 확인
|
|
9
|
+
- `client.worker.ts`의 `sourceFileCache.loadResultCache.watchFiles`, `sourceFileCache.typeScriptFileCache.keys()`, `sourceFileCache.invalidate()` 접근이 새 구조와 타입 호환된다: typecheck 0 에러로 타입 호환성 확인됨
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
5
|
+
- postcssConfigPath가 CreateClientEsbuildOptions 인터페이스에서 제거됨: `esbuild-client-config.ts`에서 `postcssConfigPath` 검색 결과 없음 (No matches found). `client.worker.ts`에서도 2곳 모두 제거 확인.
|
|
6
|
+
- createScssPlugin에 로딩된 PostCSS 인스턴스가 전달됨: `esbuild-client-config.ts:118`에서 `postcssPlugins: loadedPostcssPlugins`로 `createScssPlugin`에 전달 확인.
|
|
@@ -215,7 +215,7 @@ describe("createClientEsbuildContext — PostCSS 플러그인 통합", () => {
|
|
|
215
215
|
await createClientEsbuildContext({
|
|
216
216
|
...baseBuild,
|
|
217
217
|
postcssPlugins: [["autoprefixer"]],
|
|
218
|
-
plugins: [customPlugin
|
|
218
|
+
plugins: [customPlugin],
|
|
219
219
|
legacyModule: true,
|
|
220
220
|
onEnd: vi.fn(),
|
|
221
221
|
});
|
|
@@ -294,7 +294,7 @@ describe("createClientEsbuildContext — 추가 옵션", () => {
|
|
|
294
294
|
const customPlugin = { name: "custom", setup: vi.fn() };
|
|
295
295
|
await createClientEsbuildContext({
|
|
296
296
|
...baseDev,
|
|
297
|
-
plugins: [customPlugin
|
|
297
|
+
plugins: [customPlugin],
|
|
298
298
|
});
|
|
299
299
|
const opts = vi.mocked(esbuild.context).mock.calls[0][0];
|
|
300
300
|
expect(opts.plugins).toContainEqual(customPlugin);
|
|
@@ -460,7 +460,7 @@ describe("createClientEsbuildContext — onEnd 플러그인", () => {
|
|
|
460
460
|
it("customPlugins가 angularPlugin 이전에 위치 (onStart에서 sourceFileCache 무효화 선행)", async () => {
|
|
461
461
|
await createClientEsbuildContext({
|
|
462
462
|
...baseDev,
|
|
463
|
-
plugins: [{ name: "custom", setup: vi.fn() }
|
|
463
|
+
plugins: [{ name: "custom", setup: vi.fn() }],
|
|
464
464
|
onEnd: vi.fn(),
|
|
465
465
|
});
|
|
466
466
|
const opts = vi.mocked(esbuild.context).mock.calls[0][0];
|
|
@@ -506,7 +506,7 @@ describe("createClientEsbuildContext — SCSS 플러그인 통합", () => {
|
|
|
506
506
|
const customPlugin = { name: "custom", setup: vi.fn() };
|
|
507
507
|
await createClientEsbuildContext({
|
|
508
508
|
...baseDev,
|
|
509
|
-
plugins: [customPlugin
|
|
509
|
+
plugins: [customPlugin],
|
|
510
510
|
});
|
|
511
511
|
const opts = vi.mocked(esbuild.context).mock.calls[0][0];
|
|
512
512
|
const pluginNames = opts.plugins!.map((p: any) => p.name);
|
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
## Feature 1.1a 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
5
|
+
- import 경로: `@angular/build/private`에서 `createCompilerPlugin`, `SourceFileCache`, `CompilerPluginOptions`, `BundleStylesheetOptions`를 정상 import — `private.d.ts` line 31-37에 모두 export 확인
|
|
6
|
+
- `createCompilerPlugin`의 2-param 시그니처(private export wrapper)와 일치하는 호출 — `createCompilerPlugin(pluginOptions, styleOptions)` 2개 인자로 호출 (private.d.ts의 wrapper 시그니처와 일치)
|
|
7
|
+
- `CompilerPluginOptions.sourcemap` 타입이 `boolean | 'external'` 범위 내 값 사용 — `isDev` (boolean)으로 전달, `true`/`false` 범위 내
|
|
8
|
+
- `BundleStylesheetOptions.sourcemap` 타입이 `boolean | 'external' | 'inline' | 'linked'` 범위 내 값 사용 — `isDev ? "linked" : false` 범위 내
|
|
9
|
+
- `sd-config.types.ts`의 `postCss.plugins` 타입이 Angular의 `PostcssConfiguration` 포맷과 일치 — `[string, (object | string)?][]` = Angular의 `[name: string, options?: object | string][]`
|
|
10
|
+
- `onEnd` 플러그인이 esbuild Plugin 규격(`name` + `setup`)을 준수 — `{ name: "sd-on-end", setup(build) { build.onEnd(...) } }` 규격 충족
|
|
11
|
+
- 패키지 루트 `index.ts`에서 신규 모듈 export 필요 여부 — 불필요. 기존 `esbuild-config.ts`도 내부 유틸로 export 안 함. `sd-config.types.ts`만 export 중
|
|
12
12
|
|
|
13
13
|
## Feature 1.1b-2 검증 항목
|
|
14
14
|
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
15
|
+
- `browserslist-to-esbuild` import 정상 — `import browserslistToEsbuild from "browserslist-to-esbuild"` 추가. `vite-config.ts:5`와 동일한 패턴
|
|
16
|
+
- `browserslistToEsbuild` 반환값이 esbuild target 및 BundleStylesheetOptions.target에 동시 적용 — `esbuildTarget` 변수로 통합하여 두 곳에 사용 (line 51-56, 82, 122)
|
|
17
|
+
- 에셋 복사: `copyPublicFiles(pkgDir, false)` 시그니처가 build 모드 호출 가능 — `copy-public.ts:15` 시그니처 `(pkgDir: string, includeDev: boolean): Promise<void>` 확인. build 모드에서 `false` 전달 적합
|
|
18
|
+
- 에셋 감시: `watchPublicFiles(pkgDir, true)` 시그니처가 dev 모드 호출 가능 — `copy-public.ts:58` 시그니처 `(pkgDir: string, includeDev: boolean): Promise<FsWatcher | undefined>` 확인. dev 모드에서 `true` 전달 적합
|
|
19
|
+
- 에셋 복사 함수는 `createClientEsbuildContext` 외부 호출자 담당 (설계 결정 D4) — `createClientEsbuildContext` 내부에 `copyPublicFiles`/`watchPublicFiles` 호출 없음 확인. 실제 호출 통합은 Feature 3.1에서 수행
|
|
20
20
|
|
|
21
21
|
## Feature 1.1b-1 검증 항목
|
|
22
22
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
23
|
+
- tsconfig 옵션이 CompilerPluginOptions와 esbuild context에 동일 기본값 사용 — 둘 다 `options.tsconfig ?? path.join(options.pkgDir, "tsconfig.json")`. CompilerPluginOptions(line 65)와 esbuild context(line 151)에서 동일 패턴
|
|
24
|
+
- esbuild tsconfig 옵션이 서버 빌드 패턴(D1)과 일치 — `esbuild-config.ts:94` `tsconfig: path.join(options.pkgDir, "tsconfig.json")`과 동일. 클라이언트는 추가로 `options.tsconfig` 커스텀 경로 지원 (기존 인터페이스에 이미 존재)
|
|
25
|
+
- scssPlugin loadPaths가 buildScssLoadPaths 패턴과 일치 — `ngtsc-build-core.ts:91-96`의 `[pkgDir/scss, cwd/node_modules]`와 `esbuild-client-config.ts:105-108`의 `[options.pkgDir/scss, options.cwd/node_modules]` 동일
|
|
26
|
+
- plugins 배열 순서가 구현계획과 일치 — `[angularPlugin, scssPlugin, ...customPlugins, ...onEndPlugin]` (line 153-169)
|
|
@@ -123,7 +123,7 @@ describe("createEnvBanner", () => {
|
|
|
123
123
|
describe("writeChangedOutputFiles", () => {
|
|
124
124
|
beforeEach(() => {
|
|
125
125
|
vi.clearAllMocks();
|
|
126
|
-
vi.mocked(mockFs.mkdir).mockResolvedValue(undefined
|
|
126
|
+
vi.mocked(mockFs.mkdir).mockResolvedValue(undefined);
|
|
127
127
|
vi.mocked(mockFs.writeFile).mockResolvedValue();
|
|
128
128
|
});
|
|
129
129
|
|
|
@@ -160,7 +160,7 @@ describe("writeChangedOutputFiles", () => {
|
|
|
160
160
|
});
|
|
161
161
|
|
|
162
162
|
it("skips writing when transformed content matches existing file", async () => {
|
|
163
|
-
vi.mocked(mockFs.readFile).mockResolvedValue('import { bar } from "./bar.js";'
|
|
163
|
+
vi.mocked(mockFs.readFile).mockResolvedValue('import { bar } from "./bar.js";');
|
|
164
164
|
|
|
165
165
|
await writeChangedOutputFiles([
|
|
166
166
|
{
|
|
@@ -173,7 +173,7 @@ describe("writeChangedOutputFiles", () => {
|
|
|
173
173
|
});
|
|
174
174
|
|
|
175
175
|
it("writes file when content changed", async () => {
|
|
176
|
-
vi.mocked(mockFs.readFile).mockResolvedValue('import { old } from "./old.js";'
|
|
176
|
+
vi.mocked(mockFs.readFile).mockResolvedValue('import { old } from "./old.js";');
|
|
177
177
|
|
|
178
178
|
await writeChangedOutputFiles([
|
|
179
179
|
{
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
5
|
+
- FileInfo 타입이 IndexHtmlGenerator의 FileInfo와 호환: IndexHtmlGeneratorProcessOptions.files는 `{file: string, name?: string, extension: string}` — 동일 구조 확인
|
|
6
|
+
- entrypoints 타입이 IndexHtmlGenerator의 Entrypoint와 호환: `[string, boolean][]` — `Entrypoint = [name: string, isModule: boolean]`과 동일
|
|
7
|
+
- SRI 옵션이 mode에 따라 정확히 설정: `sri: options.mode === "build"` — build일 때만 true
|
|
8
|
+
- cssBundle 연결 로직의 정확성: JS entry의 `output.cssBundle` 경로를 normalize하여 CSS output의 경로와 매칭. esbuild metafile 구조상 cssBundle은 output key와 동일 형식
|
|
9
|
+
- postTransform이 IndexHtmlGeneratorOptions에 올바르게 전달: `IndexHtmlTransform = (content: string) => Promise<string>` — GenerateIndexHtmlOptions.postTransform과 동일 타입
|
|
10
|
+
- Windows 경로 호환성: `replace(/\\/g, "/")` 로 모든 경로를 POSIX 형식으로 정규화
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
5
|
+
- augmentAppWithServiceWorker 호출 인자가 정확한가: `esbuild-pwa.ts:108-113` — `(options.pkgDir, options.cwd, options.outdir, options.baseHref)` 순서로 호출 확인
|
|
6
|
+
- 기본 ngsw-config.json에 $schema, index, assetGroups(app, assets)가 포함되는가: `esbuild-pwa.ts:83-104` — `$schema`, `index: "/index.html"`, `assetGroups: [{name: "app"}, {name: "assets"}]` 확인
|
|
7
|
+
- 등록 스크립트에서 ngsw-worker.js를 등록하는가: `esbuild-pwa.ts:119` — `register("ngsw-worker.js")` 확인. `sw.js` 참조 없음
|
|
8
|
+
- SdPwaConfig.workbox 필드를 참조하지 않는가: grep 결과 "workbox" 0건 확인. D4 결정 준수
|
|
9
|
+
- generatePwaIcons 호출 결과를 dist/icons/로 복사하는 로직이 있는가: `esbuild-pwa.ts:51-58` — `srcIconsDir(public/icons/)` → `dstIconsDir(outdir/icons/)` copyFileSync 로직 확인
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
5
|
+
- createCompilerPlugin 컴포넌트 스타일과 비충돌: `createCompilerPlugin`은 `BundleStylesheetOptions`를 받아 컴포넌트 `styleUrls`를 TypeScript 변환 과정에서 내부 처리한다. 이들은 esbuild의 일반 `onLoad` 경로를 타지 않으므로, `sd-scss` 플러그인의 `onLoad({ filter: /\.scss$/ })` 콜백은 side-effect `import "./global.scss"` 같은 일반 import만 인터셉트한다. 충돌 없음 확인.
|
|
6
|
+
- onLoad filter 정확성: `/\.scss$/` 정규식이 `.scss` 파일만 매칭 — `.css`, `.scss.ts` 등은 매칭하지 않음. 단위 테스트(`esbuild-scss-plugin.spec.ts`)에서 검증 완료.
|
|
7
|
+
- sass 라인 번호 변환: sass `span.start.line`은 0-based, esbuild `location.line`은 1-based. `line + 1` 변환 적용 확인 (`esbuild-scss-plugin.ts:31`).
|
|
8
|
+
- fileURLToPath import 정상: `url` 모듈에서 import. `scss-compiler.ts`의 `pathToFileURL`과 동일 모듈.
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
5
|
+
- ws 의존성이 sd-cli package.json dependencies에 추가되었는가: `"ws": "^8.20.0"` 확인 (package.json:51)
|
|
6
|
+
- @types/ws가 sd-cli package.json devDependencies에 추가되었는가: `"@types/ws": "^8.18.1"` 확인 (package.json:57)
|
|
7
|
+
- dev-http-server.ts의 onRequest 훅 타입 시그니처가 올바른가: `onRequest?: (req: http.IncomingMessage, res: http.ServerResponse) => boolean` — Node.js 표준 타입 사용, boolean 반환으로 처리 완료 여부 표시
|
|
8
|
+
- hmr-service.ts의 handleRequest가 angularComponentMiddleware와 동일한 encodeURIComponent 패턴을 사용하는가: `templateUpdates.get(encodeURIComponent(componentId))` (hmr-service.ts:65) — vite-angular-plugin.ts:553과 동일 패턴
|
|
9
|
+
- WebSocketServer가 httpServer의 upgrade 이벤트를 통해 연결되는가: `new WebSocketServer({ server: httpServer })` (hmr-service.ts:27) — ws 라이브러리가 httpServer의 upgrade 이벤트를 자동 처리
|
|
10
10
|
|
|
11
11
|
## Slice 2 검증 항목
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
13
|
+
- import.meta.hot 폴리필이 esbuild banner로 주입되는가: `esbuild-client-config.ts`에서 `templateUpdates != null && legacyModule !== true` 조건으로 banner 생성. `import.meta.hot.on()`, `import.meta.hot.off()`, `globalThis.__hmr_dispatch()` 제공.
|
|
14
|
+
- legacyModule일 때 폴리필이 주입되지 않는가: `options.legacyModule !== true` 조건으로 legacyModule에서 banner 미생성.
|
|
15
|
+
- ngHmrMode 가드가 있어 prod에서 실행되지 않는가: banner 코드가 `if(typeof ngHmrMode!=="undefined"&&ngHmrMode)` 가드로 래핑. prod에서 `ngHmrMode="false"`로 정의되므로 실행 안됨.
|
|
16
|
+
- sd-hmr-reset 플러그인이 onStart에서 templateUpdates.clear()를 호출하는가: `esbuild-client-config.ts`에 `sd-hmr-reset` 플러그인 추가. `build.onStart(() => { options.templateUpdates!.clear(); })` 확인.
|
|
17
|
+
- sd-hmr-reset이 angularPlugin보다 먼저 등록되는가: plugins 배열에서 `sd-hmr-reset`이 첫 번째 위치 (angularPlugin, scssPlugin보다 앞). createCompilerPlugin이 templateUpdates에 쓰기 전에 clear됨.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
5
|
+
- lint.worker.ts가 `../utils/lint-core`에서 import: `import { executeLint, type LintOptions, type LintResult } from "../utils/lint-core";` (line 2) 확인
|
|
6
|
+
- lint-utils.ts가 `./lint-core`에서 import: `import type { LintOptions, LintResult } from "./lint-core";` (line 2) 확인
|
|
7
|
+
- check.ts가 `../utils/lint-core`에서 import: `import { executeLint, type LintResult } from "../utils/lint-core";` (line 4) 확인
|
|
8
|
+
- commands/lint.ts�� `../commands/lint` import가 없음: `import { executeLint, type LintOptions } from "../utils/lint-core";` (line 1)만 존재
|
|
9
|
+
- lint-core.ts에 runLint가 없음: `executeLint`, `loadIgnorePatterns`, `LintOptions`, `LintResult`만 export
|
|
10
|
+
- commands/lint.ts에 runLint만 존재: 13줄의 thin wrapper
|
|
@@ -8,7 +8,7 @@ const mockCollectDiagnostics = vi.fn().mockReturnValue([]);
|
|
|
8
8
|
const mockEmitAffectedFiles = vi.fn().mockReturnValue([]);
|
|
9
9
|
const mockGetTsProgram = vi.fn().mockReturnValue({
|
|
10
10
|
getSourceFiles: () => [],
|
|
11
|
-
}
|
|
11
|
+
});
|
|
12
12
|
|
|
13
13
|
const angularCompilerConstructorSpy = vi.fn();
|
|
14
14
|
|
|
@@ -97,8 +97,8 @@ describe("mergeTestsPackagesIntoConfig", () => {
|
|
|
97
97
|
// Acceptance: targets 없이 watch 실행 시 tests 패키지가 포함된다
|
|
98
98
|
it("merges tests packages into config packages with target node", () => {
|
|
99
99
|
const configPackages: Record<string, SdPackageConfig | undefined> = {
|
|
100
|
-
"core-common": { target: "neutral" }
|
|
101
|
-
"core-node": { target: "node" }
|
|
100
|
+
"core-common": { target: "neutral" },
|
|
101
|
+
"core-node": { target: "node" },
|
|
102
102
|
};
|
|
103
103
|
const workspacePackages = new Map([
|
|
104
104
|
["core-common", "packages/core-common"],
|
|
@@ -124,7 +124,7 @@ describe("mergeTestsPackagesIntoConfig", () => {
|
|
|
124
124
|
// Acceptance: tests 패키지를 target으로 지정하여 watch 실행 (validateTargets에서 통합 맵 사용)
|
|
125
125
|
it("makes tests packages available for validateTargets", () => {
|
|
126
126
|
const configPackages: Record<string, SdPackageConfig | undefined> = {
|
|
127
|
-
"core-common": { target: "neutral" }
|
|
127
|
+
"core-common": { target: "neutral" },
|
|
128
128
|
};
|
|
129
129
|
const workspacePackages = new Map([
|
|
130
130
|
["core-common", "packages/core-common"],
|
|
@@ -140,7 +140,7 @@ describe("mergeTestsPackagesIntoConfig", () => {
|
|
|
140
140
|
// Unit: packages/ entries in workspacePackages are not added to merged (already in config)
|
|
141
141
|
it("does not duplicate packages/ entries from workspacePackages", () => {
|
|
142
142
|
const configPackages: Record<string, SdPackageConfig | undefined> = {
|
|
143
|
-
"core-common": { target: "neutral" }
|
|
143
|
+
"core-common": { target: "neutral" },
|
|
144
144
|
};
|
|
145
145
|
const workspacePackages = new Map([
|
|
146
146
|
["core-common", "packages/core-common"],
|
|
@@ -156,7 +156,7 @@ describe("mergeTestsPackagesIntoConfig", () => {
|
|
|
156
156
|
// Unit: empty workspacePackages returns config as-is
|
|
157
157
|
it("returns config unchanged when no workspace packages", () => {
|
|
158
158
|
const configPackages: Record<string, SdPackageConfig | undefined> = {
|
|
159
|
-
"core-common": { target: "neutral" }
|
|
159
|
+
"core-common": { target: "neutral" },
|
|
160
160
|
};
|
|
161
161
|
const workspacePackages = new Map<string, string>();
|
|
162
162
|
|
|
@@ -169,7 +169,7 @@ describe("mergeTestsPackagesIntoConfig", () => {
|
|
|
169
169
|
// Acceptance: 이름 충돌 시 에러 발생
|
|
170
170
|
it("throws when config package name collides with tests package name", () => {
|
|
171
171
|
const configPackages: Record<string, SdPackageConfig | undefined> = {
|
|
172
|
-
"orm": { target: "node" }
|
|
172
|
+
"orm": { target: "node" },
|
|
173
173
|
};
|
|
174
174
|
const workspacePackages = new Map([
|
|
175
175
|
["orm", "tests/orm"],
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
5
|
+
- 파일 구조: `replace-deps-resolve.ts` 신규 생성, `replace-deps.ts` 기존 유지 확인
|
|
6
|
+
- 해석 함수 이동: `resolveReplaceDepEntries`, `parseWorkspaceGlobs`, `collectSearchRoots`, `resolveAllReplaceDepEntries`가 `replace-deps-resolve.ts`에 위치
|
|
7
|
+
- 타입 위치: `ReplaceDepEntry`가 `replace-deps-resolve.ts`에서 export, `replace-deps.ts`에서 `export type` re-export
|
|
8
|
+
- `WatchReplaceDepResult`가 `replace-deps.ts`에서 export
|
|
9
|
+
- `replace-deps.ts`에서 `resolveAllReplaceDepEntries`를 import하여 사용
|
|
10
|
+
- `commands/publish.ts` import 경로가 `../utils/replace-deps-resolve`로 변경
|
|
11
|
+
- `sd-cli.ts`, `BaseOrchestrator.ts`, `commands/replace-deps.ts`의 import 경로는 변경 없음 (실행 함수만 사용)
|
|
12
|
+
- `tests/utils/replace-deps.spec.ts` import 경로가 `../../src/deps/replace-deps-resolve`로 변경
|
|
13
|
+
- `tests/utils/replace-deps-watch.spec.ts`, `replace-deps-watch.acc.spec.ts`의 import 경로는 변경 없음
|
|
14
|
+
- `replace-deps.ts`에서 `glob` import가 제거됨 (해석 로직 전용)
|
|
15
|
+
- `replace-deps-resolve.ts`에서 `fsx`, `FsWatcher`, `exec` import가 없음 (실행 로직 전용)
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
5
|
+
- watchReplaceDeps 시그니처에 optional `options` 파라미터가 추가되었는가: `replace-deps.ts:321`에 `options?: { onChanged?: () => void }` 확인
|
|
6
|
+
- onChanged 콜백이 파일 복사 루프 완료 후(for 루프 바깥) 호출되는가: `replace-deps.ts:393`에서 for 루프(346-392) 완료 후 `options?.onChanged?.()` 호출 확인
|
|
7
|
+
- 기존 watchReplaceDeps 호출자가 새 시그니처와 호환되는가: `DevWatchOrchestrator.ts:121`에서 2개 인자로 호출 — 3번째 optional 파라미터 생략으로 호환
|
|
8
|
+
- esbuild onEnd 플러그인(esbuild-client-config.ts)이 빌드 결과를 외부로 전달하는 경로가 존재하는가: `esbuild-client-config.ts:215-218`에 `sd-on-end` 플러그인이 `options.onEnd(result)` 호출
|
|
9
|
+
- hmrService.onBuildEnd()가 metafile 기반으로 HMR 메시지를 디스패치하는 경로가 존재하는가: `hmr-service.ts:49-133`에 metafile 기반 변경 판별 → WS broadcast 로직 존재
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
5
|
+
- 4개 함수가 utils/server-production-files.ts에 export되어 있다: line 14, 27, 68, 87에 각각 export function 확인
|
|
6
|
+
- worker에서 4개 함수 정의가 제거되었다: worker에 함수 정의 없음, import와 호출만 존재
|
|
7
|
+
- worker에서 collectAllExternals, generateProductionFiles를 새 모듈에서 import한다: line 19 `import { collectAllExternals, generateProductionFiles } from "../utils/server-production-files"`
|
|
8
|
+
- collectAllExternals 시그니처: `(pkgDir: string, manualExternals?: string[]) => string[]` — line 14 확인
|
|
9
|
+
- parseLockfileVersions 시그니처: `(cwd: string) => Map<string, string>` — line 27 확인
|
|
10
|
+
- resolveLockedVersions 시그니처: `(cwd: string, pkgNames: string[]) => Record<string, string>` — line 68 확인
|
|
11
|
+
- generateProductionFiles 시그니처: `(info: ServerBuildInfo, externals: string[]) => void` — line 87 확인
|
|
12
|
+
- worker에 build, rebuildAll, startWatch, stopWatch, cleanup, createEsbuildWatchContext가 존재한다: line 116, 148, 259, 336, 359, 488 확인
|
|
13
|
+
- worker에서 cpx import가 제거되었다: grep 결과 매칭 없음
|
|
14
|
+
- worker에서 collectAllDependencyExternals import가 제거되었다: grep 결과 매칭 없음
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
5
|
+
- enableLint 옵션 제거: `CreateClientViteConfigOptions` 인터페이스에서 `enableLint` 필드가 완전히 제거됨. `vite-config.ts` 전체에서 `enableLint` 문자열 검색 결과 0건.
|
|
6
|
+
- replaceDepDistPaths 계산 제거: `vite-config.ts` 전체에서 `replaceDepDistPaths` 문자열 검색 결과 0건. 기존 line 98-114의 계산 로직(fs.realpathSync, pathx.posix 사용)이 완전히 제거됨. `fs`와 `pathx` import도 함께 제거됨.
|
|
7
|
+
- tsconfigPath, browserslist, postCssPlugins, legacyModule은 인터페이스 옵션이 아닌 함수 내부 로컬 변수로만 존재: 모두 `loadSdConfig()` 결과에서 추출하거나 `pkgDir`에서 derive됨.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
5
|
+
- buildWatchPaths 호출 인자가 기존 코드와 동등: `srcGlobs: ["*.ts"]`, `replaceDeps: info.replaceDeps` — 기존 `pathx.posixResolve(info.pkgDir, "src", "**", "*.ts")` 패턴과 동일한 경로 생성 확인
|
|
6
|
+
- workspace deps 경로 생성이 동일: 기존 `workspaceDeps.map((d) => pathx.posixResolve(info.cwd, "packages", d, "src", "**", "*.ts"))` → buildWatchPaths 내부에서 동일하게 `pathx.posixResolve(cwd, "packages", d)` + `src/**/*.ts` 생성
|
|
7
|
+
- replaceDeps dist 경로가 cwd와 pkgDir 양쪽에서 생성됨: buildWatchPaths 내부에서 `pathx.posixResolve(cwd, "node_modules", ...pkg.split("/"), "dist", "**", "*.{js,mjs,cjs}")` 및 pkgDir 경로 동일하게 생성
|
|
8
|
+
- collectDeps import 제거됨: library-build.worker.ts에서 collectDeps가 더 이상 직접 import되지 않음 — buildWatchPaths가 내부에서 호출
|
|
9
|
+
- 변경 필터링 동작 동일: 기존 `hasFileAddOrRemove` 인라인 로직 + `lastSourceFilePaths` 교차가 `shouldSkipRebuild(changes.map(c => c.path), hasFileAddOrRemove(changes), lastSourceFilePaths, logger)`로 동일하게 대체됨
|
|
10
|
+
- 기존 테스트(library-build-worker.spec.ts) 16건 모두 통과 확인
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
5
|
+
- ngtsc-build watchPaths 동일성: `srcGlobs: ["*.{ts,scss,css}"]`, `extraDirs: [{ dir: "scss", globs: ["*.{scss,css}"] }]` — 기존 코드의 `src/**/*.{ts,scss,css}` + `scss/**/*.{scss,css}` + deps 동일 패턴과 매칭 확인
|
|
6
|
+
- ngtsc-build SCSS 역방향 탐색 유지: `hasFileAddOrRemove` → `hasFileAddOrRemoveFn`으로 변경 후에도 `modifiedFiles` 구성 로직(pipeline.findAffectedByScss)이 그대로 유지됨
|
|
7
|
+
- ngtsc-build `shouldSkipRebuild(modifiedFiles, addOrRemove, ...)`: SCSS 역방향 탐색 결과가 포함된 `modifiedFiles` Set을 Iterable로 전달하여 정확한 필터링 수행
|
|
8
|
+
- server-build watchPaths 동일성: `srcGlobs: ["*"]` — 기존 `src/**/*` 패턴과 동일
|
|
9
|
+
- server-build metafile 기반 필터링 유지: `hasFileAddOrRemoveFn(changes)` → `addOrRemove` 변수명으로 변경 외에 metafile 기반 로직(L444-470) 무변경
|
|
10
|
+
- server-build esbuild context 재생성 로직 유지: `if (addOrRemove)` 블록 내 context 재생성 로직이 기존과 동일
|
|
11
|
+
- collectDeps import 제거: ngtsc-build, server-build 모두에서 collectDeps 직접 import 제거됨 — buildWatchPaths가 내부에서 호출
|
|
12
|
+
- 기존 테스트 94건 모두 통과 확인
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
5
|
+
- loadSdConfig import 제거: `client.worker.ts` — `import { loadSdConfig }` 라인이 제거됨. `sd-config` 모듈 import 없음
|
|
6
|
+
- resolvePackageInfo가 동기 함수: `client.worker.ts:73` — `function resolvePackageInfo(info: ClientBuildInfo): {` (async 제거, Promise 반환 없음)
|
|
7
|
+
- resolvePackageInfo가 info.browserSupport 사용: `client.worker.ts:83-86` — `info.browserSupport?.legacyModule`, `info.browserSupport?.browserslist`, `info.browserSupport?.postCss?.plugins`
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
5
|
+
- resolvePackageInfo에서 tsconfigPath 반환 제거: 반환 타입이 `{ pkgName: string }`으로 변경됨. 함수 내부에서 `tsconfigPath` 변수 선언 및 계산이 제거됨. 모든 호출부(startWatch:199, startLegacyWatch:266, build:396)에서 `{ pkgName }`으로만 구조분해.
|
|
6
|
+
- startWatch에서 제거된 옵션 미전달: `createClientViteConfig` 호출에서 `tsconfigPath`, `browserslist`, `postCssPlugins`, `legacyModule`, `enableLint` 모두 제거됨.
|
|
7
|
+
- startLegacyWatch에서 제거된 옵션 미전달: 동일하게 5개 옵션 모두 제거됨.
|
|
8
|
+
- build에서 제거된 옵션 미전달: 동일하게 5개 옵션 모두 제거됨.
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
5
|
+
- client.worker.ts onEnd에서 초기 빌드 시 errors 필드가 포함되는지: `client.worker.ts:285-291` — `initialBuildResolve`에 `errors: result.errors.map((e) => e.text)` 포함 확인
|
|
6
|
+
- EsbuildClientEngine.startWatch에서 반환값의 success 확인 후 ResultCollector에 보고하는지: `EsbuildClientEngine.ts:129-138` — `!result.success` 조건으로 `resultCollector.add()` 호출 확인. logger.error는 Feature 1.2에서 제거됨 (중복 출력 방지)
|
|
7
|
+
- esbuild-client-config.ts에서 logLevel이 "silent"인지: `esbuild-client-config.ts:191` — `logLevel: "silent"` 확인. Feature 1.2에서 dev/build 모두 "silent"로 통일됨
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
5
|
+
- client.worker.ts의 initialBuildResolve에 warnings 필드가 포함되는지: `client.worker.ts:305-315` — `initialBuildResolve`에 `warnings: result.warnings.length > 0 ? result.warnings.map(formatEsbuildMessage) : undefined` 포함 확인. 후속 빌드(line 295-298)와 동일 패턴
|
|
6
|
+
- warnings가 없을 때 undefined인지: `client.worker.ts:312-314` — `result.warnings.length > 0` 조건으로 빈 배열일 때 undefined 반환 확인
|
|
7
|
+
- ClientBuildResult 인터페이스에 warnings 필드가 있는지: `client.worker.ts:47` — `warnings?: string[]` 확인. 변경 불필요
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
5
|
+
- createSourceFileCachePlugin이 IncrementalMtimeTracker를 사용하는지 확인: `client.worker.ts:198` — `const mtimeTracker = new IncrementalMtimeTracker();` 확인됨
|
|
6
|
+
- onStart에서 detectChanges 결과로 invalidate가 호출되는지 확인: `client.worker.ts:210-213` — `mtimeTracker.detectChanges(watchTargets)` 결과를 `sourceFileCache.invalidate(changedFiles)`에 전달. 기존 로직과 동작 동일
|
|
7
|
+
- onEnd에서 updateMtimes가 호출되는지 확인: `client.worker.ts:228` — `mtimeTracker.updateMtimes(watchTargets)` 호출 확인. `prevMtimes.clear()` + 전체 순회 제거됨
|
|
8
|
+
- esbuildResult == null 가드가 유지되는지 확인: onStart의 `if (esbuildResult != null)` (라인 202), onEnd의 `if (esbuildResult == null) return;` (라인 222) 모두 유지됨
|
|
9
|
+
- isInitialBuild 가드와 sender.send("buildStart")가 유지되는지 확인: `client.worker.ts:216-218` — `if (!isInitialBuild) { sender.send("buildStart", {}); }` 유지됨
|
|
10
|
+
- import 경로에 .js 확장자가 없는지 확인: `client.worker.ts:20` — `from "./incremental-mtime-tracker"` (확장자 없음)
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
5
|
+
- onEnd 타입이 `void | Promise<void>`를 허용: `esbuild-client-config.ts:29` — `onEnd?: (result: esbuild.BuildResult) => void | Promise<void>;`
|
|
6
|
+
- sd-on-end 플러그인이 onEnd 반환값을 return: `esbuild-client-config.ts:220` — `return options.onEnd!(result);`
|
|
7
|
+
- client.worker.ts onEnd가 async 직접 전달 (fire-and-forget 제거): `client.worker.ts:240` — `onEnd: async (result: esbuild.BuildResult) => {` (이전의 `void (async () => { ... })()` 패턴 제거됨)
|
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## 검증 항목
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
5
|
+
- createSourceFileCachePlugin이 모듈 스코프에 존재하고 esbuild.Plugin을 반환한다: lines 192-250, `function createSourceFileCachePlugin(): esbuild.Plugin` 반환 타입 명시, `name: "sd-build-start"` 유지
|
|
6
|
+
- createDevBuildEndHandler가 모듈 스코프에 존재하고 onEnd 콜백을 반환한다: lines 255-322, 반환 타입 `(result: esbuild.BuildResult) => Promise<void>`
|
|
7
|
+
- startWatch에서 추출 함수를 호출한다: line 385 `plugins: [createSourceFileCachePlugin()]`, line 386 `onEnd: createDevBuildEndHandler(basePath, actualPort, outdir, entryNames, info.pkgDir)`
|
|
8
|
+
- 파일 변경 감지 로직이 동일하다: createSourceFileCachePlugin onStart (lines 198-230) — watchFiles + typeScriptFileCache 순회, mtime 비교, invalidate 호출, buildStart 이벤트 전송 모두 원본과 동일
|
|
9
|
+
- mtime 기록 로직이 동일하다: createSourceFileCachePlugin onEnd (lines 232-247) — prevMtimes.clear() + mtime 기록 원본과 동일
|
|
10
|
+
- index.html 재생성 로직이 동일하다: createDevBuildEndHandler (lines 264-279) — lastMetafile 보관 + generateIndexHtml + writeFileSync 원본과 동일
|
|
11
|
+
- HMR 디스패치 로직이 동일하다: lines 281-284, `hmrService.onBuildEnd(result.metafile)` 조건부 호출 원본과 동일
|
|
12
|
+
- build 이벤트 전송 로직이 동일하다: lines 286-300, `sender.send("build", ...)` 조건부 호출 원본과 동일
|
|
13
|
+
- 초기 빌드 resolve 로직이 동일하다: lines 302-312, `isInitialBuild = false` + `initialBuildResolve?.()` 원본과 동일
|
|
14
|
+
- 에러 핸들링 로직이 동일하다: lines 313-320, catch 블록 원본과 동일
|
|
15
|
+
- 외부 인터페이스가 변경되지 않았다: export는 `export default sender`만 존재 (line 501), ClientBuildInfo/ClientBuildResult/ClientWorkerEvents 타입 변경 없음
|
|
16
|
+
- build 함수가 변경되지 않았다: lines 96-187, 원본과 동일
|
|
17
|
+
- stopWatch에 리셋 로직이 추가되었다: lines 472-475, `lastMetafile = undefined`, `isInitialBuild = true`, `initialBuildResolve = undefined`
|
|
18
|
+
- stopWatch 기존 정리 로직이 변경되지 않았다: lines 439-470, 5단계 정리(esbuild dispose, HMR 종료, HTTP 종료, public 감시 종료, index.html 감시 종료) 원본과 동일
|
|
19
|
+
- 모듈 스코프 변수가 올바르게 선언되었다: lines 67-69, 기존 변수(62-66) 바로 아래 배치
|
|
20
|
+
- startWatch가 ~110줄로 축소되었다: lines 327-434 = 107줄 (목표 ~110줄 달성)
|
|
21
|
+
- index.html watcher에서 lastMetafile 접근이 정상 동작한다: line 400, `if (lastMetafile == null) return;` — 모듈 스코프 변수로 접근
|
|
22
|
+
- 기존 테스트 6개 전부 통과: client-worker.spec.ts (3), client-worker.acc.spec.ts (3) — 회귀 없음
|