@simplysm/sd-cli 12.15.39 → 12.15.41
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/entry/SdCliCordova.d.ts +33 -1
- package/dist/entry/SdCliCordova.js +84 -88
- package/dist/entry/SdCliElectron.d.ts +5 -1
- package/dist/entry/SdCliElectron.js +21 -21
- package/dist/entry/SdCliLocalUpdate.d.ts +1 -1
- package/dist/entry/SdCliLocalUpdate.js +3 -3
- package/dist/entry/SdCliProject.d.ts +4 -1
- package/dist/entry/SdCliProject.js +11 -11
- package/dist/pkg-builders/SdProjectBuildRunner.d.ts +6 -1
- package/dist/pkg-builders/SdProjectBuildRunner.js +27 -27
- package/dist/pkg-builders/client/SdClientBuildRunner.d.ts +2 -1
- package/dist/pkg-builders/client/SdClientBuildRunner.js +8 -10
- package/dist/pkg-builders/client/SdNgBundler.d.ts +22 -1
- package/dist/pkg-builders/client/SdNgBundler.js +70 -80
- package/dist/pkg-builders/client/SdNgBundlerContext.d.ts +3 -1
- package/dist/pkg-builders/client/SdNgBundlerContext.js +9 -10
- package/dist/pkg-builders/lib/SdCliIndexFileGenerator.d.ts +2 -1
- package/dist/pkg-builders/lib/SdCliIndexFileGenerator.js +5 -5
- package/dist/pkg-builders/lib/SdJsLibBuildRunner.d.ts +1 -1
- package/dist/pkg-builders/lib/SdJsLibBuildRunner.js +2 -2
- package/dist/pkg-builders/lib/SdTsLibBuildRunner.d.ts +1 -1
- package/dist/pkg-builders/lib/SdTsLibBuildRunner.js +2 -3
- package/dist/pkg-builders/lib/SdTsLibBuilder.d.ts +2 -1
- package/dist/pkg-builders/lib/SdTsLibBuilder.js +7 -8
- package/dist/pkg-builders/server/SdServerBuildRunner.d.ts +3 -1
- package/dist/pkg-builders/server/SdServerBuildRunner.js +6 -7
- package/dist/pkg-builders/server/SdServerBundler.d.ts +6 -1
- package/dist/pkg-builders/server/SdServerBundler.js +21 -23
- package/dist/ts-compiler/ScopePathSet.d.ts +1 -1
- package/dist/ts-compiler/ScopePathSet.js +3 -4
- package/dist/ts-compiler/SdDepCache.d.ts +45 -1
- package/dist/ts-compiler/SdDepCache.js +71 -69
- package/dist/ts-compiler/SdStyleBundler.d.ts +5 -1
- package/dist/ts-compiler/SdStyleBundler.js +25 -26
- package/dist/ts-compiler/SdTsCompiler.d.ts +20 -1
- package/dist/ts-compiler/SdTsCompiler.js +122 -129
- package/dist/utils/SdCliPerformanceTimer.d.ts +2 -1
- package/dist/utils/SdCliPerformanceTimer.js +9 -9
- package/package.json +8 -8
- package/src/entry/SdCliCordova.ts +89 -89
- package/src/entry/SdCliElectron.ts +21 -21
- package/src/entry/SdCliLocalUpdate.ts +3 -3
- package/src/entry/SdCliProject.ts +11 -11
- package/src/pkg-builders/SdProjectBuildRunner.ts +27 -27
- package/src/pkg-builders/client/SdClientBuildRunner.ts +10 -10
- package/src/pkg-builders/client/SdNgBundler.ts +78 -78
- package/src/pkg-builders/client/SdNgBundlerContext.ts +10 -10
- package/src/pkg-builders/lib/SdCliIndexFileGenerator.ts +5 -5
- package/src/pkg-builders/lib/SdJsLibBuildRunner.ts +2 -2
- package/src/pkg-builders/lib/SdTsLibBuildRunner.ts +3 -3
- package/src/pkg-builders/lib/SdTsLibBuilder.ts +8 -8
- package/src/pkg-builders/server/SdServerBuildRunner.ts +7 -7
- package/src/pkg-builders/server/SdServerBundler.ts +23 -23
- package/src/ts-compiler/ScopePathSet.ts +4 -4
- package/src/ts-compiler/SdDepCache.ts +47 -47
- package/src/ts-compiler/SdStyleBundler.ts +26 -26
- package/src/ts-compiler/SdTsCompiler.ts +130 -130
- package/src/utils/SdCliPerformanceTimer.ts +9 -9
|
@@ -13,41 +13,34 @@ import { FlatESLint } from "eslint/use-at-your-own-risk";
|
|
|
13
13
|
import { SdStyleBundler } from "./SdStyleBundler";
|
|
14
14
|
import { ScopePathSet } from "./ScopePathSet";
|
|
15
15
|
export class SdTsCompiler {
|
|
16
|
-
#logger = SdLogger.get(["simplysm", "sd-cli", "SdTsCompiler"]);
|
|
17
|
-
#isForAngular;
|
|
18
|
-
#scopePathSet;
|
|
19
|
-
#styleBundler;
|
|
20
|
-
#moduleResolutionCache;
|
|
21
|
-
#ngProgram;
|
|
22
|
-
#program;
|
|
23
|
-
// 빌드정보 캐싱
|
|
24
|
-
#cache = {
|
|
25
|
-
dep: new SdDepCache(),
|
|
26
|
-
type: new WeakMap(),
|
|
27
|
-
prop: new WeakMap(),
|
|
28
|
-
declFiles: new WeakMap(),
|
|
29
|
-
ngOrg: new Map(),
|
|
30
|
-
};
|
|
31
|
-
#sourceFileCacheMap = new Map();
|
|
32
|
-
#emittedFilesCacheMap = new Map();
|
|
33
|
-
#perf;
|
|
34
16
|
constructor(_opt, _forBundle) {
|
|
35
17
|
this._opt = _opt;
|
|
36
18
|
this._forBundle = _forBundle;
|
|
37
|
-
this
|
|
19
|
+
this._logger = SdLogger.get(["simplysm", "sd-cli", "SdTsCompiler"]);
|
|
20
|
+
// 빌드정보 캐싱
|
|
21
|
+
this._cache = {
|
|
22
|
+
dep: new SdDepCache(),
|
|
23
|
+
type: new WeakMap(),
|
|
24
|
+
prop: new WeakMap(),
|
|
25
|
+
declFiles: new WeakMap(),
|
|
26
|
+
ngOrg: new Map(),
|
|
27
|
+
};
|
|
28
|
+
this._sourceFileCacheMap = new Map();
|
|
29
|
+
this._emittedFilesCacheMap = new Map();
|
|
30
|
+
this._debug("초기화 중...");
|
|
38
31
|
const tsconfigPath = path.resolve(this._opt.pkgPath, "tsconfig.json");
|
|
39
32
|
const tsconfig = FsUtils.readJson(tsconfigPath);
|
|
40
|
-
this
|
|
41
|
-
this
|
|
33
|
+
this._isForAngular = Boolean(tsconfig.angularCompilerOptions);
|
|
34
|
+
this._scopePathSet = new ScopePathSet(this._opt.scopePathSet);
|
|
42
35
|
if (!this._opt.watch?.noEmit) {
|
|
43
|
-
this
|
|
36
|
+
this._styleBundler = new SdStyleBundler({
|
|
44
37
|
pkgPath: this._opt.pkgPath,
|
|
45
|
-
scopePathSet: this
|
|
38
|
+
scopePathSet: this._scopePathSet,
|
|
46
39
|
dev: !!this._opt.watch?.dev,
|
|
47
40
|
});
|
|
48
41
|
}
|
|
49
42
|
}
|
|
50
|
-
|
|
43
|
+
_parseTsConfig() {
|
|
51
44
|
const tsconfigPath = path.resolve(this._opt.pkgPath, "tsconfig.json");
|
|
52
45
|
const tsconfig = FsUtils.readJson(tsconfigPath);
|
|
53
46
|
const parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._opt.pkgPath, {
|
|
@@ -76,7 +69,7 @@ export class SdTsCompiler {
|
|
|
76
69
|
distPath: distPath,
|
|
77
70
|
};
|
|
78
71
|
}
|
|
79
|
-
|
|
72
|
+
_createCompilerHost(compilerOptions, modifiedFileSet) {
|
|
80
73
|
// 지식: SourceFile은 하나의 파일에만 국한된 정적 정보객체임, 변경된 파일의 SourceFile만 다시 생성하면됨
|
|
81
74
|
const compilerHost = ts.createCompilerHost(compilerOptions);
|
|
82
75
|
const baseGetSourceFile = compilerHost.getSourceFile;
|
|
@@ -85,18 +78,18 @@ export class SdTsCompiler {
|
|
|
85
78
|
/*if (!shouldCreateNewSourceFile && this.#sourceFileCacheMap.has(fileNPath)) {
|
|
86
79
|
return this.#sourceFileCacheMap.get(fileNPath);
|
|
87
80
|
}*/
|
|
88
|
-
if (this
|
|
89
|
-
return this
|
|
81
|
+
if (this._sourceFileCacheMap.has(fileNPath)) {
|
|
82
|
+
return this._sourceFileCacheMap.get(fileNPath);
|
|
90
83
|
}
|
|
91
84
|
const sf = baseGetSourceFile.call(compilerHost, fileName, languageVersionOrOptions, onError, false, ...args);
|
|
92
85
|
if (!sf) {
|
|
93
|
-
this
|
|
86
|
+
this._sourceFileCacheMap.delete(fileNPath);
|
|
94
87
|
return undefined;
|
|
95
88
|
}
|
|
96
|
-
this
|
|
89
|
+
this._sourceFileCacheMap.set(fileNPath, sf);
|
|
97
90
|
return sf;
|
|
98
91
|
};
|
|
99
|
-
if (this
|
|
92
|
+
if (this._isForAngular) {
|
|
100
93
|
compilerHost.readResource = (fileName) => {
|
|
101
94
|
return compilerHost.readFile(fileName) ?? "";
|
|
102
95
|
};
|
|
@@ -105,7 +98,7 @@ export class SdTsCompiler {
|
|
|
105
98
|
if (context.type !== "style") {
|
|
106
99
|
return null;
|
|
107
100
|
}
|
|
108
|
-
const styleBundleResult = await this
|
|
101
|
+
const styleBundleResult = await this._styleBundler.bundleAsync(data, PathUtils.norm(context.containingFile), context.resourceFile != null ? PathUtils.norm(context.resourceFile) : undefined);
|
|
109
102
|
return StringUtils.isNullOrEmpty(styleBundleResult.contents)
|
|
110
103
|
? null
|
|
111
104
|
: { content: styleBundleResult.contents };
|
|
@@ -115,17 +108,17 @@ export class SdTsCompiler {
|
|
|
115
108
|
return new Set(Array.from(modifiedFileSet).map((item) => PathUtils.posix(item)));
|
|
116
109
|
};
|
|
117
110
|
}
|
|
118
|
-
this
|
|
119
|
-
compilerHost.getModuleResolutionCache = () => this
|
|
111
|
+
this._moduleResolutionCache = ts.createModuleResolutionCache(compilerHost.getCurrentDirectory(), compilerHost.getCanonicalFileName.bind(compilerHost), compilerOptions, this._moduleResolutionCache?.getPackageJsonInfoCache());
|
|
112
|
+
compilerHost.getModuleResolutionCache = () => this._moduleResolutionCache;
|
|
120
113
|
return compilerHost;
|
|
121
114
|
}
|
|
122
115
|
async compileAsync(modifiedFileSet) {
|
|
123
|
-
this
|
|
124
|
-
const prepareResult = await this
|
|
116
|
+
this._perf = new SdCliPerformanceTimer("esbuild compile");
|
|
117
|
+
const prepareResult = await this._prepareAsync(modifiedFileSet);
|
|
125
118
|
const [globalStyleSheet, lintResults, buildResult] = await Promise.all([
|
|
126
|
-
this._opt.watch?.noEmit ? Promise.resolve(undefined) : this
|
|
127
|
-
this._opt.watch?.emitOnly ? Promise.resolve([]) : this
|
|
128
|
-
Promise.resolve(this
|
|
119
|
+
this._opt.watch?.noEmit ? Promise.resolve(undefined) : this._buildGlobalStyleAsync(),
|
|
120
|
+
this._opt.watch?.emitOnly ? Promise.resolve([]) : this._lintAsync(prepareResult),
|
|
121
|
+
Promise.resolve(this._build(prepareResult)),
|
|
129
122
|
]);
|
|
130
123
|
const messages = [
|
|
131
124
|
...SdCliConvertMessageUtils.convertToBuildMessagesFromTsDiag(buildResult.diagnostics),
|
|
@@ -133,101 +126,101 @@ export class SdTsCompiler {
|
|
|
133
126
|
];
|
|
134
127
|
const affectedFileSet = new Set([
|
|
135
128
|
...prepareResult.affectedFileSet,
|
|
136
|
-
...(this
|
|
129
|
+
...(this._styleBundler?.getAffectedFileSet(modifiedFileSet) ?? []),
|
|
137
130
|
]);
|
|
138
131
|
const watchFileSet = new Set([
|
|
139
132
|
...prepareResult.watchFileSet,
|
|
140
|
-
...(this
|
|
133
|
+
...(this._styleBundler?.getAllStyleFileSet() ?? []),
|
|
141
134
|
]);
|
|
142
|
-
this
|
|
143
|
-
this
|
|
144
|
-
this
|
|
135
|
+
this._debug(`빌드 완료됨`, this._perf.toString());
|
|
136
|
+
this._debug(`영향 받은 파일: ${affectedFileSet.size}개`, ...(modifiedFileSet.size > 0 ? [affectedFileSet] : []));
|
|
137
|
+
this._debug(`감시 중인 파일: ${watchFileSet.size}개`);
|
|
145
138
|
return {
|
|
146
139
|
messages: messages,
|
|
147
140
|
affectedFileSet: affectedFileSet,
|
|
148
141
|
watchFileSet: watchFileSet,
|
|
149
|
-
stylesheetBundlingResultMap: this
|
|
150
|
-
emittedFilesCacheMap: this
|
|
142
|
+
stylesheetBundlingResultMap: this._styleBundler?.getResultCache() ?? new Map(),
|
|
143
|
+
emittedFilesCacheMap: this._emittedFilesCacheMap,
|
|
151
144
|
emitFileSet: new Set([...buildResult.emitFileSet, globalStyleSheet].filterExists()),
|
|
152
145
|
};
|
|
153
146
|
}
|
|
154
|
-
async
|
|
155
|
-
const tsconfig = this
|
|
147
|
+
async _prepareAsync(modifiedFileSet) {
|
|
148
|
+
const tsconfig = this._parseTsConfig();
|
|
156
149
|
if (modifiedFileSet.size !== 0 && this._opt.watch) {
|
|
157
|
-
this
|
|
150
|
+
this._debug(`캐시 무효화 및 초기화 중...`);
|
|
158
151
|
// this._perf.run("캐시 무효화 및 초기화", () => {
|
|
159
|
-
this
|
|
152
|
+
this._perf.run("캐시 무효화 및 초기화", () => {
|
|
160
153
|
// 소스파일은 변경된 파일들로 무효화
|
|
161
154
|
for (const modifiedFile of modifiedFileSet) {
|
|
162
|
-
this
|
|
155
|
+
this._sourceFileCacheMap.delete(modifiedFile);
|
|
163
156
|
}
|
|
164
157
|
// 스타일 번들러 무효화 (transformResource 재실행 땜에 필요할듯)
|
|
165
|
-
if (this
|
|
166
|
-
const styleAffectedFileSet = this
|
|
158
|
+
if (this._styleBundler) {
|
|
159
|
+
const styleAffectedFileSet = this._styleBundler.invalidate(modifiedFileSet);
|
|
167
160
|
// 스타일 변경된 파일들로 무효화
|
|
168
161
|
for (const styleAffectedFile of styleAffectedFileSet) {
|
|
169
|
-
this
|
|
170
|
-
this
|
|
162
|
+
this._sourceFileCacheMap.delete(styleAffectedFile);
|
|
163
|
+
this._emittedFilesCacheMap.delete(styleAffectedFile);
|
|
171
164
|
}
|
|
172
165
|
}
|
|
173
166
|
// angular origin 파일 매핑은 변경된 파일들로 무효화
|
|
174
167
|
for (const modifiedFile of modifiedFileSet) {
|
|
175
|
-
this
|
|
168
|
+
this._cache.ngOrg.delete(modifiedFile);
|
|
176
169
|
}
|
|
177
170
|
// 기존 의존성에 의해 영향받는 파일들 계산
|
|
178
|
-
this
|
|
171
|
+
this._cache.dep.invalidates(modifiedFileSet);
|
|
179
172
|
// 결과물이 바뀌어야 하는 캐시 모두 무효화 (modified만 다시쓰면될듯..)
|
|
180
173
|
for (const modifiedFile of modifiedFileSet) {
|
|
181
|
-
this
|
|
174
|
+
this._emittedFilesCacheMap.delete(modifiedFile);
|
|
182
175
|
}
|
|
183
176
|
});
|
|
184
177
|
}
|
|
185
|
-
this
|
|
186
|
-
const compilerHost = this
|
|
187
|
-
return this
|
|
178
|
+
this._debug(`ts.Program 생성 중...`);
|
|
179
|
+
const compilerHost = this._perf.run("ts.CompilerHost 생성", () => {
|
|
180
|
+
return this._createCompilerHost(tsconfig.options, modifiedFileSet);
|
|
188
181
|
});
|
|
189
|
-
this
|
|
190
|
-
if (this
|
|
191
|
-
this
|
|
192
|
-
this
|
|
182
|
+
this._perf.run("ts.Program 생성", () => {
|
|
183
|
+
if (this._isForAngular) {
|
|
184
|
+
this._ngProgram = new NgtscProgram(tsconfig.fileNames, tsconfig.options, compilerHost, this._ngProgram);
|
|
185
|
+
this._program = this._ngProgram.getTsProgram();
|
|
193
186
|
}
|
|
194
187
|
else {
|
|
195
|
-
this
|
|
188
|
+
this._program = ts.createProgram(tsconfig.fileNames, tsconfig.options, compilerHost, this._program);
|
|
196
189
|
}
|
|
197
190
|
});
|
|
198
|
-
if (this
|
|
199
|
-
this
|
|
200
|
-
await this
|
|
201
|
-
await this
|
|
191
|
+
if (this._ngProgram) {
|
|
192
|
+
this._debug(`Angular 템플릿 분석...`);
|
|
193
|
+
await this._perf.run("Angular 템플릿 분석", async () => {
|
|
194
|
+
await this._ngProgram.compiler.analyzeAsync();
|
|
202
195
|
});
|
|
203
196
|
}
|
|
204
197
|
if (this._opt.watch && !this._opt.watch.emitOnly) {
|
|
205
|
-
this
|
|
206
|
-
this
|
|
198
|
+
this._debug(`새 의존성 분석 중...`);
|
|
199
|
+
this._perf.run("새 의존성 분석", () => {
|
|
207
200
|
// SdTsDependencyAnalyzer를 통해 의존성 분석 및 SdDepCache 업데이트
|
|
208
|
-
SdDepAnalyzer.analyze(this
|
|
201
|
+
SdDepAnalyzer.analyze(this._program, compilerHost, this._scopePathSet, this._cache);
|
|
209
202
|
});
|
|
210
203
|
// Angular 리소스 의존성 추가
|
|
211
|
-
if (this
|
|
212
|
-
this
|
|
213
|
-
this
|
|
214
|
-
SdDepAnalyzer.analyzeAngularResources(this
|
|
204
|
+
if (this._ngProgram) {
|
|
205
|
+
this._debug(`새 의존성 분석(Angular) 중...`);
|
|
206
|
+
this._perf.run("새 의존성 분석(Angular)", () => {
|
|
207
|
+
SdDepAnalyzer.analyzeAngularResources(this._ngProgram, this._scopePathSet, this._cache.dep);
|
|
215
208
|
});
|
|
216
209
|
}
|
|
217
210
|
}
|
|
218
|
-
const allTsFiles = this
|
|
211
|
+
const allTsFiles = this._program.getSourceFiles().mapMany((item) => [
|
|
219
212
|
PathUtils.norm(item.fileName),
|
|
220
213
|
...(item.fileName.endsWith(".d.ts")
|
|
221
214
|
? [PathUtils.norm(item.fileName.replace(/\.d\.ts$/, "") + ".js")]
|
|
222
215
|
: []),
|
|
223
216
|
]);
|
|
224
|
-
const watchFileSet = new Set(allTsFiles.filter((item) => this
|
|
217
|
+
const watchFileSet = new Set(allTsFiles.filter((item) => this._scopePathSet.inScope(item)));
|
|
225
218
|
let affectedFileSet;
|
|
226
219
|
if (modifiedFileSet.size === 0) {
|
|
227
|
-
affectedFileSet = new Set(allTsFiles.filter((item) => this
|
|
220
|
+
affectedFileSet = new Set(allTsFiles.filter((item) => this._scopePathSet.inScope(item)));
|
|
228
221
|
}
|
|
229
222
|
else {
|
|
230
|
-
const affectedFileMap = this
|
|
223
|
+
const affectedFileMap = this._cache.dep.getAffectedFileMap(modifiedFileSet);
|
|
231
224
|
affectedFileSet = new Set(Array.from(affectedFileMap.values()).mapMany((item) => Array.from(item)));
|
|
232
225
|
}
|
|
233
226
|
return {
|
|
@@ -235,12 +228,12 @@ export class SdTsCompiler {
|
|
|
235
228
|
compilerHost,
|
|
236
229
|
watchFileSet,
|
|
237
230
|
affectedFileSet,
|
|
238
|
-
styleAffectedFileSet: this
|
|
231
|
+
styleAffectedFileSet: this._styleBundler?.getAffectedFileSet(modifiedFileSet) ?? new Set(),
|
|
239
232
|
};
|
|
240
233
|
}
|
|
241
|
-
async
|
|
242
|
-
return await this
|
|
243
|
-
this
|
|
234
|
+
async _lintAsync(prepareResult) {
|
|
235
|
+
return await this._perf.run("Linting", async () => {
|
|
236
|
+
this._debug(`Linting...`);
|
|
244
237
|
const lintFilePaths = Array.from(prepareResult.affectedFileSet)
|
|
245
238
|
.filter((item) => PathUtils.isChildPath(item, this._opt.pkgPath))
|
|
246
239
|
.filter((item) => (!item.endsWith(".d.ts") && item.endsWith(".ts")) || item.endsWith(".js"))
|
|
@@ -257,7 +250,7 @@ export class SdTsCompiler {
|
|
|
257
250
|
// project: true,
|
|
258
251
|
// tsconfigRootDir: this._opt.pkgPath,
|
|
259
252
|
project: null,
|
|
260
|
-
programs: [this
|
|
253
|
+
programs: [this._program],
|
|
261
254
|
},
|
|
262
255
|
},
|
|
263
256
|
},
|
|
@@ -268,25 +261,25 @@ export class SdTsCompiler {
|
|
|
268
261
|
// return await linter.lintText(sf.text, { filePath: lintFilePath });
|
|
269
262
|
// });
|
|
270
263
|
const result = await linter.lintFiles(lintFilePaths);
|
|
271
|
-
this
|
|
264
|
+
this._debug(`Linting 완료`);
|
|
272
265
|
// return result.mapMany();
|
|
273
266
|
return result;
|
|
274
267
|
});
|
|
275
268
|
}
|
|
276
|
-
async
|
|
277
|
-
if (!this
|
|
269
|
+
async _buildGlobalStyleAsync() {
|
|
270
|
+
if (!this._isForAngular)
|
|
278
271
|
return;
|
|
279
272
|
//-- global style
|
|
280
273
|
const globalStyleFilePath = PathUtils.norm(this._opt.pkgPath, "scss/styles.scss");
|
|
281
|
-
if (this
|
|
274
|
+
if (this._emittedFilesCacheMap.has(globalStyleFilePath))
|
|
282
275
|
return;
|
|
283
276
|
if (!FsUtils.exists(globalStyleFilePath))
|
|
284
277
|
return;
|
|
285
|
-
this
|
|
286
|
-
await this
|
|
278
|
+
this._debug(`전역 스타일 번들링 중...`);
|
|
279
|
+
await this._perf.run("전역 스타일 번들링", async () => {
|
|
287
280
|
const data = await FsUtils.readFileAsync(globalStyleFilePath);
|
|
288
|
-
const stylesheetBundlingResult = await this
|
|
289
|
-
const emitFileInfos = this
|
|
281
|
+
const stylesheetBundlingResult = await this._styleBundler.bundleAsync(data, globalStyleFilePath, globalStyleFilePath);
|
|
282
|
+
const emitFileInfos = this._emittedFilesCacheMap.getOrCreate(globalStyleFilePath, []);
|
|
290
283
|
emitFileInfos.push({
|
|
291
284
|
outAbsPath: PathUtils.norm(this._opt.pkgPath, path
|
|
292
285
|
.relative(path.resolve(this._opt.pkgPath, "scss"), globalStyleFilePath)
|
|
@@ -296,55 +289,55 @@ export class SdTsCompiler {
|
|
|
296
289
|
});
|
|
297
290
|
return globalStyleFilePath;
|
|
298
291
|
}
|
|
299
|
-
|
|
292
|
+
_build(prepareResult) {
|
|
300
293
|
const emitFileSet = new Set();
|
|
301
294
|
const diagnostics = [];
|
|
302
295
|
if (!this._opt.watch?.emitOnly) {
|
|
303
|
-
this
|
|
304
|
-
this
|
|
305
|
-
diagnostics.push(...this
|
|
306
|
-
if (this
|
|
307
|
-
diagnostics.push(...this
|
|
296
|
+
this._debug(`프로그램 진단 수집 중...`);
|
|
297
|
+
this._perf.run("프로그램 진단 수집", () => {
|
|
298
|
+
diagnostics.push(...this._program.getConfigFileParsingDiagnostics(), ...this._program.getOptionsDiagnostics(), ...this._program.getGlobalDiagnostics());
|
|
299
|
+
if (this._ngProgram) {
|
|
300
|
+
diagnostics.push(...this._ngProgram.compiler.getOptionDiagnostics());
|
|
308
301
|
}
|
|
309
302
|
});
|
|
310
|
-
this
|
|
303
|
+
this._debug(`개별 파일 진단 수집 중...`);
|
|
311
304
|
for (const affectedFile of prepareResult.affectedFileSet) {
|
|
312
305
|
if (!PathUtils.isChildPath(affectedFile, this._opt.pkgPath))
|
|
313
306
|
continue;
|
|
314
|
-
const affectedSourceFile = this
|
|
307
|
+
const affectedSourceFile = this._program.getSourceFile(affectedFile);
|
|
315
308
|
if (!affectedSourceFile ||
|
|
316
|
-
(this
|
|
309
|
+
(this._ngProgram && this._ngProgram.compiler.ignoreForDiagnostics.has(affectedSourceFile))) {
|
|
317
310
|
continue;
|
|
318
311
|
}
|
|
319
|
-
this
|
|
320
|
-
diagnostics.push(...this
|
|
312
|
+
this._perf.run("개별 파일 진단 수집", () => {
|
|
313
|
+
diagnostics.push(...this._program.getSyntacticDiagnostics(affectedSourceFile), ...this._program.getSemanticDiagnostics(affectedSourceFile));
|
|
321
314
|
});
|
|
322
|
-
if (this
|
|
323
|
-
this
|
|
315
|
+
if (this._ngProgram) {
|
|
316
|
+
this._perf.run("개별 파일 진단 수집(Angular)", () => {
|
|
324
317
|
if (affectedSourceFile.isDeclarationFile)
|
|
325
318
|
return;
|
|
326
|
-
diagnostics.push(...this
|
|
319
|
+
diagnostics.push(...this._ngProgram.compiler.getDiagnosticsForFile(affectedSourceFile, OptimizeFor.WholeProgram));
|
|
327
320
|
});
|
|
328
321
|
}
|
|
329
322
|
}
|
|
330
323
|
}
|
|
331
324
|
if (!this._opt.watch?.noEmit) {
|
|
332
|
-
this
|
|
333
|
-
this
|
|
325
|
+
this._perf.run("파일 출력 (emit)", () => {
|
|
326
|
+
this._debug(`파일 출력 준비 중...`);
|
|
334
327
|
let transformers = {};
|
|
335
|
-
if (this
|
|
336
|
-
const angularTransfomers = this
|
|
328
|
+
if (this._ngProgram) {
|
|
329
|
+
const angularTransfomers = this._ngProgram.compiler.prepareEmit().transformers;
|
|
337
330
|
(transformers.before ??= []).push(...(angularTransfomers.before ?? []));
|
|
338
331
|
(transformers.after ??= []).push(...(angularTransfomers.after ?? []));
|
|
339
332
|
(transformers.afterDeclarations ??= []).push(...(angularTransfomers.afterDeclarations ?? []));
|
|
340
|
-
(transformers.before ??= []).push(replaceBootstrap(() => this
|
|
333
|
+
(transformers.before ??= []).push(replaceBootstrap(() => this._program.getTypeChecker()));
|
|
341
334
|
(transformers.before ??= []).push(createWorkerTransformer((file, importer) => {
|
|
342
335
|
const fullPath = path.resolve(path.dirname(importer), file);
|
|
343
336
|
const relPath = path.relative(path.resolve(this._opt.pkgPath, "src"), fullPath);
|
|
344
337
|
return relPath.replace(/\.ts$/, "").replaceAll("\\", "/") + ".js";
|
|
345
338
|
}));
|
|
346
339
|
}
|
|
347
|
-
this
|
|
340
|
+
this._debug(`파일 출력 중...`);
|
|
348
341
|
// affected에 새로 추가된 파일은 포함되지 않는 현상이 있어 sourceFileSet으로 바꿈
|
|
349
342
|
// 비교해보니, 딱히 getSourceFiles라서 더 느려지는것 같지는 않음
|
|
350
343
|
// 그래도 affected로 다시 테스트 (조금이라도 더 빠르게)
|
|
@@ -354,39 +347,39 @@ export class SdTsCompiler {
|
|
|
354
347
|
]) {
|
|
355
348
|
if (affectedFile.endsWith(".scss"))
|
|
356
349
|
continue;
|
|
357
|
-
if (this
|
|
350
|
+
if (this._emittedFilesCacheMap
|
|
358
351
|
.get(affectedFile)
|
|
359
352
|
?.some((item) => !item.outAbsPath?.endsWith(".css")))
|
|
360
353
|
continue;
|
|
361
|
-
const sf = this
|
|
354
|
+
const sf = this._program.getSourceFile(affectedFile);
|
|
362
355
|
if (!sf || sf.isDeclarationFile)
|
|
363
356
|
continue;
|
|
364
|
-
if (this
|
|
357
|
+
if (this._ngProgram?.compiler.ignoreForEmit.has(sf))
|
|
365
358
|
continue;
|
|
366
|
-
if (this
|
|
359
|
+
if (this._ngProgram?.compiler.incrementalCompilation.safeToSkipEmit(sf))
|
|
367
360
|
continue;
|
|
368
361
|
// 번들이 아닌 외부패키지는 보통 emit안해도 됨
|
|
369
362
|
// but esbuild를 통해 bundle로 묶어야 하는놈들은 모든 output이 있어야 함.
|
|
370
363
|
if (!this._forBundle && !PathUtils.isChildPath(sf.fileName, this._opt.pkgPath)) {
|
|
371
364
|
continue;
|
|
372
365
|
}
|
|
373
|
-
this
|
|
366
|
+
this._program.emit(sf, (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => {
|
|
374
367
|
if (!sourceFiles || sourceFiles.length === 0) {
|
|
375
368
|
prepareResult.compilerHost.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
|
|
376
369
|
return;
|
|
377
370
|
}
|
|
378
371
|
const sourceFile = ts.getOriginalNode(sourceFiles[0], ts.isSourceFile);
|
|
379
|
-
if (this
|
|
380
|
-
if (this
|
|
372
|
+
if (this._ngProgram) {
|
|
373
|
+
if (this._ngProgram.compiler.ignoreForEmit.has(sourceFile))
|
|
381
374
|
return;
|
|
382
|
-
this
|
|
375
|
+
this._ngProgram.compiler.incrementalCompilation.recordSuccessfulEmit(sourceFile);
|
|
383
376
|
}
|
|
384
|
-
const emitFileInfoCaches = this
|
|
377
|
+
const emitFileInfoCaches = this._emittedFilesCacheMap.getOrCreate(PathUtils.norm(sourceFile.fileName), []);
|
|
385
378
|
if (PathUtils.isChildPath(sourceFile.fileName, this._opt.pkgPath)) {
|
|
386
|
-
const real = this
|
|
379
|
+
const real = this._convertOutputToReal(fileName, prepareResult.tsconfig.distPath, text);
|
|
387
380
|
emitFileInfoCaches.push({
|
|
388
381
|
outAbsPath: real.filePath,
|
|
389
|
-
text: this
|
|
382
|
+
text: this._removeOutputDevModeLine(real.text),
|
|
390
383
|
});
|
|
391
384
|
}
|
|
392
385
|
else {
|
|
@@ -395,7 +388,7 @@ export class SdTsCompiler {
|
|
|
395
388
|
emitFileSet.add(PathUtils.norm(sourceFile.fileName));
|
|
396
389
|
}, undefined, undefined, transformers);
|
|
397
390
|
}
|
|
398
|
-
this
|
|
391
|
+
this._debug(`파일 출력 완료`);
|
|
399
392
|
});
|
|
400
393
|
}
|
|
401
394
|
return {
|
|
@@ -403,7 +396,7 @@ export class SdTsCompiler {
|
|
|
403
396
|
diagnostics,
|
|
404
397
|
};
|
|
405
398
|
}
|
|
406
|
-
|
|
399
|
+
_convertOutputToReal(filePath, distPath, text) {
|
|
407
400
|
let realFilePath = PathUtils.norm(filePath);
|
|
408
401
|
let realText = text;
|
|
409
402
|
const srcRelBasePath = path.resolve(distPath, path.basename(this._opt.pkgPath), "src");
|
|
@@ -418,10 +411,10 @@ export class SdTsCompiler {
|
|
|
418
411
|
}
|
|
419
412
|
return { filePath: realFilePath, text: realText };
|
|
420
413
|
}
|
|
421
|
-
|
|
414
|
+
_removeOutputDevModeLine(str) {
|
|
422
415
|
return str.replace(/\(\(\) => \{ \(typeof ngDevMode === "undefined" \|\| ngDevMode\) && i0.ɵsetClassDebugInfo\(.*, \{ className: ".*", filePath: ".*", lineNumber: [0-9]* }\); }\)\(\);/, "");
|
|
423
416
|
}
|
|
424
|
-
|
|
425
|
-
this
|
|
417
|
+
_debug(...msg) {
|
|
418
|
+
this._logger.debug(`[${path.basename(this._opt.pkgPath)}]`, ...msg);
|
|
426
419
|
}
|
|
427
420
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
export class SdCliPerformanceTimer {
|
|
2
|
-
#startingMap = new Map();
|
|
3
|
-
#resultMap = new Map();
|
|
4
2
|
constructor(_name) {
|
|
5
3
|
this._name = _name;
|
|
4
|
+
this._startingMap = new Map();
|
|
5
|
+
this._resultMap = new Map();
|
|
6
6
|
}
|
|
7
7
|
start(name) {
|
|
8
|
-
this
|
|
8
|
+
this._startingMap.set(name, {
|
|
9
9
|
time: new Date().getTime(),
|
|
10
10
|
cpu: process.cpuUsage(),
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
end(name) {
|
|
14
|
-
const start = this
|
|
14
|
+
const start = this._startingMap.get(name);
|
|
15
15
|
if (start == null)
|
|
16
16
|
throw new Error(`No start record for '${name}'`);
|
|
17
17
|
const time = new Date().getTime() - start.time;
|
|
18
18
|
const cpuUsage = process.cpuUsage(start.cpu);
|
|
19
19
|
const cpu = (cpuUsage.user + cpuUsage.system) / 1000; // μs -> ms
|
|
20
|
-
this
|
|
21
|
-
this
|
|
20
|
+
this._resultMap.set(name, { time, cpu });
|
|
21
|
+
this._startingMap.delete(name);
|
|
22
22
|
}
|
|
23
23
|
run(name, fn) {
|
|
24
24
|
const startTime = new Date().getTime();
|
|
@@ -26,8 +26,8 @@ export class SdCliPerformanceTimer {
|
|
|
26
26
|
const finish = (res, start) => {
|
|
27
27
|
const duration = new Date().getTime() - start;
|
|
28
28
|
const cpu = (process.cpuUsage(startCpu).user + process.cpuUsage(startCpu).system) / 1000;
|
|
29
|
-
const prev = this
|
|
30
|
-
this
|
|
29
|
+
const prev = this._resultMap.get(name);
|
|
30
|
+
this._resultMap.set(name, {
|
|
31
31
|
time: (prev?.time ?? 0) + duration,
|
|
32
32
|
cpu: (prev?.cpu ?? 0) + cpu,
|
|
33
33
|
});
|
|
@@ -42,7 +42,7 @@ export class SdCliPerformanceTimer {
|
|
|
42
42
|
toString() {
|
|
43
43
|
return `${this._name} 성능 보고서
|
|
44
44
|
------------------------------------
|
|
45
|
-
${Array.from(this
|
|
45
|
+
${Array.from(this._resultMap.entries())
|
|
46
46
|
.map(([key, val]) => `${key}: ${val.time.toLocaleString()}ms (${val.cpu.toLocaleString()}ms CPU)`)
|
|
47
47
|
.join("\n")}
|
|
48
48
|
------------------------------------`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/sd-cli",
|
|
3
|
-
"version": "12.15.
|
|
3
|
+
"version": "12.15.41",
|
|
4
4
|
"description": "심플리즘 패키지 - CLI",
|
|
5
5
|
"author": "김석래",
|
|
6
6
|
"repository": {
|
|
@@ -12,18 +12,18 @@
|
|
|
12
12
|
"bin": "./dist/sd-cli.js",
|
|
13
13
|
"type": "module",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@angular/build": "^20.3.
|
|
15
|
+
"@angular/build": "^20.3.13",
|
|
16
16
|
"@angular/compiler": "^20.3.15",
|
|
17
17
|
"@angular/compiler-cli": "^20.3.15",
|
|
18
18
|
"@anthropic-ai/sdk": "^0.71.0",
|
|
19
19
|
"@electron/rebuild": "^4.0.1",
|
|
20
|
-
"@simplysm/sd-core-common": "12.15.
|
|
21
|
-
"@simplysm/sd-core-node": "12.15.
|
|
22
|
-
"@simplysm/sd-service-server": "12.15.
|
|
23
|
-
"@simplysm/sd-storage": "12.15.
|
|
24
|
-
"browserslist": "^4.28.
|
|
20
|
+
"@simplysm/sd-core-common": "12.15.41",
|
|
21
|
+
"@simplysm/sd-core-node": "12.15.41",
|
|
22
|
+
"@simplysm/sd-service-server": "12.15.41",
|
|
23
|
+
"@simplysm/sd-storage": "12.15.41",
|
|
24
|
+
"browserslist": "^4.28.1",
|
|
25
25
|
"cordova": "^13.0.0",
|
|
26
|
-
"electron": "^39.2.
|
|
26
|
+
"electron": "^39.2.5",
|
|
27
27
|
"electron-builder": "26.0.12",
|
|
28
28
|
"esbuild": "0.25.9",
|
|
29
29
|
"esbuild-sass-plugin": "^3.3.1",
|