@simplysm/sd-cli 14.0.47 → 14.0.49
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 +782 -0
- package/dist/angular/ngtsc-build-core.js +2 -2
- package/dist/angular/ngtsc-build-core.js.map +1 -1
- package/dist/angular/vite-angular-plugin.d.ts.map +1 -1
- package/dist/angular/vite-angular-plugin.js +3 -2
- package/dist/angular/vite-angular-plugin.js.map +1 -1
- package/dist/capacitor/capacitor-android.js +2 -2
- package/dist/capacitor/capacitor-android.js.map +1 -1
- package/dist/capacitor/capacitor-build.d.ts.map +1 -1
- package/dist/capacitor/capacitor-build.js +2 -1
- package/dist/capacitor/capacitor-build.js.map +1 -1
- package/dist/capacitor/capacitor-icon.d.ts.map +1 -1
- package/dist/capacitor/capacitor-icon.js +2 -1
- package/dist/capacitor/capacitor-icon.js.map +1 -1
- package/dist/capacitor/capacitor-npm-config.d.ts.map +1 -1
- package/dist/capacitor/capacitor-npm-config.js +2 -1
- package/dist/capacitor/capacitor-npm-config.js.map +1 -1
- package/dist/capacitor/capacitor.d.ts.map +1 -1
- package/dist/capacitor/capacitor.js +2 -1
- package/dist/capacitor/capacitor.js.map +1 -1
- package/dist/commands/device.js +2 -2
- package/dist/commands/device.js.map +1 -1
- package/dist/commands/replace-deps.js +2 -2
- package/dist/commands/replace-deps.js.map +1 -1
- package/dist/deps/replace-deps/collect-deps.js +2 -2
- package/dist/deps/replace-deps/collect-deps.js.map +1 -1
- package/dist/deps/replace-deps/replace-deps.d.ts.map +1 -1
- package/dist/deps/replace-deps/replace-deps.js +108 -81
- package/dist/deps/replace-deps/replace-deps.js.map +1 -1
- package/dist/deps/server-externals/server-production-files.js +2 -2
- package/dist/deps/server-externals/server-production-files.js.map +1 -1
- package/dist/electron/electron.d.ts.map +1 -1
- package/dist/electron/electron.js +2 -1
- package/dist/electron/electron.js.map +1 -1
- package/dist/engines/BaseEngine.d.ts.map +1 -1
- package/dist/engines/BaseEngine.js +2 -2
- package/dist/engines/BaseEngine.js.map +1 -1
- package/dist/engines/EsbuildClientEngine.d.ts.map +1 -1
- package/dist/engines/EsbuildClientEngine.js +2 -2
- package/dist/engines/EsbuildClientEngine.js.map +1 -1
- package/dist/engines/NgtscEngine.js +2 -2
- package/dist/engines/NgtscEngine.js.map +1 -1
- package/dist/engines/ServerEsbuildEngine.js +2 -2
- package/dist/engines/ServerEsbuildEngine.js.map +1 -1
- package/dist/engines/TscEngine.js +2 -2
- package/dist/engines/TscEngine.js.map +1 -1
- package/dist/engines/engine-factory.d.ts.map +1 -1
- package/dist/engines/engine-factory.js +2 -2
- package/dist/engines/engine-factory.js.map +1 -1
- package/dist/esbuild/esbuild-angular-compiler-plugin.d.ts.map +1 -1
- package/dist/esbuild/esbuild-angular-compiler-plugin.js +46 -18
- package/dist/esbuild/esbuild-angular-compiler-plugin.js.map +1 -1
- package/dist/esbuild/esbuild-config.js +2 -2
- package/dist/esbuild/esbuild-config.js.map +1 -1
- package/dist/lint/lint-with-program.js +2 -2
- package/dist/lint/lint-with-program.js.map +1 -1
- package/dist/runtime/lazy-logger.d.ts +14 -0
- package/dist/runtime/lazy-logger.d.ts.map +1 -0
- package/dist/runtime/lazy-logger.js +23 -0
- package/dist/runtime/lazy-logger.js.map +1 -0
- package/dist/sd-cli-entry.js +2 -2
- package/dist/sd-cli-entry.js.map +1 -1
- package/dist/sd-cli.js +2 -2
- package/dist/sd-cli.js.map +1 -1
- package/dist/ts-compiler/SdTsCompiler.d.ts +11 -0
- package/dist/ts-compiler/SdTsCompiler.d.ts.map +1 -1
- package/dist/ts-compiler/SdTsCompiler.js +223 -116
- package/dist/ts-compiler/SdTsCompiler.js.map +1 -1
- package/dist/typecheck/typecheck-non-package.js +2 -2
- package/dist/typecheck/typecheck-non-package.js.map +1 -1
- package/dist/typecheck/typecheck-serialization.d.ts +31 -9
- package/dist/typecheck/typecheck-serialization.d.ts.map +1 -1
- package/dist/typecheck/typecheck-serialization.js +62 -22
- package/dist/typecheck/typecheck-serialization.js.map +1 -1
- package/dist/utils/output-utils.js +2 -2
- package/dist/utils/output-utils.js.map +1 -1
- package/dist/utils/package-classify.js +2 -2
- package/dist/utils/package-classify.js.map +1 -1
- package/dist/utils/package-utils.js +2 -2
- package/dist/utils/package-utils.js.map +1 -1
- package/dist/utils/sd-config.js +2 -2
- package/dist/utils/sd-config.js.map +1 -1
- package/dist/utils/tsconfig.d.ts.map +1 -1
- package/dist/utils/tsconfig.js +3 -5
- package/dist/utils/tsconfig.js.map +1 -1
- package/package.json +5 -5
- package/src/angular/ngtsc-build-core.ts +3 -3
- package/src/angular/vite-angular-plugin.ts +3 -2
- package/src/capacitor/capacitor-android.ts +2 -2
- package/src/capacitor/capacitor-build.ts +2 -1
- package/src/capacitor/capacitor-icon.ts +2 -1
- package/src/capacitor/capacitor-npm-config.ts +2 -1
- package/src/capacitor/capacitor.ts +2 -1
- package/src/commands/device.ts +2 -2
- package/src/commands/replace-deps.ts +2 -2
- package/src/deps/replace-deps/collect-deps.ts +2 -2
- package/src/deps/replace-deps/replace-deps.ts +119 -85
- package/src/deps/server-externals/server-production-files.ts +2 -2
- package/src/electron/electron.ts +2 -1
- package/src/engines/BaseEngine.ts +2 -2
- package/src/engines/EsbuildClientEngine.ts +2 -2
- package/src/engines/NgtscEngine.ts +2 -2
- package/src/engines/ServerEsbuildEngine.ts +2 -2
- package/src/engines/TscEngine.ts +2 -2
- package/src/engines/engine-factory.ts +2 -2
- package/src/esbuild/esbuild-angular-compiler-plugin.ts +60 -19
- package/src/esbuild/esbuild-config.ts +2 -2
- package/src/lint/lint-with-program.ts +2 -2
- package/src/runtime/lazy-logger.ts +23 -0
- package/src/sd-cli-entry.ts +2 -2
- package/src/sd-cli.ts +2 -2
- package/src/ts-compiler/SdTsCompiler.ts +280 -138
- package/src/typecheck/typecheck-non-package.ts +2 -2
- package/src/typecheck/typecheck-serialization.ts +100 -26
- package/src/utils/output-utils.ts +2 -2
- package/src/utils/package-classify.ts +2 -2
- package/src/utils/package-utils.ts +2 -2
- package/src/utils/sd-config.ts +2 -2
- package/src/utils/tsconfig.ts +3 -4
- 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.verify.md +9 -9
- package/tests/esbuild/esbuild-postcss-plugin-chunking.verify.md +3 -3
- package/tests/esbuild/esbuild-tsc-plugin-imports.verify.md +9 -9
- package/tests/esbuild/esbuild-worker-plugin-node.verify.md +7 -7
- package/tests/esbuild/esbuild-worker-plugin.spec.ts +8 -0
- package/tests/esbuild/esbuild-worker-plugin.verify.md +3 -3
- 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/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-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/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.verify.md +16 -16
- package/tests/utils/esbuild-index-html.verify.md +6 -6
- package/tests/utils/esbuild-pwa.verify.md +5 -5
- package/tests/utils/esbuild-scss-plugin.verify.md +4 -4
- package/tests/utils/hmr-service.verify.md +10 -10
- package/tests/utils/lint-core-import-paths.verify.md +6 -6
- package/tests/utils/replace-deps-split.verify.md +11 -11
- package/tests/utils/replace-deps-watch.acc.spec.ts +85 -0
- package/tests/utils/replace-deps-watch.spec.ts +198 -1
- 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-esbuild-context-integration.verify.md +6 -6
- package/tests/workers/server-esbuild-context-tsc.verify.md +3 -3
- package/dist/sd-cli/tests/angular/fixtures/packages/basic-app/tests/test.fixture.d.ts +0 -3
- package/dist/sd-cli/tests/angular/fixtures/packages/basic-app/tests/test.fixture.d.ts.map +0 -1
- package/dist/sd-cli/tests/angular/fixtures/packages/basic-app/tests/test.fixture.js +0 -9
- package/dist/sd-cli/tests/angular/fixtures/packages/basic-app/tests/test.fixture.js.map +0 -1
|
@@ -50,14 +50,27 @@ async function copyWithUnlink(
|
|
|
50
50
|
if (stats.isDirectory()) {
|
|
51
51
|
await fsx.mkdir(targetPath);
|
|
52
52
|
const names = await fs.promises.readdir(sourcePath);
|
|
53
|
+
const allowedChildren = names
|
|
54
|
+
.map((name) => path.resolve(sourcePath, name))
|
|
55
|
+
.filter((child) => filter == null || filter(child));
|
|
56
|
+
const allowedBasenames = new Set(allowedChildren.map((c) => path.basename(c)));
|
|
57
|
+
|
|
58
|
+
// 고아 엔트리 정리: filter 범위 내이면서 소스에 없는 타겟 엔트리 삭제
|
|
59
|
+
const targetNames = await fs.promises.readdir(targetPath).catch(() => [] as string[]);
|
|
60
|
+
await Promise.all(
|
|
61
|
+
targetNames.map(async (name) => {
|
|
62
|
+
const targetChild = path.join(targetPath, name);
|
|
63
|
+
if (filter != null && !filter(targetChild)) return;
|
|
64
|
+
if (allowedBasenames.has(name)) return;
|
|
65
|
+
await fs.promises.rm(targetChild, { recursive: true, force: true });
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
|
|
53
69
|
await Promise.all(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
child,
|
|
59
|
-
path.join(targetPath, path.basename(child)),
|
|
60
|
-
)),
|
|
70
|
+
allowedChildren.map((child) => copyWithUnlink(
|
|
71
|
+
child,
|
|
72
|
+
path.join(targetPath, path.basename(child)),
|
|
73
|
+
)),
|
|
61
74
|
);
|
|
62
75
|
} else {
|
|
63
76
|
if (await isFileContentSame(sourcePath, targetPath)) return;
|
|
@@ -201,115 +214,136 @@ export async function watchReplaceDeps(
|
|
|
201
214
|
|
|
202
215
|
const entries = await resolveAllReplaceDepEntries(projectRoot, replaceDeps, logger);
|
|
203
216
|
|
|
204
|
-
// 소스 디렉토리 감시자 설정
|
|
205
|
-
const watchers: FsWatcher[] = [];
|
|
206
|
-
const watchedSources = new Set<string>();
|
|
207
|
-
|
|
208
217
|
logger.start(`replace-deps 워치 시작 중... (${entries.length}개 대상)`);
|
|
209
218
|
|
|
219
|
+
// resolvedSourcePath(posix) → entries 그룹화
|
|
220
|
+
// resolvedSourcePath는 replace-deps-resolve의 pathx.posixResolve 결과로 이미 POSIX이다.
|
|
221
|
+
const sourceMap = new Map<string, ReplaceDepEntry[]>();
|
|
210
222
|
for (const entry of entries) {
|
|
211
|
-
|
|
212
|
-
|
|
223
|
+
const key = entry.resolvedSourcePath;
|
|
224
|
+
const arr = sourceMap.get(key) ?? [];
|
|
225
|
+
arr.push(entry);
|
|
226
|
+
sourceMap.set(key, arr);
|
|
227
|
+
}
|
|
213
228
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
229
|
+
// 각 source의 watchPaths 수집 (files 필드 없는 source는 경고 후 제외). source 단위 병렬.
|
|
230
|
+
const allWatchPaths = new Set<string>();
|
|
231
|
+
await Promise.all(
|
|
232
|
+
[...sourceMap].map(async ([sourcePath, sourceEntries]) => {
|
|
233
|
+
try {
|
|
234
|
+
const files = await loadFilesField(sourcePath);
|
|
235
|
+
|
|
236
|
+
if (files == null) {
|
|
237
|
+
logger.warn(
|
|
238
|
+
`[${sourceEntries[0].targetName}] package.json에 files 필드가 없어 감시 건너뜀`,
|
|
239
|
+
);
|
|
240
|
+
sourceMap.delete(sourcePath);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
221
243
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
);
|
|
244
|
+
for (const f of files) {
|
|
245
|
+
allWatchPaths.add(pathx.posix(path.join(sourcePath, f)));
|
|
246
|
+
}
|
|
226
247
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
248
|
+
const rootEntries = await fs.promises
|
|
249
|
+
.readdir(sourcePath)
|
|
250
|
+
.catch(() => [] as string[]);
|
|
230
251
|
for (const name of rootEntries) {
|
|
231
252
|
if (NPM_DEFAULT_FILE_PATTERN.test(name)) {
|
|
232
|
-
|
|
253
|
+
allWatchPaths.add(pathx.posix(path.join(sourcePath, name)));
|
|
233
254
|
}
|
|
234
255
|
}
|
|
235
|
-
} catch {
|
|
236
|
-
|
|
256
|
+
} catch (err) {
|
|
257
|
+
logger.error(
|
|
258
|
+
`[${sourceEntries[0].targetName}] 감시 설정 실패: ${err instanceof Error ? err.message : err}`,
|
|
259
|
+
);
|
|
260
|
+
sourceMap.delete(sourcePath);
|
|
237
261
|
}
|
|
262
|
+
}),
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
if (allWatchPaths.size === 0) {
|
|
266
|
+
if (entries.length > 0) {
|
|
267
|
+
logger.warn("감시 대상이 없어 워치가 시작되지 않음");
|
|
268
|
+
} else {
|
|
269
|
+
logger.success("replace-deps 워치 준비 완료");
|
|
270
|
+
}
|
|
271
|
+
return { entries, dispose: () => {} };
|
|
272
|
+
}
|
|
238
273
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
274
|
+
// longest-prefix 매칭을 위해 긴 경로 우선 정렬
|
|
275
|
+
const sortedSources = [...sourceMap.keys()].sort((a, b) => b.length - a.length);
|
|
276
|
+
|
|
277
|
+
const findSource = (changedPath: string): string | undefined => {
|
|
278
|
+
for (const src of sortedSources) {
|
|
279
|
+
if (changedPath === src || changedPath.startsWith(src + "/")) return src;
|
|
280
|
+
}
|
|
281
|
+
return undefined;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const watcher = await FsWatcher.watch([...allWatchPaths], {
|
|
285
|
+
followSymlinks: false,
|
|
286
|
+
});
|
|
243
287
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
|
|
288
|
+
watcher.onChange({ delay: 300 }, async (changeInfos) => {
|
|
289
|
+
const flags = await Promise.all(
|
|
290
|
+
changeInfos.map(async ({ path: changedPath }) => {
|
|
291
|
+
const src = findSource(changedPath);
|
|
292
|
+
if (src == null) return false;
|
|
293
|
+
const sourceEntries = sourceMap.get(src)!;
|
|
249
294
|
|
|
250
|
-
|
|
251
|
-
// 사전 필터링된 항목만 순회
|
|
252
|
-
for (const e of sourceEntries) {
|
|
253
|
-
// 소스로부터의 상대 경로 계산
|
|
254
|
-
const relativePath = pathx.posix(path.relative(e.resolvedSourcePath, changedPath));
|
|
255
|
-
const destPath = pathx.posix(path.join(e.actualTargetPath, relativePath));
|
|
295
|
+
let localActualCopy = false;
|
|
256
296
|
|
|
297
|
+
// 동일 source의 복수 target 복사는 순차로 유지한다 (destination 중복 시 race 방지).
|
|
298
|
+
for (const e of sourceEntries) {
|
|
299
|
+
const relativePath = pathx.posix(path.relative(e.resolvedSourcePath, changedPath));
|
|
300
|
+
const destPath = pathx.posix(path.join(e.actualTargetPath, relativePath));
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
let sourceExists = false;
|
|
257
304
|
try {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
} catch {
|
|
264
|
-
// 소스가 삭제됨
|
|
265
|
-
}
|
|
305
|
+
await fs.promises.access(changedPath);
|
|
306
|
+
sourceExists = true;
|
|
307
|
+
} catch {
|
|
308
|
+
// 소스가 삭제됨
|
|
309
|
+
}
|
|
266
310
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
await fsx.mkdir(destPath);
|
|
272
|
-
} else {
|
|
273
|
-
// 파일 내용이 동일하면 복사 건너뜀 (불필요한 리빌드 방지)
|
|
274
|
-
if (await isFileContentSame(changedPath, destPath)) continue;
|
|
275
|
-
await fsx.mkdir(pathx.posix(path.dirname(destPath)));
|
|
276
|
-
await fsx.copy(changedPath, destPath);
|
|
277
|
-
hasActualCopy = true;
|
|
278
|
-
}
|
|
311
|
+
if (sourceExists) {
|
|
312
|
+
const stat = await fs.promises.stat(changedPath);
|
|
313
|
+
if (stat.isDirectory()) {
|
|
314
|
+
await fsx.mkdir(destPath);
|
|
279
315
|
} else {
|
|
280
|
-
|
|
281
|
-
await fsx.
|
|
282
|
-
|
|
316
|
+
if (await isFileContentSame(changedPath, destPath)) continue;
|
|
317
|
+
await fsx.mkdir(pathx.posix(path.dirname(destPath)));
|
|
318
|
+
await fsx.copy(changedPath, destPath);
|
|
319
|
+
localActualCopy = true;
|
|
283
320
|
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
);
|
|
321
|
+
} else {
|
|
322
|
+
await fsx.rm(destPath);
|
|
323
|
+
localActualCopy = true;
|
|
288
324
|
}
|
|
325
|
+
} catch (err) {
|
|
326
|
+
logger.error(
|
|
327
|
+
`[${e.targetName}] 복사 실패 (${relativePath}): ${err instanceof Error ? err.message : err}`,
|
|
328
|
+
);
|
|
289
329
|
}
|
|
290
330
|
}
|
|
291
331
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
});
|
|
332
|
+
return localActualCopy;
|
|
333
|
+
}),
|
|
334
|
+
);
|
|
296
335
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
logger.error(
|
|
300
|
-
`[${entry.targetName}] 감시 설정 실패: ${err instanceof Error ? err.message : err}`,
|
|
301
|
-
);
|
|
336
|
+
if (flags.some((f) => f)) {
|
|
337
|
+
options?.onChanged?.();
|
|
302
338
|
}
|
|
303
|
-
}
|
|
339
|
+
});
|
|
304
340
|
|
|
305
341
|
logger.success("replace-deps 워치 준비 완료");
|
|
306
342
|
|
|
307
343
|
return {
|
|
308
344
|
entries,
|
|
309
345
|
dispose: () => {
|
|
310
|
-
|
|
311
|
-
void watcher.close();
|
|
312
|
-
}
|
|
346
|
+
void watcher.close();
|
|
313
347
|
},
|
|
314
348
|
};
|
|
315
349
|
}
|
|
@@ -4,10 +4,10 @@ import fs from "fs";
|
|
|
4
4
|
import YAML from "yaml";
|
|
5
5
|
import TOML from "smol-toml";
|
|
6
6
|
import { cpx } from "@simplysm/core-node";
|
|
7
|
-
import {
|
|
7
|
+
import { createLazyLogger } from "../../runtime/lazy-logger";
|
|
8
8
|
import { collectAllDependencyExternals } from "../../esbuild/esbuild-config";
|
|
9
9
|
|
|
10
|
-
const logger =
|
|
10
|
+
const logger = createLazyLogger("sd:cli:server-production-files");
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* 외부 모듈을 두 용도로 분리하여 수집한다.
|
package/src/electron/electron.ts
CHANGED
|
@@ -3,11 +3,12 @@ import fs from "fs";
|
|
|
3
3
|
import module from "module";
|
|
4
4
|
import { cpx, fsx, pathx } from "@simplysm/core-node";
|
|
5
5
|
import { consola, LogLevels } from "consola";
|
|
6
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
6
7
|
import type { NpmConfig, SdElectronConfig } from "../sd-config.types.js";
|
|
7
8
|
import { createEnvBanner } from "../esbuild/esbuild-config.js";
|
|
8
9
|
|
|
9
10
|
export class Electron {
|
|
10
|
-
private static readonly _logger =
|
|
11
|
+
private static readonly _logger = createLazyLogger("sd:cli:electron");
|
|
11
12
|
|
|
12
13
|
private readonly _electronPath: string;
|
|
13
14
|
private readonly _srcPath: string;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Worker, type WorkerProxy } from "@simplysm/core-node";
|
|
2
2
|
import { err as errNs } from "@simplysm/core-common";
|
|
3
|
-
import { consola } from "consola";
|
|
4
3
|
import type { BuildResult, ResultCollector } from "../runtime/ResultCollector";
|
|
5
4
|
import { stopEngineWorker } from "../runtime/engine-stop";
|
|
6
5
|
import { setupWatchEvents } from "../runtime/engine-watch-events";
|
|
6
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
7
7
|
import type { LintWithProgramResult } from "../lint/lint-with-program";
|
|
8
8
|
import type { RebuildManager } from "../runtime/rebuild-manager";
|
|
9
9
|
import type { SerializedDiagnostic } from "../typecheck/typecheck-serialization";
|
|
10
10
|
import type { BuildEngine, BuildOutput, EngineResult, PackageInfo } from "./types";
|
|
11
11
|
|
|
12
|
-
const logger =
|
|
12
|
+
const logger = createLazyLogger("sd:cli:engine");
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* 모든 빌드 워커가 공유하는 공통 빌드 워커 이벤트
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { Worker, type WorkerProxy } from "@simplysm/core-node";
|
|
4
|
-
import { consola } from "consola";
|
|
5
4
|
import type * as ClientWorkerModule from "../workers/client.worker";
|
|
6
5
|
import type { ResultCollector } from "../runtime/ResultCollector";
|
|
7
6
|
import { stopEngineWorker } from "../runtime/engine-stop";
|
|
8
7
|
import { setupWatchEvents, type NormalizedBuildInfo } from "../runtime/engine-watch-events";
|
|
8
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
9
9
|
import type { RebuildManager } from "../runtime/rebuild-manager";
|
|
10
10
|
import type { BuildEngine, BuildOutput, ClientPackageInfo, EngineResult } from "./types";
|
|
11
11
|
|
|
12
|
-
const logger =
|
|
12
|
+
const logger = createLazyLogger("sd:cli:engine:esbuild-client");
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* EsbuildClientEngine 옵션
|
|
@@ -3,9 +3,9 @@ import type { ResultCollector } from "../runtime/ResultCollector";
|
|
|
3
3
|
import type { RebuildManager } from "../runtime/rebuild-manager";
|
|
4
4
|
import type { BuildOutput, BuildPackageInfo, EngineResult } from "./types";
|
|
5
5
|
import { BaseEngine, type CommonBuildWorkerModule } from "./BaseEngine";
|
|
6
|
-
import {
|
|
6
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
7
7
|
|
|
8
|
-
const logger =
|
|
8
|
+
const logger = createLazyLogger("sd:cli:engine:ngtsc");
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* NgtscEngine 옵션
|
|
@@ -3,9 +3,9 @@ import type { ResultCollector } from "../runtime/ResultCollector";
|
|
|
3
3
|
import type { RebuildManager } from "../runtime/rebuild-manager";
|
|
4
4
|
import type { BuildOutput, EngineResult, ServerPackageInfo } from "./types";
|
|
5
5
|
import { BaseEngine, type CommonBuildWorkerModule } from "./BaseEngine";
|
|
6
|
-
import {
|
|
6
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
7
7
|
|
|
8
|
-
const logger =
|
|
8
|
+
const logger = createLazyLogger("sd:cli:engine:server");
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* ServerEsbuildEngine 옵션
|
package/src/engines/TscEngine.ts
CHANGED
|
@@ -3,9 +3,9 @@ import type { ResultCollector } from "../runtime/ResultCollector";
|
|
|
3
3
|
import type { RebuildManager } from "../runtime/rebuild-manager";
|
|
4
4
|
import type { BuildOutput, BuildPackageInfo, EngineResult } from "./types";
|
|
5
5
|
import { BaseEngine, type CommonBuildWorkerModule } from "./BaseEngine";
|
|
6
|
-
import {
|
|
6
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
7
7
|
|
|
8
|
-
const logger =
|
|
8
|
+
const logger = createLazyLogger("sd:cli:engine:tsc");
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* TscEngine 옵션
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { consola } from "consola";
|
|
2
1
|
import type { ResultCollector } from "../runtime/ResultCollector";
|
|
2
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
3
3
|
import type { RebuildManager } from "../runtime/rebuild-manager";
|
|
4
4
|
import { hasAngularCoreDependency } from "../utils/package-utils";
|
|
5
5
|
import { NgtscEngine } from "./NgtscEngine";
|
|
@@ -8,7 +8,7 @@ import { TscEngine } from "./TscEngine";
|
|
|
8
8
|
import { EsbuildClientEngine } from "./EsbuildClientEngine";
|
|
9
9
|
import type { BuildEngine, BuildPackageInfo, ClientPackageInfo, ServerPackageInfo } from "./types";
|
|
10
10
|
|
|
11
|
-
const logger =
|
|
11
|
+
const logger = createLazyLogger("sd:cli:engine");
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -3,10 +3,13 @@ import fs from "fs";
|
|
|
3
3
|
import os from "os";
|
|
4
4
|
import ts from "typescript";
|
|
5
5
|
import type esbuild from "esbuild";
|
|
6
|
-
import { consola } from "consola";
|
|
7
6
|
import { JavaScriptTransformer, Cache as AngularCache } from "@angular/build/private";
|
|
7
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
8
8
|
import type { AngularSourceFileCache } from "../angular/angular-compiler";
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
SerializedDiagnostic,
|
|
11
|
+
SerializedMessageChain,
|
|
12
|
+
} from "../typecheck/typecheck-serialization";
|
|
10
13
|
import { SdTsCompiler } from "../ts-compiler/SdTsCompiler";
|
|
11
14
|
import type { ISdTsCompilerResult } from "../ts-compiler/sd-ts-compiler-result";
|
|
12
15
|
import { FileReferenceTracker } from "./file-reference-tracker";
|
|
@@ -15,7 +18,7 @@ import { createCachedLoad, type LoadResultCache } from "./load-result-cache";
|
|
|
15
18
|
import { collectHmrCandidates, HMR_MODIFIED_FILE_LIMIT } from "../angular/hmr-candidates";
|
|
16
19
|
import { transformWorkerPatterns } from "./esbuild-worker-plugin";
|
|
17
20
|
|
|
18
|
-
const logger =
|
|
21
|
+
const logger = createLazyLogger("sd:cli:angular-plugin");
|
|
19
22
|
|
|
20
23
|
//#region Types
|
|
21
24
|
|
|
@@ -125,29 +128,67 @@ export function convertDiagnostic(
|
|
|
125
128
|
return { text, location };
|
|
126
129
|
}
|
|
127
130
|
|
|
131
|
+
function flattenSerializedMessage(
|
|
132
|
+
messageText: string | SerializedMessageChain,
|
|
133
|
+
indent = 0,
|
|
134
|
+
): string {
|
|
135
|
+
if (typeof messageText === "string") return messageText;
|
|
136
|
+
const prefix = " ".repeat(indent);
|
|
137
|
+
let text = prefix + messageText.messageText;
|
|
138
|
+
if (messageText.next != null) {
|
|
139
|
+
for (const n of messageText.next) {
|
|
140
|
+
text += "\n" + flattenSerializedMessage(n, indent + 1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return text;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function locationOf(
|
|
147
|
+
fileInfo: { fileName: string } | undefined,
|
|
148
|
+
start: number | undefined,
|
|
149
|
+
length: number | undefined,
|
|
150
|
+
program: ts.Program,
|
|
151
|
+
cwd: string,
|
|
152
|
+
): esbuild.PartialMessage["location"] {
|
|
153
|
+
if (fileInfo == null || start == null) return null;
|
|
154
|
+
const sf = program.getSourceFile(fileInfo.fileName);
|
|
155
|
+
if (sf == null) return null;
|
|
156
|
+
const pos = sf.getLineAndCharacterOfPosition(start);
|
|
157
|
+
const lineStart = sf.getLineStarts()[pos.line];
|
|
158
|
+
const lineEnd = sf.getLineStarts()[pos.line + 1] ?? sf.text.length;
|
|
159
|
+
const lineText = sf.text.slice(lineStart, lineEnd).replace(/\r?\n$/, "");
|
|
160
|
+
return {
|
|
161
|
+
file: path.relative(cwd, fileInfo.fileName),
|
|
162
|
+
line: pos.line + 1,
|
|
163
|
+
column: pos.character,
|
|
164
|
+
lineText,
|
|
165
|
+
length: length ?? 0,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
128
169
|
export function convertSerializedDiagnosticToEsbuild(
|
|
129
170
|
d: SerializedDiagnostic,
|
|
130
171
|
program: ts.Program,
|
|
131
172
|
cwd: string,
|
|
132
173
|
): esbuild.PartialMessage {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
line: pos.line + 1,
|
|
144
|
-
column: pos.character,
|
|
145
|
-
lineText,
|
|
146
|
-
length: d.length ?? 0,
|
|
147
|
-
};
|
|
174
|
+
const location = locationOf(d.file, d.start, d.length, program, cwd);
|
|
175
|
+
const text = flattenSerializedMessage(d.messageText);
|
|
176
|
+
|
|
177
|
+
const notes: esbuild.PartialNote[] = [];
|
|
178
|
+
if (d.relatedInformation != null) {
|
|
179
|
+
for (const ri of d.relatedInformation) {
|
|
180
|
+
notes.push({
|
|
181
|
+
text: flattenSerializedMessage(ri.messageText),
|
|
182
|
+
location: locationOf(ri.file, ri.start, ri.length, program, cwd),
|
|
183
|
+
});
|
|
148
184
|
}
|
|
149
185
|
}
|
|
150
|
-
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
text,
|
|
189
|
+
location,
|
|
190
|
+
notes: notes.length > 0 ? notes : undefined,
|
|
191
|
+
};
|
|
151
192
|
}
|
|
152
193
|
|
|
153
194
|
//#endregion
|
|
@@ -3,10 +3,10 @@ import { readFileSync, existsSync } from "fs";
|
|
|
3
3
|
import fs from "fs/promises";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import type esbuild from "esbuild";
|
|
6
|
-
import {
|
|
6
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
7
7
|
import { addJsExtensionToImports } from "../utils/output-path-rewriter";
|
|
8
8
|
|
|
9
|
-
const logger =
|
|
9
|
+
const logger = createLazyLogger("sd:cli:esbuild-config");
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* esbuild outputFiles에서 변경된 파일만 디스크에 쓴다.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type ts from "typescript";
|
|
2
2
|
import { ESLint } from "eslint";
|
|
3
3
|
import { pathx } from "@simplysm/core-node";
|
|
4
|
-
import {
|
|
4
|
+
import { createLazyLogger } from "../runtime/lazy-logger";
|
|
5
5
|
|
|
6
|
-
const logger =
|
|
6
|
+
const logger = createLazyLogger("sd:cli:lint-with-program");
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* LintWithProgramRunner.lint()가 반환하는 lint 결과
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { consola, type ConsolaInstance } from "consola";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 모듈 레벨에서 선언해도 안전한 lazy logger 프록시.
|
|
5
|
+
*
|
|
6
|
+
* consola.withTag()는 호출 시점의 consola.options(level/reporters)를
|
|
7
|
+
* 스냅샷 복사한 새 인스턴스를 반환한다. 모듈 import 시점에 호출하면
|
|
8
|
+
* setupConsola 이전의 기본 level(info) 상태가 고정되어 이후 setupConsola가
|
|
9
|
+
* level을 debug로 올려도 반영되지 않는다.
|
|
10
|
+
*
|
|
11
|
+
* createLazyLogger는 실제 ConsolaInstance 생성을 첫 접근 시점까지 미뤄
|
|
12
|
+
* setupConsola 이후의 설정이 반영된 스냅샷을 갖도록 한다.
|
|
13
|
+
*/
|
|
14
|
+
export function createLazyLogger(tag: string): ConsolaInstance {
|
|
15
|
+
let cached: ConsolaInstance | undefined;
|
|
16
|
+
return new Proxy({} as ConsolaInstance, {
|
|
17
|
+
get(_target, prop) {
|
|
18
|
+
cached ??= consola.withTag(tag);
|
|
19
|
+
const value: unknown = Reflect.get(cached, prop);
|
|
20
|
+
return typeof value === "function" ? value.bind(cached) : value;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
package/src/sd-cli-entry.ts
CHANGED
|
@@ -15,10 +15,10 @@ import path from "path";
|
|
|
15
15
|
import fs from "fs";
|
|
16
16
|
import { fileURLToPath } from "url";
|
|
17
17
|
import { EventEmitter } from "node:events";
|
|
18
|
-
import { consola } from "consola";
|
|
19
18
|
import { setupConsola } from "@simplysm/core-node";
|
|
19
|
+
import { createLazyLogger } from "./runtime/lazy-logger";
|
|
20
20
|
|
|
21
|
-
const logger =
|
|
21
|
+
const logger = createLazyLogger("sd:cli:entry");
|
|
22
22
|
|
|
23
23
|
Error.stackTraceLimit = Infinity;
|
|
24
24
|
EventEmitter.defaultMaxListeners = 100;
|
package/src/sd-cli.ts
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { cpx, setupConsola } from "@simplysm/core-node";
|
|
11
|
-
import { consola } from "consola";
|
|
12
11
|
import os from "os";
|
|
13
12
|
import path from "path";
|
|
14
13
|
import { fileURLToPath } from "url";
|
|
14
|
+
import { createLazyLogger } from "./runtime/lazy-logger";
|
|
15
15
|
|
|
16
16
|
const __filename = fileURLToPath(import.meta.url);
|
|
17
17
|
const __dirname = path.dirname(__filename);
|
|
18
18
|
const isDev = path.extname(__filename) === ".ts";
|
|
19
|
-
const logger =
|
|
19
|
+
const logger = createLazyLogger("sd:cli");
|
|
20
20
|
|
|
21
21
|
if (isDev) {
|
|
22
22
|
// 개발 모드 (.ts): affinity 적용 후 직접 실행
|