@simplysm/sd-cli 14.0.42 → 14.0.44
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/dist/angular/angular-compiler.d.ts +0 -35
- package/dist/angular/angular-compiler.d.ts.map +1 -1
- package/dist/angular/angular-compiler.js +0 -374
- package/dist/angular/angular-compiler.js.map +1 -1
- package/dist/angular/hmr-candidates.d.ts +13 -0
- package/dist/angular/hmr-candidates.d.ts.map +1 -0
- package/dist/angular/hmr-candidates.js +230 -0
- package/dist/angular/hmr-candidates.js.map +1 -0
- package/dist/angular/ngtsc-build-core.d.ts +41 -37
- package/dist/angular/ngtsc-build-core.d.ts.map +1 -1
- package/dist/angular/ngtsc-build-core.js +155 -52
- package/dist/angular/ngtsc-build-core.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 +63 -56
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/angular/web-worker-transformer.d.ts +9 -0
- package/dist/angular/web-worker-transformer.d.ts.map +1 -0
- package/dist/angular/web-worker-transformer.js +73 -0
- package/dist/angular/web-worker-transformer.js.map +1 -0
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +6 -4
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/check.d.ts +1 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +15 -65
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/publish/deployment-phase.d.ts.map +1 -1
- package/dist/commands/publish/deployment-phase.js +13 -5
- package/dist/commands/publish/deployment-phase.js.map +1 -1
- package/dist/commands/publish/npm-publisher.js +1 -1
- package/dist/commands/publish/npm-publisher.js.map +1 -1
- package/dist/commands/publish/publish-command.js +1 -1
- package/dist/commands/publish/publish-command.js.map +1 -1
- package/dist/commands/publish/version-upgrade.d.ts.map +1 -1
- package/dist/commands/publish/version-upgrade.js +16 -13
- package/dist/commands/publish/version-upgrade.js.map +1 -1
- package/dist/commands/replace-deps.d.ts.map +1 -1
- package/dist/commands/replace-deps.js +2 -1
- package/dist/commands/replace-deps.js.map +1 -1
- package/dist/deps/replace-deps/collect-deps.d.ts.map +1 -1
- package/dist/deps/replace-deps/collect-deps.js +5 -2
- package/dist/deps/replace-deps/collect-deps.js.map +1 -1
- package/dist/deps/replace-deps/replace-deps-resolve.d.ts.map +1 -1
- package/dist/deps/replace-deps/replace-deps-resolve.js +6 -7
- package/dist/deps/replace-deps/replace-deps-resolve.js.map +1 -1
- package/dist/deps/replace-deps/replace-deps.d.ts +21 -3
- package/dist/deps/replace-deps/replace-deps.d.ts.map +1 -1
- package/dist/deps/replace-deps/replace-deps.js +175 -66
- package/dist/deps/replace-deps/replace-deps.js.map +1 -1
- package/dist/electron/electron.js +7 -7
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +2 -5
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/EsbuildClientEngine.d.ts.map +1 -1
- package/dist/engines/EsbuildClientEngine.js +16 -9
- package/dist/engines/EsbuildClientEngine.js.map +1 -1
- package/dist/engines/NgtscEngine.d.ts +4 -4
- package/dist/engines/NgtscEngine.d.ts.map +1 -1
- package/dist/engines/NgtscEngine.js +5 -5
- package/dist/engines/NgtscEngine.js.map +1 -1
- package/dist/engines/TscEngine.d.ts.map +1 -1
- package/dist/engines/TscEngine.js +0 -2
- package/dist/engines/TscEngine.js.map +1 -1
- package/dist/engines/types.d.ts +2 -0
- package/dist/engines/types.d.ts.map +1 -1
- package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts +36 -0
- package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts.map +1 -0
- package/dist/esbuild/esbuild-angular-compiler-plugin.js +464 -0
- package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -0
- package/dist/esbuild/esbuild-client-config.d.ts +8 -2
- package/dist/esbuild/esbuild-client-config.d.ts.map +1 -1
- package/dist/esbuild/esbuild-client-config.js +48 -33
- package/dist/esbuild/esbuild-client-config.js.map +1 -1
- package/dist/esbuild/esbuild-postcss-plugin.d.ts.map +1 -1
- package/dist/esbuild/esbuild-postcss-plugin.js +9 -6
- package/dist/esbuild/esbuild-postcss-plugin.js.map +1 -1
- package/dist/esbuild/esbuild-tsc-plugin.d.ts +4 -1
- package/dist/esbuild/esbuild-tsc-plugin.d.ts.map +1 -1
- package/dist/esbuild/esbuild-tsc-plugin.js +27 -23
- package/dist/esbuild/esbuild-tsc-plugin.js.map +1 -1
- package/dist/esbuild/file-reference-tracker.d.ts +24 -0
- package/dist/esbuild/file-reference-tracker.d.ts.map +1 -0
- package/dist/esbuild/file-reference-tracker.js +57 -0
- package/dist/esbuild/file-reference-tracker.js.map +1 -0
- package/dist/esbuild/lmdb-cache-store.d.ts +18 -0
- package/dist/esbuild/lmdb-cache-store.d.ts.map +1 -0
- package/dist/esbuild/lmdb-cache-store.js +41 -0
- package/dist/esbuild/lmdb-cache-store.js.map +1 -0
- package/dist/esbuild/load-result-cache.d.ts +17 -0
- package/dist/esbuild/load-result-cache.d.ts.map +1 -0
- package/dist/esbuild/load-result-cache.js +61 -0
- package/dist/esbuild/load-result-cache.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lint/lint-core.js +7 -7
- package/dist/lint/lint-core.js.map +1 -1
- package/dist/orchestrators/BaseOrchestrator.js +2 -2
- package/dist/orchestrators/BaseOrchestrator.js.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.d.ts.map +1 -1
- package/dist/orchestrators/BuildOrchestrator.js +5 -19
- package/dist/orchestrators/BuildOrchestrator.js.map +1 -1
- package/dist/orchestrators/DevOrchestrator.js +5 -5
- package/dist/orchestrators/DevOrchestrator.js.map +1 -1
- package/dist/orchestrators/WatchOrchestrator.js +6 -6
- package/dist/orchestrators/WatchOrchestrator.js.map +1 -1
- package/dist/runtime/ResultCollector.d.ts +1 -0
- package/dist/runtime/ResultCollector.d.ts.map +1 -1
- package/dist/runtime/ResultCollector.js.map +1 -1
- package/dist/runtime/engine-watch-events.d.ts.map +1 -1
- package/dist/runtime/engine-watch-events.js +3 -0
- package/dist/runtime/engine-watch-events.js.map +1 -1
- package/dist/runtime/rebuild-manager.js +1 -1
- package/dist/runtime/rebuild-manager.js.map +1 -1
- package/dist/runtime/worker-utils.js +1 -1
- package/dist/runtime/worker-utils.js.map +1 -1
- package/dist/sd-cli-entry.d.ts.map +1 -1
- package/dist/sd-cli-entry.js +4 -3
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.js +3 -3
- package/dist/sd-cli.js.map +1 -1
- package/dist/ts-compiler/SdTsCompiler.d.ts +39 -0
- package/dist/ts-compiler/SdTsCompiler.d.ts.map +1 -0
- package/dist/ts-compiler/SdTsCompiler.js +593 -0
- package/dist/ts-compiler/SdTsCompiler.js.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-options.d.ts +40 -0
- package/dist/ts-compiler/sd-ts-compiler-options.d.ts.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-options.js +2 -0
- package/dist/ts-compiler/sd-ts-compiler-options.js.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-result.d.ts +34 -0
- package/dist/ts-compiler/sd-ts-compiler-result.d.ts.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler-result.js +2 -0
- package/dist/ts-compiler/sd-ts-compiler-result.js.map +1 -0
- package/dist/utils/copy-public.d.ts +6 -4
- package/dist/utils/copy-public.d.ts.map +1 -1
- package/dist/utils/copy-public.js +9 -7
- package/dist/utils/copy-public.js.map +1 -1
- package/dist/utils/diagnostic-utils.d.ts +2 -3
- package/dist/utils/diagnostic-utils.d.ts.map +1 -1
- package/dist/utils/diagnostic-utils.js +8 -9
- package/dist/utils/diagnostic-utils.js.map +1 -1
- package/dist/utils/output-utils.d.ts +8 -2
- package/dist/utils/output-utils.d.ts.map +1 -1
- package/dist/utils/output-utils.js +32 -8
- package/dist/utils/output-utils.js.map +1 -1
- package/dist/workers/client.worker.d.ts +1 -1
- package/dist/workers/client.worker.d.ts.map +1 -1
- package/dist/workers/client.worker.js +115 -110
- package/dist/workers/client.worker.js.map +1 -1
- package/dist/workers/incremental-mtime-tracker.d.ts +13 -0
- package/dist/workers/incremental-mtime-tracker.d.ts.map +1 -0
- package/dist/workers/incremental-mtime-tracker.js +65 -0
- package/dist/workers/incremental-mtime-tracker.js.map +1 -0
- package/dist/workers/library-build.worker.d.ts +0 -2
- package/dist/workers/library-build.worker.d.ts.map +1 -1
- package/dist/workers/library-build.worker.js +169 -70
- package/dist/workers/library-build.worker.js.map +1 -1
- package/dist/workers/server-build.worker.d.ts.map +1 -1
- package/dist/workers/server-build.worker.js +30 -57
- package/dist/workers/server-build.worker.js.map +1 -1
- package/dist/workers/server-esbuild-context.d.ts +7 -0
- package/dist/workers/server-esbuild-context.d.ts.map +1 -1
- package/dist/workers/server-esbuild-context.js +11 -2
- package/dist/workers/server-esbuild-context.js.map +1 -1
- package/package.json +5 -4
- package/src/angular/angular-compiler.ts +0 -502
- package/src/angular/hmr-candidates.ts +295 -0
- package/src/angular/ngtsc-build-core.ts +192 -91
- package/src/angular/vite-angular-plugin.ts +71 -65
- package/src/angular/web-worker-transformer.ts +117 -0
- package/src/capacitor/capacitor.ts +6 -4
- package/src/commands/check.ts +17 -76
- package/src/commands/publish/deployment-phase.ts +11 -7
- package/src/commands/publish/npm-publisher.ts +1 -1
- package/src/commands/publish/publish-command.ts +1 -1
- package/src/commands/publish/version-upgrade.ts +44 -35
- package/src/commands/replace-deps.ts +3 -1
- package/src/deps/replace-deps/collect-deps.ts +4 -2
- package/src/deps/replace-deps/replace-deps-resolve.ts +12 -7
- package/src/deps/replace-deps/replace-deps.ts +191 -69
- package/src/electron/electron.ts +7 -7
- package/src/engines/BaseEngine.ts +2 -6
- package/src/engines/EsbuildClientEngine.ts +16 -10
- package/src/engines/NgtscEngine.ts +7 -7
- package/src/engines/TscEngine.ts +0 -2
- package/src/engines/types.ts +2 -0
- package/src/esbuild/esbuild-angular-compiler-plugin.ts +647 -0
- package/src/esbuild/esbuild-client-config.ts +57 -41
- package/src/esbuild/esbuild-postcss-plugin.ts +9 -6
- package/src/esbuild/esbuild-tsc-plugin.ts +33 -23
- package/src/esbuild/file-reference-tracker.ts +61 -0
- package/src/esbuild/lmdb-cache-store.ts +46 -0
- package/src/esbuild/load-result-cache.ts +85 -0
- package/src/index.ts +5 -0
- package/src/lint/lint-core.ts +7 -7
- package/src/orchestrators/BaseOrchestrator.ts +2 -2
- package/src/orchestrators/BuildOrchestrator.ts +5 -24
- package/src/orchestrators/DevOrchestrator.ts +5 -5
- package/src/orchestrators/WatchOrchestrator.ts +6 -6
- package/src/runtime/ResultCollector.ts +1 -0
- package/src/runtime/engine-watch-events.ts +3 -0
- package/src/runtime/rebuild-manager.ts +1 -1
- package/src/runtime/worker-utils.ts +1 -1
- package/src/sd-cli-entry.ts +5 -3
- package/src/sd-cli.ts +4 -4
- package/src/ts-compiler/SdTsCompiler.ts +815 -0
- package/src/ts-compiler/sd-ts-compiler-options.ts +46 -0
- package/src/ts-compiler/sd-ts-compiler-result.ts +34 -0
- package/src/utils/copy-public.ts +9 -6
- package/src/utils/diagnostic-utils.ts +8 -9
- package/src/utils/output-utils.ts +38 -8
- package/src/workers/client.worker.ts +141 -126
- package/src/workers/incremental-mtime-tracker.ts +68 -0
- package/src/workers/library-build.worker.ts +214 -75
- package/src/workers/server-build.worker.ts +31 -61
- package/src/workers/server-esbuild-context.ts +14 -2
- package/tests/angular/fixtures/packages/basic-app/dist/styles.css +3 -0
- package/tests/angular/fixtures/packages/basic-app/scss/styles.scss +5 -0
- package/tests/angular/ngtsc-build-core.acc.spec.ts +210 -0
- package/tests/angular/ngtsc-build-core.spec.ts +52 -0
- package/tests/angular/vite-angular-plugin-sdtscompiler.verify.md +13 -0
- package/tests/angular/web-worker-transformer.spec.ts +154 -0
- package/tests/capacitor/capacitor-build.spec.ts +1 -1
- package/tests/capacitor/capacitor-icon.spec.ts +1 -1
- package/tests/capacitor/capacitor-init.spec.ts +1 -1
- package/tests/commands/check.spec.ts +90 -104
- package/tests/commands/publish.spec.ts +12 -4
- package/tests/commands/slice3-severity-cleanup.verify.md +12 -0
- package/tests/commands/version-upgrade.acc.spec.ts +210 -0
- package/tests/commands/version-upgrade.spec.ts +148 -0
- package/tests/deps/replace-deps/collect-deps.acc.spec.ts +62 -0
- package/tests/deps/replace-deps/collect-deps.spec.ts +49 -0
- package/tests/deps/replace-deps/replace-deps-filter.spec.ts +103 -0
- package/tests/deps/replace-deps/replace-deps-perf.verify.md +15 -0
- package/tests/deps/replace-deps/replace-deps-resolve.acc.spec.ts +124 -0
- package/tests/deps/replace-deps/replace-deps-setup.acc.spec.ts +156 -0
- package/tests/electron/electron.spec.ts +4 -1
- package/tests/engines/engine-adapter-isolation.spec.ts +5 -6
- package/tests/engines/engine-duplicate-output-removal.verify.md +10 -0
- package/tests/engines/esbuild-client-engine.acc.spec.ts +79 -0
- package/tests/engines/esbuild-client-engine.spec.ts +73 -3
- package/tests/esbuild/esbuild-angular-compiler-plugin-hmr.verify.md +23 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-onload.verify.md +21 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-onstart-extraction.verify.md +16 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-sdtscompiler.verify.md +15 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-stylesheet.verify.md +31 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin-worker.verify.md +31 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin.spec.ts +397 -0
- package/tests/esbuild/esbuild-angular-compiler-plugin.verify.md +21 -0
- package/tests/esbuild/esbuild-postcss-plugin-chunking.verify.md +17 -0
- package/tests/esbuild/esbuild-postcss-plugin.acc.spec.ts +152 -0
- package/tests/esbuild/esbuild-tsc-plugin-imports.verify.md +13 -0
- package/tests/esbuild/esbuild-tsc-plugin.acc.spec.ts +56 -111
- package/tests/esbuild/esbuild-tsc-plugin.spec.ts +116 -52
- package/tests/esbuild/file-reference-tracker.spec.ts +99 -0
- package/tests/esbuild/lmdb-cache-store.spec.ts +58 -0
- package/tests/esbuild/load-result-cache.acc.spec.ts +55 -0
- package/tests/esbuild/load-result-cache.spec.ts +133 -0
- package/tests/orchestrators/build-orchestrator.spec.ts +4 -3
- package/tests/orchestrators/dev-orchestrator.spec.ts +5 -5
- package/tests/orchestrators/slice1-stdout-to-consola.verify.md +10 -0
- package/tests/orchestrators/typecheck-orchestrator.spec.ts +1 -1
- package/tests/orchestrators/watch-orchestrator.spec.ts +7 -7
- package/tests/runtime/result-collector.spec.ts +64 -0
- package/tests/sd-cli-entry.spec.ts +3 -4
- package/tests/sd-cli-log-tag.verify.md +11 -0
- package/tests/ts-compiler/SdTsCompiler-affected-files.verify.md +8 -0
- package/tests/ts-compiler/SdTsCompiler-diagnostics.verify.md +12 -0
- package/tests/ts-compiler/SdTsCompiler-emit.verify.md +9 -0
- package/tests/ts-compiler/SdTsCompiler.acc.spec.ts +603 -0
- package/tests/ts-compiler/SdTsCompiler.spec.ts +265 -0
- package/tests/ts-compiler/SdTsCompiler.verify.md +41 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-browser.tsbuildinfo +1 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck-node.tsbuildinfo +1 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/.cache/typecheck.tsbuildinfo +1 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/src/index.ts +3 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/src/util.ts +3 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/tests/sample.test-file.ts +3 -0
- package/tests/ts-compiler/fixtures/non-angular-pkg/tsconfig.json +12 -0
- package/tests/ts-compiler/scss-lint-integration.verify.md +14 -0
- package/tests/utils/angular-build.spec.ts +1 -1
- package/tests/utils/copy-public-outdir.verify.md +8 -0
- package/tests/utils/copy-public.acc.spec.ts +52 -0
- package/tests/utils/copy-public.spec.ts +56 -0
- package/tests/utils/diagnostic-utils.spec.ts +24 -15
- package/tests/utils/engine-watch-events.acc.spec.ts +59 -0
- package/tests/utils/engine-watch-events.spec.ts +58 -0
- package/tests/utils/esbuild-client-config-integration.verify.md +9 -0
- package/tests/utils/esbuild-client-config.acc.spec.ts +45 -61
- package/tests/utils/esbuild-client-config.spec.ts +70 -52
- package/tests/utils/ngtsc-build-core-write-emit.spec.ts +136 -12
- package/tests/utils/ngtsc-build-core.spec.ts +1 -44
- package/tests/utils/output-utils.spec.ts +133 -13
- package/tests/utils/replace-deps-watch.acc.spec.ts +7 -1
- package/tests/utils/replace-deps-watch.spec.ts +57 -1
- package/tests/utils/worker-utils.spec.ts +8 -2
- package/tests/workers/client-worker-initial-build-error.verify.md +2 -3
- package/tests/workers/client-worker-initial-build-warnings.verify.md +7 -0
- package/tests/workers/client-worker-mtime-incremental.verify.md +10 -0
- package/tests/workers/client-worker-refactor.verify.md +22 -0
- package/tests/workers/client-worker-ts-cache-invalidation.verify.md +12 -0
- package/tests/workers/client-worker.acc.spec.ts +6 -3
- package/tests/workers/incremental-mtime-tracker.acc.spec.ts +144 -0
- package/tests/workers/incremental-mtime-tracker.spec.ts +102 -0
- package/tests/workers/library-build-lint.spec.ts +40 -45
- package/tests/workers/library-build-worker.spec.ts +298 -40
- package/tests/workers/server-build-lint.spec.ts +59 -45
- package/tests/workers/server-build-worker.spec.ts +63 -24
- package/tests/workers/server-esbuild-context.acc.spec.ts +2 -0
- package/tests/workers/server-esbuild-context.spec.ts +2 -0
- package/tests/workers/server-runtime-worker.spec.ts +1 -1
- package/tests/workers/shared-worker-lifecycle.acc.spec.ts +1 -1
- package/dist/angular/angular-build-pipeline.d.ts +0 -97
- package/dist/angular/angular-build-pipeline.d.ts.map +0 -1
- package/dist/angular/angular-build-pipeline.js +0 -285
- package/dist/angular/angular-build-pipeline.js.map +0 -1
- package/dist/utils/tsc-build.d.ts +0 -51
- package/dist/utils/tsc-build.d.ts.map +0 -1
- package/dist/utils/tsc-build.js +0 -156
- package/dist/utils/tsc-build.js.map +0 -1
- package/dist/workers/ngtsc-build.worker.d.ts +0 -23
- package/dist/workers/ngtsc-build.worker.d.ts.map +0 -1
- package/dist/workers/ngtsc-build.worker.js +0 -267
- package/dist/workers/ngtsc-build.worker.js.map +0 -1
- package/src/angular/angular-build-pipeline.ts +0 -406
- package/src/utils/tsc-build.ts +0 -226
- package/src/workers/ngtsc-build.worker.ts +0 -351
- package/tests/angular/angular-build-pipeline.spec.ts +0 -247
- package/tests/angular/angular-compiler-aot.acc.spec.ts +0 -68
- package/tests/angular/angular-compiler-aot.spec.ts +0 -80
- package/tests/utils/angular-compiler-emit.spec.ts +0 -666
- package/tests/utils/angular-compiler.spec.ts +0 -707
- package/tests/utils/tsc-build.spec.ts +0 -527
- package/tests/workers/ngtsc-build-lint.spec.ts +0 -141
- package/tests/workers/ngtsc-build-worker.spec.ts +0 -199
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type ts from "typescript";
|
|
2
|
+
import type { AngularSourceFileCache } from "../angular/angular-compiler";
|
|
3
|
+
import type { TypecheckEnv } from "../utils/tsconfig";
|
|
4
|
+
|
|
5
|
+
export interface ISdTsCompilerEmitOptions {
|
|
6
|
+
/** emit 대상 소스 필터 (Angular only, 지정 시 해당 파일만 EmitResult에 포함) */
|
|
7
|
+
sourceFilter?: (fileName: string) => boolean;
|
|
8
|
+
/** Angular transformers 외 추가 transformers (Angular only) */
|
|
9
|
+
additionalTransformers?: {
|
|
10
|
+
before?: ts.TransformerFactory<ts.SourceFile>[];
|
|
11
|
+
after?: ts.TransformerFactory<ts.SourceFile>[];
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ISdTsCompilerOptions {
|
|
16
|
+
/** 패키지 디렉토리 */
|
|
17
|
+
pkgDir: string;
|
|
18
|
+
/** workspace 루트 (diagnostics 필터링 등에 사용) */
|
|
19
|
+
cwd: string;
|
|
20
|
+
/** 출력 제어 플래그 */
|
|
21
|
+
output: { js: boolean; dts: boolean };
|
|
22
|
+
/** tests/ 파일을 rootNames에 포함할지 여부. 기본값 false */
|
|
23
|
+
includeTests?: boolean;
|
|
24
|
+
/** 타입체크 환경. 설정 시 getCompilerOptionsForEnv()를 적용 */
|
|
25
|
+
env?: TypecheckEnv;
|
|
26
|
+
|
|
27
|
+
// === Angular 전용 (선택적, isForAngular 시 활성화) ===
|
|
28
|
+
/** SourceFile 캐시 (Angular 증분 빌드용). 미제공 시 내부 생성 */
|
|
29
|
+
sourceFileCache?: AngularSourceFileCache;
|
|
30
|
+
/** 스타일시트 변환 콜백 (Feature 1.3에서 활용) */
|
|
31
|
+
transformStylesheet?: (
|
|
32
|
+
data: string,
|
|
33
|
+
containingFile: string,
|
|
34
|
+
stylesheetFile?: string,
|
|
35
|
+
) => Promise<string | null>;
|
|
36
|
+
/** 외부 스타일시트 맵 (클라이언트 빌드용, resourceNameToFileName에서 사용) */
|
|
37
|
+
externalStylesheets?: Map<string, string>;
|
|
38
|
+
/** compilerOptions 후처리 (클라이언트의 target/module 강제 등) */
|
|
39
|
+
compilerOptionsTransformer?: (options: ts.CompilerOptions) => ts.CompilerOptions;
|
|
40
|
+
|
|
41
|
+
// === SCSS/lint 통합 (Feature 1.3) ===
|
|
42
|
+
/** lint 실행 여부. true이면 compileAsync 결과에 lint 결과 포함 */
|
|
43
|
+
lint?: boolean;
|
|
44
|
+
/** 글로벌 SCSS 컴파일 여부. true이면 scss/styles.scss → dist/styles.css 생성 */
|
|
45
|
+
globalScss?: boolean;
|
|
46
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type ts from "typescript";
|
|
2
|
+
import type { SerializedDiagnostic } from "../typecheck/typecheck-serialization";
|
|
3
|
+
import type { EmitResult } from "../angular/angular-compiler";
|
|
4
|
+
import type { LintWithProgramResult } from "../lint/lint-with-program";
|
|
5
|
+
import type { NgtscProgram } from "../angular/angular-build";
|
|
6
|
+
|
|
7
|
+
export interface ISdTsCompilerResult {
|
|
8
|
+
/** TypeScript Program 참조 (lint, 외부 도구용) */
|
|
9
|
+
program: ts.Program;
|
|
10
|
+
/** Builder Program 참조 */
|
|
11
|
+
builderProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram;
|
|
12
|
+
/** Angular 패키지 여부 */
|
|
13
|
+
isForAngular: boolean;
|
|
14
|
+
/** 이 빌드에서 영향받은 파일 (posix 경로). undefined = 전역 변경 (전체 리빌드) */
|
|
15
|
+
affectedFiles: ReadonlySet<string> | undefined;
|
|
16
|
+
/** 직렬화된 진단 정보 (Worker 경계 통과용) */
|
|
17
|
+
diagnostics: SerializedDiagnostic[];
|
|
18
|
+
/** Error 카테고리 진단 수 */
|
|
19
|
+
errorCount: number;
|
|
20
|
+
/** Warning 카테고리 진단 수 */
|
|
21
|
+
warningCount: number;
|
|
22
|
+
/** Error 카테고리 진단을 "파일:줄:열: TS코드: 메시지" 형식으로 포맷한 배열 */
|
|
23
|
+
errors?: string[];
|
|
24
|
+
/** NgtscProgram 참조 (Angular only, HMR용). Non-Angular이면 undefined */
|
|
25
|
+
ngtscProgram?: NgtscProgram;
|
|
26
|
+
/** Angular emit 결과 (Non-Angular이면 undefined — writeFile 훅으로 디스크 직접 쓰기) */
|
|
27
|
+
emitResults?: EmitResult[];
|
|
28
|
+
/** lint 결과 (lint 옵션 활성 시) */
|
|
29
|
+
lint?: LintWithProgramResult;
|
|
30
|
+
/** SCSS 에러 목록 */
|
|
31
|
+
scssErrors: string[];
|
|
32
|
+
/** SCSS 의존성 맵 (소유자 파일 → 의존 SCSS 경로 집합). watch 역방향 탐색용 */
|
|
33
|
+
scssDependencies: ReadonlyMap<string, ReadonlySet<string>>;
|
|
34
|
+
}
|
package/src/utils/copy-public.ts
CHANGED
|
@@ -6,14 +6,15 @@ import {
|
|
|
6
6
|
} from "@simplysm/core-node";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* public/ 및 public-dev/ 디렉토리의 파일을
|
|
9
|
+
* public/ 및 public-dev/ 디렉토리의 파일을 출력 디렉토리로 복사한다.
|
|
10
10
|
* public-dev/가 public/보다 우선한다 (오버레이).
|
|
11
11
|
*
|
|
12
12
|
* @param pkgDir 패키지 루트 디렉토리
|
|
13
13
|
* @param includeDev public-dev/ 포함 여부 (dev 모드에서만 true)
|
|
14
|
+
* @param outDir 출력 디렉토리 (미지정 시 pkgDir/dist)
|
|
14
15
|
*/
|
|
15
|
-
export async function copyPublicFiles(pkgDir: string, includeDev: boolean): Promise<void> {
|
|
16
|
-
const distDir = pathx.posix(path.join(pkgDir, "dist"));
|
|
16
|
+
export async function copyPublicFiles(pkgDir: string, includeDev: boolean, outDir?: string): Promise<void> {
|
|
17
|
+
const distDir = pathx.posix(outDir ?? path.join(pkgDir, "dist"));
|
|
17
18
|
await fsx.mkdir(distDir);
|
|
18
19
|
|
|
19
20
|
// public/ 복사
|
|
@@ -48,23 +49,25 @@ export async function copyPublicFiles(pkgDir: string, includeDev: boolean): Prom
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
|
-
* public/ 및 public-dev/ 디렉토리를 감시하고 변경사항을 실시간으로
|
|
52
|
+
* public/ 및 public-dev/ 디렉토리를 감시하고 변경사항을 실시간으로 출력 디렉토리에 복사한다.
|
|
52
53
|
* 초기 복사 후 변경/추가/삭제를 자동으로 반영한다.
|
|
53
54
|
*
|
|
54
55
|
* @param pkgDir 패키지 루트 디렉토리
|
|
55
56
|
* @param includeDev public-dev/ 포함 여부 (dev 모드에서만 true)
|
|
57
|
+
* @param outDir 출력 디렉토리 (미지정 시 pkgDir/dist)
|
|
56
58
|
* @returns FsWatcher 인스턴스 (종료 시 close() 호출 필요) 또는 감시 대상이 없으면 undefined
|
|
57
59
|
*/
|
|
58
60
|
export async function watchPublicFiles(
|
|
59
61
|
pkgDir: string,
|
|
60
62
|
includeDev: boolean,
|
|
63
|
+
outDir?: string,
|
|
61
64
|
): Promise<FsWatcher | undefined> {
|
|
62
|
-
const distDir = pathx.posix(path.join(pkgDir, "dist"));
|
|
65
|
+
const distDir = pathx.posix(outDir ?? path.join(pkgDir, "dist"));
|
|
63
66
|
const publicDir = pathx.posix(path.join(pkgDir, "public"));
|
|
64
67
|
const publicDevDir = pathx.posix(path.join(pkgDir, "public-dev"));
|
|
65
68
|
|
|
66
69
|
// 초기 복사
|
|
67
|
-
await copyPublicFiles(pkgDir, includeDev);
|
|
70
|
+
await copyPublicFiles(pkgDir, includeDev, outDir);
|
|
68
71
|
|
|
69
72
|
// 감시 대상 경로 수집
|
|
70
73
|
const watchPaths: string[] = [];
|
|
@@ -30,14 +30,13 @@ export function formatDiagnosticsOutput(diagnostics: ts.Diagnostic[], cwd: strin
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* 진단 에러를
|
|
34
|
-
* 파일 정보가 없는 경우 "TS코드: 메시지" 형식으로 반환한다.
|
|
33
|
+
* 진단 에러를 TypeScript 네이티브 컬러+코드 컨텍스트 포맷으로 변환한다.
|
|
35
34
|
*/
|
|
36
|
-
export function formatDiagnosticError(diagnostic: ts.Diagnostic): string {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
return
|
|
35
|
+
export function formatDiagnosticError(diagnostic: ts.Diagnostic, cwd: string): string {
|
|
36
|
+
const formatHost: ts.FormatDiagnosticsHost = {
|
|
37
|
+
getCanonicalFileName: (f) => f,
|
|
38
|
+
getCurrentDirectory: () => cwd,
|
|
39
|
+
getNewLine: () => ts.sys.newLine,
|
|
40
|
+
};
|
|
41
|
+
return ts.formatDiagnosticsWithColorAndContext([diagnostic], formatHost).trimEnd();
|
|
43
42
|
}
|
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
import { formatMessagesSync, type PartialMessage } from "esbuild";
|
|
1
2
|
import { consola } from "consola";
|
|
2
3
|
import type { BuildResult } from "../runtime/ResultCollector";
|
|
3
4
|
|
|
5
|
+
const logger = consola.withTag("sd:cli:output");
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* esbuild Message 배열을 포맷된 문자열 배열로 변환한다.
|
|
9
|
+
* esbuild 네이티브 포맷(코드 컨텍스트, 위치 정보, 밑줄)을 유지한다.
|
|
10
|
+
*/
|
|
11
|
+
export function formatEsbuildMessages(
|
|
12
|
+
messages: PartialMessage[],
|
|
13
|
+
kind: "error" | "warning",
|
|
14
|
+
): string[] {
|
|
15
|
+
if (messages.length === 0) return [];
|
|
16
|
+
return formatMessagesSync(messages, { kind, color: true }).map((msg) =>
|
|
17
|
+
msg.replace(/^.*?\x1b\[0m |^X \[ERROR] |^▲ \[WARNING] /, "").trimEnd(),
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
4
21
|
/**
|
|
5
22
|
* 빌드 경고/에러 메시지를 포맷팅한다.
|
|
6
23
|
*/
|
|
@@ -8,27 +25,40 @@ export function formatBuildMessages(name: string, label: string, messages: strin
|
|
|
8
25
|
const lines: string[] = [`${name} (${label})`];
|
|
9
26
|
for (const msg of messages) {
|
|
10
27
|
for (const line of msg.split("\n")) {
|
|
11
|
-
|
|
28
|
+
if (line === "") {
|
|
29
|
+
lines.push("");
|
|
30
|
+
} else {
|
|
31
|
+
lines.push(` ${line}`);
|
|
32
|
+
}
|
|
12
33
|
}
|
|
13
34
|
}
|
|
14
35
|
return lines.join("\n");
|
|
15
36
|
}
|
|
16
37
|
|
|
17
38
|
/**
|
|
18
|
-
*
|
|
39
|
+
* 에러와 경고를 출력한다. 에러를 먼저, 경고를 나중에 출력한다.
|
|
19
40
|
* @param results 패키지별 빌드 결과 상태
|
|
20
41
|
*/
|
|
21
|
-
export function
|
|
42
|
+
export function printDiagnostics(results: ReadonlyMap<string, BuildResult>): void {
|
|
43
|
+
// 에러 출력
|
|
22
44
|
for (const result of results.values()) {
|
|
23
45
|
if (result.status === "error") {
|
|
24
46
|
const typeLabel = result.type === "lint" ? "lint" : result.target;
|
|
25
47
|
if (result.message != null && result.message !== "") {
|
|
26
|
-
|
|
48
|
+
logger.error(formatBuildMessages(result.name, typeLabel, [result.message]));
|
|
27
49
|
} else {
|
|
28
|
-
|
|
50
|
+
logger.error(`[${result.name}] (${typeLabel}) 실패`);
|
|
29
51
|
}
|
|
30
52
|
}
|
|
31
53
|
}
|
|
54
|
+
|
|
55
|
+
// 경고 출력
|
|
56
|
+
for (const result of results.values()) {
|
|
57
|
+
if (result.warnings != null && result.warnings !== "") {
|
|
58
|
+
const typeLabel = result.type === "lint" ? "lint" : result.target;
|
|
59
|
+
logger.warn(formatBuildMessages(result.name, typeLabel, [result.warnings]));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
32
62
|
}
|
|
33
63
|
|
|
34
64
|
/**
|
|
@@ -53,15 +83,15 @@ export function printServers(
|
|
|
53
83
|
const activeClients = clients.filter((c) => results.get(`${c}:build`)?.status !== "error");
|
|
54
84
|
if (activeClients.length > 0) {
|
|
55
85
|
for (const clientName of activeClients) {
|
|
56
|
-
|
|
86
|
+
logger.info(`[server] http://localhost:${server.port}/${clientName}/`);
|
|
57
87
|
}
|
|
58
88
|
} else {
|
|
59
89
|
// 연결된 클라이언트가 없으면 서버 루트 URL 출력
|
|
60
|
-
|
|
90
|
+
logger.info(`[server] http://localhost:${server.port}/`);
|
|
61
91
|
}
|
|
62
92
|
} else {
|
|
63
93
|
// 독립형 클라이언트: 이름 포함하여 출력
|
|
64
|
-
|
|
94
|
+
logger.info(`[server] http://localhost:${server.port}/${server.name}/`);
|
|
65
95
|
}
|
|
66
96
|
}
|
|
67
97
|
}
|
|
@@ -2,19 +2,22 @@ import path from "path";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import { createWorker, FsWatcher } from "@simplysm/core-node";
|
|
4
4
|
import { err as errNs } from "@simplysm/core-common";
|
|
5
|
-
import { setupWorkerLifecycle } from "./shared-worker-lifecycle
|
|
5
|
+
import { setupWorkerLifecycle } from "./shared-worker-lifecycle";
|
|
6
6
|
import {
|
|
7
7
|
createClientEsbuildContext,
|
|
8
8
|
type ClientEsbuildResult,
|
|
9
|
-
} from "../esbuild/esbuild-client-config
|
|
10
|
-
import { generateIndexHtml } from "../esbuild/esbuild-index-html
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import
|
|
9
|
+
} from "../esbuild/esbuild-client-config";
|
|
10
|
+
import { generateIndexHtml } from "../esbuild/esbuild-index-html";
|
|
11
|
+
import { formatEsbuildMessages } from "../utils/output-utils";
|
|
12
|
+
import { applyPwa, createPwaHtmlTransform } from "../esbuild/esbuild-pwa";
|
|
13
|
+
import { createDevHttpServer, type DevHttpServer } from "../dev-server/dev-http-server";
|
|
14
|
+
import { createHmrService, type HmrService } from "../dev-server/hmr-service";
|
|
15
|
+
import { createHmrPostTransform } from "../dev-server/hmr-client-script";
|
|
16
|
+
import { copyPublicFiles, watchPublicFiles } from "../utils/copy-public";
|
|
17
|
+
import type { SdBrowserSupportConfig, SdPwaConfig } from "../sd-config.types";
|
|
17
18
|
import type esbuild from "esbuild";
|
|
19
|
+
import type { PartialMessage } from "esbuild";
|
|
20
|
+
import { IncrementalMtimeTracker } from "./incremental-mtime-tracker";
|
|
18
21
|
|
|
19
22
|
//#region Types
|
|
20
23
|
|
|
@@ -63,6 +66,9 @@ let devServer: DevHttpServer | undefined;
|
|
|
63
66
|
let hmrService: HmrService | undefined;
|
|
64
67
|
let publicWatcher: FsWatcher | undefined;
|
|
65
68
|
let indexHtmlWatcher: FsWatcher | undefined;
|
|
69
|
+
let lastMetafile: esbuild.Metafile | undefined;
|
|
70
|
+
let isInitialBuild = true;
|
|
71
|
+
let initialBuildResolve: ((result: ClientBuildResult) => void) | undefined;
|
|
66
72
|
|
|
67
73
|
const { logger, guardStartWatch } = setupWorkerLifecycle("client", async () => {
|
|
68
74
|
await stopWatch();
|
|
@@ -98,7 +104,7 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
98
104
|
const outdir = info.outDir ?? path.join(info.pkgDir, "dist");
|
|
99
105
|
|
|
100
106
|
// 1. public/ 복사
|
|
101
|
-
await copyPublicFiles(info.pkgDir, false);
|
|
107
|
+
await copyPublicFiles(info.pkgDir, false, outdir);
|
|
102
108
|
|
|
103
109
|
// 2. polyfills 감지
|
|
104
110
|
const polyfillsPath = path.join(info.pkgDir, "src", "polyfills.ts");
|
|
@@ -160,7 +166,7 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
160
166
|
// SourceFileCache는 LMDB 기반. context.dispose()에 의해 정리됨.
|
|
161
167
|
|
|
162
168
|
// 8. .config.json 기록
|
|
163
|
-
writeConfigJson(
|
|
169
|
+
writeConfigJson(outdir, info.configs);
|
|
164
170
|
|
|
165
171
|
logger.debug(`[${info.name}] client worker build 완료`);
|
|
166
172
|
return {
|
|
@@ -171,17 +177,131 @@ async function build(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
171
177
|
} catch (err) {
|
|
172
178
|
const errors: string[] = [];
|
|
173
179
|
if (err != null && typeof err === "object" && "errors" in err) {
|
|
174
|
-
const buildErrors = (err as { errors:
|
|
175
|
-
errors.push(...buildErrors
|
|
180
|
+
const buildErrors = (err as { errors: PartialMessage[] }).errors;
|
|
181
|
+
errors.push(...formatEsbuildMessages(buildErrors, "error"));
|
|
176
182
|
}
|
|
177
183
|
if (errors.length === 0) {
|
|
178
184
|
errors.push(errNs.message(err));
|
|
179
185
|
}
|
|
180
|
-
logger.debug(`[${info.name}] client worker build 예외: ${errors.join("
|
|
186
|
+
logger.debug(`[${info.name}] client worker build 예외: ${errors.join("\n")}`);
|
|
181
187
|
return { success: false, errors };
|
|
182
188
|
}
|
|
183
189
|
}
|
|
184
190
|
|
|
191
|
+
/**
|
|
192
|
+
* sourceFileCache 무효화 + mtime 추적 플러그인 생성
|
|
193
|
+
*/
|
|
194
|
+
function createSourceFileCachePlugin(): esbuild.Plugin {
|
|
195
|
+
return {
|
|
196
|
+
name: "sd-build-start",
|
|
197
|
+
setup(pluginBuild: esbuild.PluginBuild) {
|
|
198
|
+
const mtimeTracker = new IncrementalMtimeTracker();
|
|
199
|
+
|
|
200
|
+
pluginBuild.onStart(() => {
|
|
201
|
+
// sourceFileCache 무효화: 변경된 파일의 loadResultCache + TypeScript 소스 캐시 모두 제거
|
|
202
|
+
if (esbuildResult != null) {
|
|
203
|
+
const { loadResultCache, typeScriptFileCache } =
|
|
204
|
+
esbuildResult.sourceFileCache;
|
|
205
|
+
// JS 파일 (loadResultCache) + TS 파일 (typeScriptFileCache) 모두 감시
|
|
206
|
+
const watchTargets = [
|
|
207
|
+
...loadResultCache.watchFiles,
|
|
208
|
+
...typeScriptFileCache.keys(),
|
|
209
|
+
];
|
|
210
|
+
const changedFiles = mtimeTracker.detectChanges(watchTargets);
|
|
211
|
+
if (changedFiles.size > 0) {
|
|
212
|
+
esbuildResult.sourceFileCache.invalidate(changedFiles);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (!isInitialBuild) {
|
|
217
|
+
sender.send("buildStart", {});
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
pluginBuild.onEnd(() => {
|
|
222
|
+
if (esbuildResult == null) return;
|
|
223
|
+
// JS 파일 (loadResultCache) + TS 파일 (typeScriptFileCache) 모두 기록
|
|
224
|
+
const watchTargets = [
|
|
225
|
+
...esbuildResult.sourceFileCache.loadResultCache.watchFiles,
|
|
226
|
+
...esbuildResult.sourceFileCache.typeScriptFileCache.keys(),
|
|
227
|
+
];
|
|
228
|
+
mtimeTracker.updateMtimes(watchTargets);
|
|
229
|
+
});
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* dev watch 빌드 완료 핸들러 생성 (index.html 재생성 + HMR + 이벤트 전송)
|
|
236
|
+
*/
|
|
237
|
+
function createDevBuildEndHandler(
|
|
238
|
+
basePath: string,
|
|
239
|
+
actualPort: number,
|
|
240
|
+
outdir: string,
|
|
241
|
+
entryNames: string[],
|
|
242
|
+
pkgDir: string,
|
|
243
|
+
): (result: esbuild.BuildResult) => Promise<void> {
|
|
244
|
+
return async (result: esbuild.BuildResult) => {
|
|
245
|
+
try {
|
|
246
|
+
// index.html 재생성 (lastMetafile 보관 — index.html 단독 변경 시 재생성용)
|
|
247
|
+
if (result.metafile != null) {
|
|
248
|
+
lastMetafile = result.metafile;
|
|
249
|
+
const hmrPostTransform = createHmrPostTransform(basePath, actualPort);
|
|
250
|
+
const indexPath = path.join(pkgDir, "src", "index.html");
|
|
251
|
+
const indexResult = await generateIndexHtml({
|
|
252
|
+
indexPath,
|
|
253
|
+
metafile: result.metafile,
|
|
254
|
+
outdir,
|
|
255
|
+
baseHref: basePath,
|
|
256
|
+
mode: "dev",
|
|
257
|
+
entryNames,
|
|
258
|
+
postTransform: hmrPostTransform,
|
|
259
|
+
});
|
|
260
|
+
fs.writeFileSync(path.join(outdir, "index.html"), indexResult.content);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// HMR 메시지 디스패치
|
|
264
|
+
if (hmrService != null && result.metafile != null && !isInitialBuild) {
|
|
265
|
+
hmrService.onBuildEnd(result.metafile);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// build 이벤트 전송
|
|
269
|
+
const success = result.errors.length === 0;
|
|
270
|
+
const errors = result.errors.length > 0
|
|
271
|
+
? formatEsbuildMessages(result.errors, "error")
|
|
272
|
+
: undefined;
|
|
273
|
+
const warnings = result.warnings.length > 0
|
|
274
|
+
? formatEsbuildMessages(result.warnings, "warning")
|
|
275
|
+
: undefined;
|
|
276
|
+
|
|
277
|
+
if (!isInitialBuild) {
|
|
278
|
+
sender.send("build", { success, errors, warnings });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// 초기 빌드 완료 시 resolve
|
|
282
|
+
if (isInitialBuild) {
|
|
283
|
+
isInitialBuild = false;
|
|
284
|
+
initialBuildResolve?.({ success, errors, warnings });
|
|
285
|
+
}
|
|
286
|
+
} catch (err) {
|
|
287
|
+
const message = errNs.message(err);
|
|
288
|
+
if (!isInitialBuild) {
|
|
289
|
+
sender.send("error", { message });
|
|
290
|
+
} else {
|
|
291
|
+
isInitialBuild = false;
|
|
292
|
+
initialBuildResolve?.({
|
|
293
|
+
success: false,
|
|
294
|
+
errors: [message],
|
|
295
|
+
warnings:
|
|
296
|
+
result.warnings.length > 0
|
|
297
|
+
? formatEsbuildMessages(result.warnings, "warning")
|
|
298
|
+
: undefined,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
185
305
|
/**
|
|
186
306
|
* dev watch 시작
|
|
187
307
|
*/
|
|
@@ -232,10 +352,6 @@ async function startWatch(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
232
352
|
});
|
|
233
353
|
|
|
234
354
|
// 7. esbuild context 생성
|
|
235
|
-
let lastMetafile: esbuild.Metafile | undefined;
|
|
236
|
-
let initialBuildResolve: ((result: ClientBuildResult) => void) | undefined;
|
|
237
|
-
let isInitialBuild = true;
|
|
238
|
-
|
|
239
355
|
esbuildResult = await createClientEsbuildContext({
|
|
240
356
|
pkgDir: info.pkgDir,
|
|
241
357
|
cwd: info.cwd,
|
|
@@ -247,114 +363,8 @@ async function startWatch(info: ClientBuildInfo): Promise<ClientBuildResult> {
|
|
|
247
363
|
legacyModule,
|
|
248
364
|
postcssPlugins,
|
|
249
365
|
templateUpdates: legacyModule ? undefined : templateUpdates,
|
|
250
|
-
plugins: [
|
|
251
|
-
|
|
252
|
-
name: "sd-build-start",
|
|
253
|
-
setup(pluginBuild: esbuild.PluginBuild) {
|
|
254
|
-
const prevMtimes = new Map<string, number>();
|
|
255
|
-
|
|
256
|
-
pluginBuild.onStart(() => {
|
|
257
|
-
// sourceFileCache 무효화: 변경된 파일의 loadResultCache + TypeScript 소스 캐시 모두 제거
|
|
258
|
-
if (esbuildResult != null) {
|
|
259
|
-
const { loadResultCache } = esbuildResult.sourceFileCache;
|
|
260
|
-
const changedFiles = new Set<string>();
|
|
261
|
-
for (const file of loadResultCache.watchFiles) {
|
|
262
|
-
try {
|
|
263
|
-
const mtime = fs.statSync(file).mtimeMs;
|
|
264
|
-
const prev = prevMtimes.get(file);
|
|
265
|
-
if (prev != null && prev !== mtime) {
|
|
266
|
-
changedFiles.add(file);
|
|
267
|
-
}
|
|
268
|
-
} catch {
|
|
269
|
-
if (prevMtimes.has(file)) {
|
|
270
|
-
changedFiles.add(file);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (changedFiles.size > 0) {
|
|
275
|
-
esbuildResult.sourceFileCache.invalidate(changedFiles);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (!isInitialBuild) {
|
|
280
|
-
sender.send("buildStart", {});
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
pluginBuild.onEnd(() => {
|
|
285
|
-
if (esbuildResult == null) return;
|
|
286
|
-
prevMtimes.clear();
|
|
287
|
-
for (const file of esbuildResult.sourceFileCache.loadResultCache.watchFiles) {
|
|
288
|
-
try {
|
|
289
|
-
prevMtimes.set(file, fs.statSync(file).mtimeMs);
|
|
290
|
-
} catch {
|
|
291
|
-
// 삭제된 파일
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
},
|
|
296
|
-
},
|
|
297
|
-
],
|
|
298
|
-
onEnd: async (result: esbuild.BuildResult) => {
|
|
299
|
-
try {
|
|
300
|
-
// index.html 재생성 (lastMetafile 보관 — index.html 단독 변경 시 재생성용)
|
|
301
|
-
if (result.metafile != null) {
|
|
302
|
-
lastMetafile = result.metafile;
|
|
303
|
-
const hmrPostTransform = createHmrPostTransform(basePath, actualPort);
|
|
304
|
-
const indexPath = path.join(info.pkgDir, "src", "index.html");
|
|
305
|
-
const indexResult = await generateIndexHtml({
|
|
306
|
-
indexPath,
|
|
307
|
-
metafile: result.metafile,
|
|
308
|
-
outdir,
|
|
309
|
-
baseHref: basePath,
|
|
310
|
-
mode: "dev",
|
|
311
|
-
entryNames,
|
|
312
|
-
postTransform: hmrPostTransform,
|
|
313
|
-
});
|
|
314
|
-
fs.writeFileSync(path.join(outdir, "index.html"), indexResult.content);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// HMR 메시지 디스패치
|
|
318
|
-
if (hmrService != null && result.metafile != null && !isInitialBuild) {
|
|
319
|
-
hmrService.onBuildEnd(result.metafile);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// build 이벤트 전송
|
|
323
|
-
const success = result.errors.length === 0;
|
|
324
|
-
if (!isInitialBuild) {
|
|
325
|
-
sender.send("build", {
|
|
326
|
-
success,
|
|
327
|
-
errors:
|
|
328
|
-
result.errors.length > 0
|
|
329
|
-
? result.errors.map((e) => e.text)
|
|
330
|
-
: undefined,
|
|
331
|
-
warnings:
|
|
332
|
-
result.warnings.length > 0
|
|
333
|
-
? result.warnings.map((w) => w.text)
|
|
334
|
-
: undefined,
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// 초기 빌드 완료 시 resolve
|
|
339
|
-
if (isInitialBuild) {
|
|
340
|
-
isInitialBuild = false;
|
|
341
|
-
initialBuildResolve?.({
|
|
342
|
-
success,
|
|
343
|
-
errors:
|
|
344
|
-
result.errors.length > 0
|
|
345
|
-
? result.errors.map((e) => e.text)
|
|
346
|
-
: undefined,
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
} catch (err) {
|
|
350
|
-
const message = errNs.message(err);
|
|
351
|
-
sender.send("error", { message });
|
|
352
|
-
if (isInitialBuild) {
|
|
353
|
-
isInitialBuild = false;
|
|
354
|
-
initialBuildResolve?.({ success: false, errors: [message] });
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
},
|
|
366
|
+
plugins: [createSourceFileCachePlugin()],
|
|
367
|
+
onEnd: createDevBuildEndHandler(basePath, actualPort, outdir, entryNames, info.pkgDir),
|
|
358
368
|
});
|
|
359
369
|
|
|
360
370
|
// 8. esbuild watch 시작 + 초기 빌드 대기
|
|
@@ -440,6 +450,11 @@ async function stopWatch(): Promise<void> {
|
|
|
440
450
|
indexHtmlWatcher = undefined;
|
|
441
451
|
}
|
|
442
452
|
|
|
453
|
+
// 6. 빌드 세션 상태 리셋
|
|
454
|
+
lastMetafile = undefined;
|
|
455
|
+
isInitialBuild = true;
|
|
456
|
+
initialBuildResolve = undefined;
|
|
457
|
+
|
|
443
458
|
logger.debug("esbuild watch 정리 완료");
|
|
444
459
|
}
|
|
445
460
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 증분 방식으로 파일 mtime을 추적하여 변경 파일을 감지한다.
|
|
5
|
+
*
|
|
6
|
+
* - `detectChanges`: watchTargets 전체를 stat하여 이전 mtime과 비교, 변경 파일 Set 반환
|
|
7
|
+
* - `updateMtimes`: 변경/신규 파일만 stat하여 prevMtimes를 증분 갱신
|
|
8
|
+
*/
|
|
9
|
+
export class IncrementalMtimeTracker {
|
|
10
|
+
private readonly _prevMtimes = new Map<string, number>();
|
|
11
|
+
private _lastChangedFiles = new Set<string>();
|
|
12
|
+
|
|
13
|
+
detectChanges(watchTargets: Iterable<string>): Set<string> {
|
|
14
|
+
const changedFiles = new Set<string>();
|
|
15
|
+
for (const file of watchTargets) {
|
|
16
|
+
try {
|
|
17
|
+
const mtime = fs.statSync(file).mtimeMs;
|
|
18
|
+
const prev = this._prevMtimes.get(file);
|
|
19
|
+
if (prev != null && prev !== mtime) {
|
|
20
|
+
changedFiles.add(file);
|
|
21
|
+
}
|
|
22
|
+
} catch {
|
|
23
|
+
if (this._prevMtimes.has(file)) {
|
|
24
|
+
changedFiles.add(file);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
this._lastChangedFiles = changedFiles;
|
|
29
|
+
return changedFiles;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
updateMtimes(currentWatchTargets: Iterable<string>): void {
|
|
33
|
+
const targetSet =
|
|
34
|
+
currentWatchTargets instanceof Set
|
|
35
|
+
? (currentWatchTargets as Set<string>)
|
|
36
|
+
: new Set(currentWatchTargets);
|
|
37
|
+
|
|
38
|
+
// 1) 삭제된 파일 정리: prevMtimes에 있지만 watchTargets에 없는 파일 제거
|
|
39
|
+
for (const file of this._prevMtimes.keys()) {
|
|
40
|
+
if (!targetSet.has(file)) {
|
|
41
|
+
this._prevMtimes.delete(file);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 2) 변경된 파일 mtime 재조회 (watchTargets에 있는 파일만)
|
|
46
|
+
for (const file of this._lastChangedFiles) {
|
|
47
|
+
if (!targetSet.has(file)) continue;
|
|
48
|
+
try {
|
|
49
|
+
this._prevMtimes.set(file, fs.statSync(file).mtimeMs);
|
|
50
|
+
} catch {
|
|
51
|
+
this._prevMtimes.delete(file);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 3) 신규 파일만 stat (prevMtimes에 없는 파일)
|
|
56
|
+
for (const file of targetSet) {
|
|
57
|
+
if (!this._prevMtimes.has(file)) {
|
|
58
|
+
try {
|
|
59
|
+
this._prevMtimes.set(file, fs.statSync(file).mtimeMs);
|
|
60
|
+
} catch {
|
|
61
|
+
// 삭제된 파일 — 무시
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this._lastChangedFiles = new Set();
|
|
67
|
+
}
|
|
68
|
+
}
|