@simplysm/sd-cli 12.8.21 → 12.9.1
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/sd-cli-ai-command.js +2 -1
- package/dist/entry/sd-cli-ai-command.js.map +1 -1
- package/dist/entry/sd-cli-cordova.d.ts +1 -1
- package/dist/entry/sd-cli-cordova.js +10 -9
- package/dist/entry/sd-cli-cordova.js.map +1 -1
- package/dist/entry/sd-cli-electron.d.ts +6 -6
- package/dist/entry/sd-cli-electron.js +15 -9
- package/dist/entry/sd-cli-electron.js.map +1 -1
- package/dist/entry/sd-cli-local-update.d.ts +5 -5
- package/dist/entry/sd-cli-local-update.js +8 -12
- package/dist/entry/sd-cli-local-update.js.map +1 -1
- package/dist/entry/sd-cli-project.d.ts +11 -11
- package/dist/entry/sd-cli-project.js +11 -14
- package/dist/entry/sd-cli-project.js.map +1 -1
- package/dist/entry/utils/loadProjConfAsync.d.ts +5 -0
- package/dist/entry/utils/loadProjConfAsync.js +8 -0
- package/dist/entry/utils/loadProjConfAsync.js.map +1 -0
- package/dist/pkg-builders/client/sd-client.build-runner.js +1 -1
- package/dist/pkg-builders/client/sd-client.build-runner.js.map +1 -1
- package/dist/pkg-builders/client/sd-ng.bundler-context.d.ts +6 -5
- package/dist/pkg-builders/client/sd-ng.bundler-context.js +6 -6
- package/dist/pkg-builders/client/sd-ng.bundler-context.js.map +1 -1
- package/dist/pkg-builders/client/sd-ng.bundler.d.ts +13 -13
- package/dist/pkg-builders/client/sd-ng.bundler.js +1 -1
- package/dist/pkg-builders/client/sd-ng.bundler.js.map +1 -1
- package/dist/pkg-builders/client/sd-ng.plugin-creator.js +4 -88
- package/dist/pkg-builders/client/sd-ng.plugin-creator.js.map +1 -1
- package/dist/pkg-builders/lib/sd-js-lib.build-runner.js.map +1 -1
- package/dist/pkg-builders/lib/sd-ts-lib.build-runner.d.ts +1 -1
- package/dist/pkg-builders/lib/sd-ts-lib.build-runner.js.map +1 -1
- package/dist/pkg-builders/lib/sd-ts-lib.builder.js.map +1 -1
- package/dist/pkg-builders/sd-multi.build-runner.d.ts +4 -0
- package/dist/pkg-builders/sd-multi.build-runner.js +33 -25
- package/dist/pkg-builders/sd-multi.build-runner.js.map +1 -1
- package/dist/pkg-builders/server/sd-server.build-runner.js.map +1 -1
- package/dist/pkg-builders/server/sd-server.bundler.d.ts +6 -2
- package/dist/pkg-builders/server/sd-server.bundler.js +24 -24
- package/dist/pkg-builders/server/sd-server.bundler.js.map +1 -1
- package/dist/sd-cli/vitest.config.d.ts +2 -0
- package/dist/sd-cli/vitest.config.js +15 -0
- package/dist/sd-cli/vitest.config.js.map +1 -0
- package/dist/sd-cli.js +7 -36
- package/dist/sd-cli.js.map +1 -1
- package/dist/ts-compiler/sd-dependency-analyzer.d.ts +8 -0
- package/dist/ts-compiler/sd-dependency-analyzer.js +244 -0
- package/dist/ts-compiler/sd-dependency-analyzer.js.map +1 -0
- package/dist/ts-compiler/sd-dependency-cache.d.ts +27 -0
- package/dist/ts-compiler/sd-dependency-cache.js +232 -0
- package/dist/ts-compiler/sd-dependency-cache.js.map +1 -0
- package/dist/ts-compiler/sd-ts-compiler.d.ts +7 -9
- package/dist/ts-compiler/sd-ts-compiler.js +101 -188
- package/dist/ts-compiler/sd-ts-compiler.js.map +1 -1
- package/dist/types/worker.types.d.ts +19 -0
- package/dist/utils/sd-cli-performance-time.d.ts +2 -1
- package/dist/utils/sd-cli-performance-time.js +9 -9
- package/dist/utils/sd-cli-performance-time.js.map +1 -1
- package/dist/workers/style-bundler.worker.d.ts +1 -0
- package/dist/workers/style-bundler.worker.js +56 -0
- package/dist/workers/style-bundler.worker.js.map +1 -0
- package/package.json +11 -11
- package/src/entry/sd-cli-ai-command.ts +2 -1
- package/src/entry/sd-cli-cordova.ts +20 -20
- package/src/entry/sd-cli-electron.ts +54 -23
- package/src/entry/sd-cli-local-update.ts +14 -29
- package/src/entry/sd-cli-project.ts +24 -41
- package/src/entry/utils/loadProjConfAsync.ts +12 -0
- package/src/pkg-builders/client/sd-client.build-runner.ts +7 -7
- package/src/pkg-builders/client/sd-ng.bundler-context.ts +15 -12
- package/src/pkg-builders/client/sd-ng.bundler.ts +17 -20
- package/src/pkg-builders/client/sd-ng.plugin-creator.ts +5 -94
- package/src/pkg-builders/lib/sd-js-lib.build-runner.ts +6 -6
- package/src/pkg-builders/lib/sd-ts-lib.build-runner.ts +7 -7
- package/src/pkg-builders/lib/sd-ts-lib.builder.ts +1 -1
- package/src/pkg-builders/sd-multi.build-runner.ts +54 -39
- package/src/pkg-builders/server/sd-server.build-runner.ts +6 -6
- package/src/pkg-builders/server/sd-server.bundler.ts +43 -35
- package/src/sd-cli.ts +7 -36
- package/src/ts-compiler/sd-dependency-analyzer.ts +312 -0
- package/src/ts-compiler/sd-dependency-cache.ts +328 -0
- package/src/ts-compiler/sd-ts-compiler.ts +161 -256
- package/src/types/worker.types.ts +17 -0
- package/src/utils/sd-cli-performance-time.ts +9 -9
- package/src/workers/style-bundler.worker.ts +70 -0
- package/tests/deps/sd-dependency-analyzer.spec.ts +272 -0
- package/tests/deps/sd-dependency-cache.spec.ts +144 -0
- package/tsconfig.json +1 -1
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +15 -0
- package/dist/index.d.ts +0 -34
- package/dist/index.js +0 -35
- package/dist/index.js.map +0 -1
- package/dist/ts-compiler/sd-ts-dependency-analyzer.d.ts +0 -10
- package/dist/ts-compiler/sd-ts-dependency-analyzer.js +0 -140
- package/dist/ts-compiler/sd-ts-dependency-analyzer.js.map +0 -1
- package/src/index.ts +0 -34
- package/src/ts-compiler/sd-ts-dependency-analyzer.ts +0 -176
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { FsUtils, PathUtils, SdLogger, TNormPath } from "@simplysm/sd-core-node";
|
|
3
|
+
import { FsUtils, PathUtils, SdLogger, SdWorker, TNormPath } from "@simplysm/sd-core-node";
|
|
4
4
|
import { StringUtils } from "@simplysm/sd-core-common";
|
|
5
5
|
import { NgtscProgram, OptimizeFor } from "@angular/compiler-cli";
|
|
6
|
-
import {
|
|
7
|
-
ComponentStylesheetBundler,
|
|
8
|
-
} from "@angular/build/src/tools/esbuild/angular/component-stylesheets";
|
|
9
6
|
import { AngularCompilerHost } from "@angular/build/src/tools/angular/angular-host";
|
|
10
|
-
import { transformSupportedBrowsersToTargets } from "@angular/build/src/tools/esbuild/utils";
|
|
11
|
-
import browserslist from "browserslist";
|
|
12
7
|
import {
|
|
13
8
|
replaceBootstrap,
|
|
14
9
|
} from "@angular/build/src/tools/angular/transformers/jit-bootstrap-transformer";
|
|
@@ -19,19 +14,26 @@ import {
|
|
|
19
14
|
SdTsCompilerOptions,
|
|
20
15
|
TStylesheetBundlingResult,
|
|
21
16
|
} from "../types/ts-compiler.types";
|
|
22
|
-
import { ISdBuildMessage } from "../types/build.types";
|
|
23
17
|
import {
|
|
24
18
|
createWorkerTransformer,
|
|
25
19
|
} from "@angular/build/src/tools/angular/transformers/web-worker-transformer";
|
|
26
20
|
import { ESLint } from "eslint";
|
|
27
|
-
import {
|
|
21
|
+
import { ISdAffectedFileTreeNode, SdDependencyCache } from "./sd-dependency-cache";
|
|
22
|
+
import { SdDependencyAnalyzer } from "./sd-dependency-analyzer";
|
|
23
|
+
import { TStyleBundlerWorkerType } from "../types/worker.types";
|
|
28
24
|
|
|
29
25
|
export class SdTsCompiler {
|
|
30
26
|
private _logger = SdLogger.get(["simplysm", "sd-cli", "SdTsCompiler"]);
|
|
31
27
|
|
|
32
28
|
private _isForAngular: boolean;
|
|
33
29
|
|
|
34
|
-
private
|
|
30
|
+
private _stylesheetBundlingWorker?: SdWorker<TStyleBundlerWorkerType>;
|
|
31
|
+
|
|
32
|
+
private _ngProgram: NgtscProgram | undefined;
|
|
33
|
+
private _program: ts.Program | undefined;
|
|
34
|
+
|
|
35
|
+
// 빌드정보 캐싱
|
|
36
|
+
private _depCache = new SdDependencyCache();
|
|
35
37
|
private _sourceFileCacheMap = new Map<TNormPath, ts.SourceFile>();
|
|
36
38
|
private _emittedFilesCacheMap = new Map<
|
|
37
39
|
TNormPath,
|
|
@@ -41,15 +43,7 @@ export class SdTsCompiler {
|
|
|
41
43
|
}[]
|
|
42
44
|
>();
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
private _ngProgram: NgtscProgram | undefined;
|
|
47
|
-
private _program: ts.Program | undefined;
|
|
48
|
-
|
|
49
|
-
private _modifiedFileSet = new Set<TNormPath>();
|
|
50
|
-
private _affectedFileSet = new Set<TNormPath>();
|
|
51
|
-
|
|
52
|
-
private _watchFileSet = new Set<TNormPath>();
|
|
46
|
+
// 빌드결과 캐싱
|
|
53
47
|
private _stylesheetBundlingResultMap = new Map<TNormPath, TStylesheetBundlingResult>();
|
|
54
48
|
|
|
55
49
|
private _perf!: SdCliPerformanceTimer;
|
|
@@ -60,46 +54,9 @@ export class SdTsCompiler {
|
|
|
60
54
|
const tsconfigPath = path.resolve(this._opt.pkgPath, "tsconfig.json");
|
|
61
55
|
const tsconfig = FsUtils.readJson(tsconfigPath);
|
|
62
56
|
this._isForAngular = Boolean(tsconfig.angularCompilerOptions);
|
|
63
|
-
|
|
64
|
-
if (this._isForAngular) {
|
|
65
|
-
//-- stylesheetBundler
|
|
66
|
-
this._stylesheetBundler = new ComponentStylesheetBundler(
|
|
67
|
-
{
|
|
68
|
-
workspaceRoot: this._opt.pkgPath,
|
|
69
|
-
optimization: !this._opt.isDevMode,
|
|
70
|
-
inlineFonts: true,
|
|
71
|
-
preserveSymlinks: false,
|
|
72
|
-
sourcemap: this._opt.isDevMode ? "inline" : false,
|
|
73
|
-
outputNames: { bundles: "[name]", media: "media/[name]" },
|
|
74
|
-
includePaths: [],
|
|
75
|
-
externalDependencies: [],
|
|
76
|
-
target: transformSupportedBrowsersToTargets(browserslist(["Chrome > 78"])),
|
|
77
|
-
postcssConfiguration: {
|
|
78
|
-
plugins: [["css-has-pseudo"]],
|
|
79
|
-
},
|
|
80
|
-
tailwindConfiguration: undefined,
|
|
81
|
-
cacheOptions: {
|
|
82
|
-
enabled: true,
|
|
83
|
-
path: ".cache/angular",
|
|
84
|
-
basePath: ".cache",
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
"scss",
|
|
88
|
-
this._opt.isDevMode,
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
57
|
}
|
|
92
58
|
|
|
93
|
-
private _parseTsConfig()
|
|
94
|
-
const config = this._loadTsConfig();
|
|
95
|
-
const compilerHost = this._createCompilerHost(config.options);
|
|
96
|
-
return {
|
|
97
|
-
...config,
|
|
98
|
-
compilerHost,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private _loadTsConfig() {
|
|
59
|
+
private _parseTsConfig() {
|
|
103
60
|
const tsconfigPath = path.resolve(this._opt.pkgPath, "tsconfig.json");
|
|
104
61
|
const tsconfig = FsUtils.readJson(tsconfigPath);
|
|
105
62
|
const parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._opt.pkgPath, {
|
|
@@ -119,7 +76,10 @@ export class SdTsCompiler {
|
|
|
119
76
|
};
|
|
120
77
|
}
|
|
121
78
|
|
|
122
|
-
private _createCompilerHost(
|
|
79
|
+
private _createCompilerHost(
|
|
80
|
+
compilerOptions: ts.CompilerOptions,
|
|
81
|
+
modifiedFileSet: Set<TNormPath>,
|
|
82
|
+
) {
|
|
123
83
|
const compilerHost = ts.createCompilerHost(compilerOptions);
|
|
124
84
|
|
|
125
85
|
const baseGetSourceFile = compilerHost.getSourceFile;
|
|
@@ -155,12 +115,6 @@ export class SdTsCompiler {
|
|
|
155
115
|
return sf;
|
|
156
116
|
};
|
|
157
117
|
|
|
158
|
-
const baseReadFile = compilerHost.readFile;
|
|
159
|
-
compilerHost.readFile = (fileName) => {
|
|
160
|
-
this._watchFileSet.add(PathUtils.norm(fileName));
|
|
161
|
-
return baseReadFile.call(compilerHost, fileName);
|
|
162
|
-
};
|
|
163
|
-
|
|
164
118
|
if (this._isForAngular) {
|
|
165
119
|
(compilerHost as AngularCompilerHost).readResource = (fileName: string) => {
|
|
166
120
|
return compilerHost.readFile(fileName) ?? "";
|
|
@@ -190,13 +144,30 @@ export class SdTsCompiler {
|
|
|
190
144
|
};
|
|
191
145
|
|
|
192
146
|
(compilerHost as AngularCompilerHost).getModifiedResourceFiles = () => {
|
|
193
|
-
return new Set(Array.from(
|
|
147
|
+
return new Set(Array.from(modifiedFileSet).map((item) => PathUtils.posix(item)));
|
|
194
148
|
};
|
|
195
149
|
}
|
|
196
150
|
|
|
197
151
|
return compilerHost;
|
|
198
152
|
}
|
|
199
153
|
|
|
154
|
+
private async _getOrCreateStyleBundleWorkerAsync() {
|
|
155
|
+
if (this._stylesheetBundlingWorker) {
|
|
156
|
+
return this._stylesheetBundlingWorker;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
this._stylesheetBundlingWorker = new SdWorker<TStyleBundlerWorkerType>(
|
|
160
|
+
import.meta.resolve("../workers/style-bundler.worker"),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
await this._stylesheetBundlingWorker.run(
|
|
164
|
+
"prepare",
|
|
165
|
+
[this._opt.pkgPath, this._opt.isDevMode],
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
return this._stylesheetBundlingWorker;
|
|
169
|
+
}
|
|
170
|
+
|
|
200
171
|
private async _bundleStylesheetAsync(
|
|
201
172
|
data: string,
|
|
202
173
|
containingFile: TNormPath,
|
|
@@ -215,24 +186,12 @@ export class SdTsCompiler {
|
|
|
215
186
|
}
|
|
216
187
|
|
|
217
188
|
try {
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
? await this._stylesheetBundler!.bundleFile(resourceFile)
|
|
221
|
-
: await this._stylesheetBundler!.bundleInline(data, containingFile, "scss");
|
|
222
|
-
|
|
223
|
-
if (result.referencedFiles) {
|
|
224
|
-
for (const referencedFile of result.referencedFiles) {
|
|
225
|
-
const depCacheSet = this._revDepCacheMap.getOrCreate(
|
|
226
|
-
PathUtils.norm(referencedFile),
|
|
227
|
-
new Set<TNormPath>(),
|
|
228
|
-
);
|
|
229
|
-
depCacheSet.add(fileNPath);
|
|
230
|
-
}
|
|
189
|
+
const worker = this._stylesheetBundlingWorker!;
|
|
190
|
+
const result = await worker.run("bundle", [data, containingFile, resourceFile]);
|
|
231
191
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
);
|
|
192
|
+
for (const referencedFile of result.referencedFiles ?? []) {
|
|
193
|
+
// 참조하는 파일과 참조된 파일 사이의 의존성 관계 추가
|
|
194
|
+
this._depCache.addImport(fileNPath, PathUtils.norm(referencedFile), 0);
|
|
236
195
|
}
|
|
237
196
|
|
|
238
197
|
this._stylesheetBundlingResultMap.set(fileNPath, result);
|
|
@@ -255,111 +214,96 @@ export class SdTsCompiler {
|
|
|
255
214
|
});
|
|
256
215
|
}
|
|
257
216
|
|
|
258
|
-
|
|
217
|
+
async compileAsync(modifiedFileSet: Set<TNormPath>): Promise<ISdTsCompilerResult> {
|
|
259
218
|
this._perf = new SdCliPerformanceTimer("esbuild compile");
|
|
260
219
|
|
|
261
|
-
|
|
262
|
-
this._affectedFileSet = new Set<TNormPath>();
|
|
263
|
-
|
|
264
|
-
/*for (const mod of modifiedFileSet) {
|
|
265
|
-
const workerImporters = this.#workerRevDependencyCacheMap.get(mod);
|
|
266
|
-
if (workerImporters) {
|
|
267
|
-
this.#modifiedFileSet.adds(...workerImporters);
|
|
268
|
-
} else {
|
|
269
|
-
this.#modifiedFileSet.add(mod);
|
|
270
|
-
}
|
|
271
|
-
}*/
|
|
272
|
-
|
|
273
|
-
const tsconf = this._parseTsConfig();
|
|
274
|
-
|
|
275
|
-
const prepareResult = await this._prepareAsync(tsconf);
|
|
220
|
+
const prepareResult = await this._prepareAsync(modifiedFileSet);
|
|
276
221
|
|
|
277
|
-
const [buildResult, lintResults] = await Promise.all([
|
|
278
|
-
this.
|
|
279
|
-
this.
|
|
222
|
+
const [globalStyleSheet, buildResult, lintResults] = await Promise.all([
|
|
223
|
+
this._buildGlobalStyleAsync(),
|
|
224
|
+
this._build(prepareResult),
|
|
225
|
+
this._lintAsync(prepareResult),
|
|
280
226
|
]);
|
|
281
227
|
|
|
282
228
|
this._debug(`빌드 완료됨`, this._perf.toString());
|
|
283
|
-
this._debug(`영향 받은 파일: ${
|
|
284
|
-
this._debug(`감시 중인 파일: ${
|
|
229
|
+
this._debug(`영향 받은 파일: ${prepareResult.affectedFileSet.size}개`);
|
|
230
|
+
this._debug(`감시 중인 파일: ${prepareResult.watchFileSet.size}개`);
|
|
285
231
|
|
|
286
232
|
return {
|
|
287
233
|
messages: [
|
|
288
|
-
...prepareResult.messages,
|
|
289
234
|
...SdCliConvertMessageUtils.convertToBuildMessagesFromTsDiag(buildResult.diagnostics),
|
|
290
235
|
...SdCliConvertMessageUtils.convertToBuildMessagesFromEslint(lintResults),
|
|
291
236
|
],
|
|
292
|
-
|
|
293
|
-
|
|
237
|
+
affectedFileSet: prepareResult.affectedFileSet,
|
|
238
|
+
watchFileSet: prepareResult.watchFileSet,
|
|
294
239
|
stylesheetBundlingResultMap: this._stylesheetBundlingResultMap,
|
|
295
240
|
emittedFilesCacheMap: this._emittedFilesCacheMap,
|
|
296
|
-
emitFileSet: buildResult.emitFileSet,
|
|
241
|
+
emitFileSet: new Set([...buildResult.emitFileSet, globalStyleSheet].filterExists()),
|
|
297
242
|
};
|
|
298
243
|
}
|
|
299
244
|
|
|
300
|
-
private async _prepareAsync(
|
|
301
|
-
|
|
302
|
-
this._debug(`영향 받은 파일 추적 중... (구 의존성)`);
|
|
245
|
+
private async _prepareAsync(modifiedFileSet: Set<TNormPath>): Promise<IPrepareResult> {
|
|
246
|
+
const worker = await this._getOrCreateStyleBundleWorkerAsync();
|
|
303
247
|
|
|
304
|
-
|
|
305
|
-
for (const modifiedFile of this._modifiedFileSet) {
|
|
306
|
-
this._affectedFileSet.add(modifiedFile);
|
|
248
|
+
const tsconfig = this._parseTsConfig();
|
|
307
249
|
|
|
308
|
-
|
|
250
|
+
if (modifiedFileSet.size !== 0) {
|
|
251
|
+
this._debug(`캐시 무효화 및 초기화 중...`);
|
|
252
|
+
|
|
253
|
+
await this._perf.run("캐시 무효화 및 초기화", async () => {
|
|
254
|
+
// 기존 의존성에 의해 영향받는 파일들 계산
|
|
255
|
+
const affectedFileSet = this._depCache.getAffectedFileSet(modifiedFileSet);
|
|
309
256
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
257
|
+
const getTreeText = (node: ISdAffectedFileTreeNode, indent = "") => {
|
|
258
|
+
let result = indent + node.fileNPath + "\n";
|
|
259
|
+
for (const child of node.children) {
|
|
260
|
+
result += getTreeText(child, indent + " ");
|
|
314
261
|
}
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
262
|
|
|
318
|
-
|
|
263
|
+
return result;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const affectedFileTree = this._depCache.getAffectedFileTree(modifiedFileSet);
|
|
267
|
+
this._debug(`
|
|
268
|
+
영향받은 기존파일:
|
|
269
|
+
${affectedFileTree.map(item => getTreeText(item)).join("\n")}`.trim());
|
|
319
270
|
|
|
320
|
-
|
|
321
|
-
|
|
271
|
+
// 스타일 번들러에서 영향받은 파일 관련 항목 무효화
|
|
272
|
+
await worker.run("invalidate", [affectedFileSet]);
|
|
322
273
|
|
|
323
|
-
|
|
274
|
+
// 의존성 캐시에서 영향받은 파일 관련 항목 무효화
|
|
275
|
+
this._depCache.invalidates(affectedFileSet);
|
|
276
|
+
|
|
277
|
+
// 내부 캐시에서 영향받은 파일 관련 항목 무효화
|
|
278
|
+
for (const affectedFile of affectedFileSet) {
|
|
324
279
|
this._emittedFilesCacheMap.delete(affectedFile);
|
|
325
280
|
this._sourceFileCacheMap.delete(affectedFile);
|
|
326
281
|
this._stylesheetBundlingResultMap.delete(affectedFile);
|
|
327
|
-
this._watchFileSet.delete(affectedFile);
|
|
328
|
-
|
|
329
|
-
for (const [key, deps] of this._revDepCacheMap.entries()) {
|
|
330
|
-
if (key === affectedFile) {
|
|
331
|
-
this._revDepCacheMap.delete(key);
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (deps.has(affectedFile)) {
|
|
336
|
-
deps.delete(affectedFile);
|
|
337
|
-
if (deps.size === 0) {
|
|
338
|
-
this._revDepCacheMap.delete(key);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
282
|
}
|
|
343
283
|
});
|
|
344
284
|
}
|
|
345
285
|
|
|
346
286
|
this._debug(`ts.Program 생성 중...`);
|
|
347
287
|
|
|
288
|
+
const compilerHost = this._perf.run("ts.CompilerHost 생성", () => {
|
|
289
|
+
return this._createCompilerHost(tsconfig.options, modifiedFileSet);
|
|
290
|
+
});
|
|
291
|
+
|
|
348
292
|
this._perf.run("ts.Program 생성", () => {
|
|
349
293
|
if (this._isForAngular) {
|
|
350
294
|
this._ngProgram = new NgtscProgram(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
295
|
+
tsconfig.fileNames,
|
|
296
|
+
tsconfig.options,
|
|
297
|
+
compilerHost,
|
|
354
298
|
this._ngProgram,
|
|
355
299
|
);
|
|
356
300
|
this._program = this._ngProgram.getTsProgram();
|
|
357
301
|
}
|
|
358
302
|
else {
|
|
359
303
|
this._program = ts.createProgram(
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
304
|
+
tsconfig.fileNames,
|
|
305
|
+
tsconfig.options,
|
|
306
|
+
compilerHost,
|
|
363
307
|
this._program,
|
|
364
308
|
);
|
|
365
309
|
}
|
|
@@ -373,86 +317,40 @@ export class SdTsCompiler {
|
|
|
373
317
|
|
|
374
318
|
this._debug(`새 의존성 분석 중...`);
|
|
375
319
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
320
|
+
this._perf.run("새 의존성 분석", () => {
|
|
321
|
+
// SdTsDependencyAnalyzer를 통해 의존성 분석 및 SdDepCache 업데이트
|
|
322
|
+
SdDependencyAnalyzer.analyze(
|
|
379
323
|
this._program!,
|
|
380
|
-
|
|
324
|
+
compilerHost,
|
|
381
325
|
this._opt.watchScopePaths,
|
|
326
|
+
this._depCache,
|
|
382
327
|
);
|
|
383
|
-
messages.push(...analysed.messages);
|
|
384
|
-
|
|
385
|
-
for (const sf of analysed.sourceFileSet) {
|
|
386
|
-
const filePath = PathUtils.norm(sf.fileName);
|
|
387
|
-
const deps = analysed.allDepMap.get(filePath) ?? new Set<TNormPath>();
|
|
388
|
-
|
|
389
|
-
for (const dep of deps) {
|
|
390
|
-
const depCache = this._revDepCacheMap.getOrCreate(dep, new Set<TNormPath>());
|
|
391
|
-
depCache.add(filePath);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (this._ngProgram) {
|
|
395
|
-
if (this._ngProgram.compiler.ignoreForEmit.has(sf)) {
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
for (const dep of this._ngProgram.compiler.getResourceDependencies(sf)) {
|
|
400
|
-
const ref = this._revDepCacheMap.getOrCreate(
|
|
401
|
-
PathUtils.norm(dep),
|
|
402
|
-
new Set<TNormPath>(),
|
|
403
|
-
);
|
|
404
|
-
ref.add(filePath);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
return analysed;
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
if (this._modifiedFileSet.size === 0) {
|
|
413
|
-
this._debug(`영향 받은 파일 추가 중... (새 의존성)`);
|
|
414
328
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
continue;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
this._affectedFileSet.add(PathUtils.norm(sf.fileName));
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
for (const dep of this._revDepCacheMap.keys()) {
|
|
430
|
-
if (this._modifiedFileSet.has(dep)) {
|
|
431
|
-
this._affectedFileSet.adds(
|
|
432
|
-
...Array.from(this._revDepCacheMap.get(dep)!).mapMany((item) =>
|
|
433
|
-
[
|
|
434
|
-
item,
|
|
435
|
-
// .d.ts면 .js파일도 affected에 추가
|
|
436
|
-
item.endsWith(".d.ts") ? PathUtils.norm(item.replace(/\.d\.ts$/, ".js")) : undefined,
|
|
437
|
-
].filterExists(),
|
|
438
|
-
),
|
|
329
|
+
// Angular 리소스 의존성 추가
|
|
330
|
+
if (this._ngProgram) {
|
|
331
|
+
SdDependencyAnalyzer.analyzeAngularResources(
|
|
332
|
+
this._ngProgram,
|
|
333
|
+
this._opt.watchScopePaths,
|
|
334
|
+
this._depCache,
|
|
439
335
|
);
|
|
440
336
|
}
|
|
337
|
+
});
|
|
441
338
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
}
|
|
447
|
-
}
|
|
339
|
+
const affectedFileSet = modifiedFileSet.size === 0
|
|
340
|
+
? this._depCache.getFiles()
|
|
341
|
+
: this._depCache.getAffectedFileSet(modifiedFileSet);
|
|
342
|
+
const watchFileSet = this._depCache.getFiles();
|
|
448
343
|
|
|
449
344
|
return {
|
|
450
|
-
|
|
345
|
+
tsconfig,
|
|
346
|
+
compilerHost,
|
|
347
|
+
affectedFileSet,
|
|
348
|
+
watchFileSet,
|
|
451
349
|
};
|
|
452
350
|
}
|
|
453
351
|
|
|
454
|
-
private async _lintAsync() {
|
|
455
|
-
const lintFilePaths = Array.from(
|
|
352
|
+
private async _lintAsync(prepareResult: IPrepareResult) {
|
|
353
|
+
const lintFilePaths = Array.from(prepareResult.affectedFileSet)
|
|
456
354
|
.filter((item) => PathUtils.isChildPath(item, this._opt.pkgPath))
|
|
457
355
|
.filter((item) => (
|
|
458
356
|
(!item.endsWith(".d.ts") && item.endsWith(".ts")) ||
|
|
@@ -470,7 +368,6 @@ export class SdTsCompiler {
|
|
|
470
368
|
overrideConfig: {
|
|
471
369
|
languageOptions: {
|
|
472
370
|
parserOptions: {
|
|
473
|
-
// parser: tseslint.parser,
|
|
474
371
|
project: null,
|
|
475
372
|
programs: [this._program],
|
|
476
373
|
},
|
|
@@ -478,16 +375,45 @@ export class SdTsCompiler {
|
|
|
478
375
|
},
|
|
479
376
|
});
|
|
480
377
|
return await linter.lintFiles(lintFilePaths);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private async _buildGlobalStyleAsync() {
|
|
381
|
+
//-- global style
|
|
382
|
+
if (
|
|
383
|
+
this._opt.globalStyleFilePath != null &&
|
|
384
|
+
FsUtils.exists(this._opt.globalStyleFilePath) &&
|
|
385
|
+
!this._emittedFilesCacheMap.has(this._opt.globalStyleFilePath)
|
|
386
|
+
) {
|
|
387
|
+
this._debug(`전역 스타일 번들링 중...`);
|
|
388
|
+
|
|
389
|
+
await this._perf.run("전역 스타일 번들링", async () => {
|
|
390
|
+
const data = await FsUtils.readFileAsync(this._opt.globalStyleFilePath!);
|
|
391
|
+
const stylesheetBundlingResult = await this._bundleStylesheetAsync(
|
|
392
|
+
data,
|
|
393
|
+
this._opt.globalStyleFilePath!,
|
|
394
|
+
this._opt.globalStyleFilePath,
|
|
395
|
+
);
|
|
396
|
+
const emitFileInfos = this._emittedFilesCacheMap.getOrCreate(
|
|
397
|
+
this._opt.globalStyleFilePath!,
|
|
398
|
+
[],
|
|
399
|
+
);
|
|
400
|
+
emitFileInfos.push({
|
|
401
|
+
outAbsPath: PathUtils.norm(
|
|
402
|
+
this._opt.pkgPath,
|
|
403
|
+
path.relative(path.resolve(this._opt.pkgPath, "src"), this._opt.globalStyleFilePath!)
|
|
404
|
+
.replace(/\.scss$/, ".css"),
|
|
405
|
+
),
|
|
406
|
+
text: stylesheetBundlingResult.contents ?? "",
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
return this._opt.globalStyleFilePath;
|
|
411
|
+
}
|
|
481
412
|
|
|
482
|
-
|
|
483
|
-
// {
|
|
484
|
-
// cwd: this.#pkgPath,
|
|
485
|
-
// fileSet: this.#affectedFileSet,
|
|
486
|
-
// },
|
|
487
|
-
// ]);
|
|
413
|
+
return undefined;
|
|
488
414
|
}
|
|
489
415
|
|
|
490
|
-
private
|
|
416
|
+
private _build(prepareResult: IPrepareResult) {
|
|
491
417
|
const emitFileSet = new Set<TNormPath>();
|
|
492
418
|
const diagnostics: ts.Diagnostic[] = [];
|
|
493
419
|
|
|
@@ -507,7 +433,7 @@ export class SdTsCompiler {
|
|
|
507
433
|
|
|
508
434
|
this._debug(`개별 파일 진단 수집 중...`);
|
|
509
435
|
|
|
510
|
-
for (const affectedFile of
|
|
436
|
+
for (const affectedFile of prepareResult.affectedFileSet) {
|
|
511
437
|
if (!PathUtils.isChildPath(affectedFile, this._opt.pkgPath)) continue;
|
|
512
438
|
|
|
513
439
|
const affectedSourceFile = this._program!.getSourceFile(affectedFile);
|
|
@@ -566,7 +492,7 @@ export class SdTsCompiler {
|
|
|
566
492
|
// affected에 새로 추가된 파일은 포함되지 않는 현상이 있어 sourceFileSet으로 바꿈
|
|
567
493
|
// 비교해보니, 딱히 getSourceFiles라서 더 느려지는것 같지는 않음
|
|
568
494
|
// 그래도 affected로 다시 테스트 (조금이라도 더 빠르게)
|
|
569
|
-
for (const affectedFile of
|
|
495
|
+
for (const affectedFile of prepareResult.affectedFileSet) {
|
|
570
496
|
if (this._emittedFilesCacheMap.has(affectedFile)) continue;
|
|
571
497
|
|
|
572
498
|
const sf = this._program!.getSourceFile(affectedFile);
|
|
@@ -584,7 +510,7 @@ export class SdTsCompiler {
|
|
|
584
510
|
sf,
|
|
585
511
|
(fileName, text, writeByteOrderMark, onError, sourceFiles, data) => {
|
|
586
512
|
if (!sourceFiles || sourceFiles.length === 0) {
|
|
587
|
-
|
|
513
|
+
prepareResult.compilerHost.writeFile(
|
|
588
514
|
fileName,
|
|
589
515
|
text,
|
|
590
516
|
writeByteOrderMark,
|
|
@@ -607,7 +533,11 @@ export class SdTsCompiler {
|
|
|
607
533
|
);
|
|
608
534
|
|
|
609
535
|
if (PathUtils.isChildPath(sourceFile.fileName, this._opt.pkgPath)) {
|
|
610
|
-
const real = this._convertOutputToReal(
|
|
536
|
+
const real = this._convertOutputToReal(
|
|
537
|
+
fileName,
|
|
538
|
+
prepareResult.tsconfig.distPath,
|
|
539
|
+
text,
|
|
540
|
+
);
|
|
611
541
|
|
|
612
542
|
emitFileInfoCaches.push({
|
|
613
543
|
outAbsPath: real.filePath,
|
|
@@ -627,37 +557,6 @@ export class SdTsCompiler {
|
|
|
627
557
|
}
|
|
628
558
|
});
|
|
629
559
|
|
|
630
|
-
//-- global style
|
|
631
|
-
if (
|
|
632
|
-
this._opt.globalStyleFilePath != null &&
|
|
633
|
-
FsUtils.exists(this._opt.globalStyleFilePath) &&
|
|
634
|
-
!this._emittedFilesCacheMap.has(this._opt.globalStyleFilePath)
|
|
635
|
-
) {
|
|
636
|
-
this._debug(`전역 스타일 번들링 중...`);
|
|
637
|
-
|
|
638
|
-
await this._perf.run("전역 스타일 번들링", async () => {
|
|
639
|
-
const data = FsUtils.readFile(this._opt.globalStyleFilePath!);
|
|
640
|
-
const stylesheetBundlingResult = await this._bundleStylesheetAsync(
|
|
641
|
-
data,
|
|
642
|
-
this._opt.globalStyleFilePath!,
|
|
643
|
-
this._opt.globalStyleFilePath,
|
|
644
|
-
);
|
|
645
|
-
const emitFileInfos = this._emittedFilesCacheMap.getOrCreate(
|
|
646
|
-
this._opt.globalStyleFilePath!,
|
|
647
|
-
[],
|
|
648
|
-
);
|
|
649
|
-
emitFileInfos.push({
|
|
650
|
-
outAbsPath: PathUtils.norm(
|
|
651
|
-
this._opt.pkgPath,
|
|
652
|
-
path.relative(path.resolve(this._opt.pkgPath, "src"), this._opt.globalStyleFilePath!)
|
|
653
|
-
.replace(/\.scss$/, ".css"),
|
|
654
|
-
),
|
|
655
|
-
text: stylesheetBundlingResult.contents ?? "",
|
|
656
|
-
});
|
|
657
|
-
emitFileSet.add(this._opt.globalStyleFilePath!);
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
|
|
661
560
|
return {
|
|
662
561
|
emitFileSet,
|
|
663
562
|
diagnostics,
|
|
@@ -693,6 +592,12 @@ export class SdTsCompiler {
|
|
|
693
592
|
interface ITsConfigInfo {
|
|
694
593
|
fileNames: string[];
|
|
695
594
|
options: ts.CompilerOptions;
|
|
696
|
-
compilerHost: ts.CompilerHost;
|
|
697
595
|
distPath: string;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
interface IPrepareResult {
|
|
599
|
+
tsconfig: ITsConfigInfo;
|
|
600
|
+
compilerHost: ts.CompilerHost;
|
|
601
|
+
affectedFileSet: Set<TNormPath>;
|
|
602
|
+
watchFileSet: Set<TNormPath>;
|
|
698
603
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { ISdBuildRunnerWorkerRequest } from "./build-runner.types";
|
|
2
2
|
import { ISdBuildMessage, ISdBuildRunnerResult } from "./build.types";
|
|
3
3
|
import { ESLint } from "eslint";
|
|
4
|
+
import { TNormPath } from "@simplysm/sd-core-node";
|
|
5
|
+
import {
|
|
6
|
+
ComponentStylesheetResult,
|
|
7
|
+
} from "@angular/build/src/tools/esbuild/angular/component-stylesheets";
|
|
4
8
|
|
|
5
9
|
export interface TServerWorkerType {
|
|
6
10
|
methods: {
|
|
@@ -35,3 +39,16 @@ export interface TSdBuildRunnerWorkerType {
|
|
|
35
39
|
complete: ISdBuildRunnerResult;
|
|
36
40
|
};
|
|
37
41
|
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export interface TStyleBundlerWorkerType {
|
|
45
|
+
methods: {
|
|
46
|
+
prepare: { params: [string, boolean]; returnType: void },
|
|
47
|
+
bundle: {
|
|
48
|
+
params: [string, TNormPath, TNormPath | null],
|
|
49
|
+
returnType: ComponentStylesheetResult
|
|
50
|
+
},
|
|
51
|
+
invalidate: { params: [Set<TNormPath>], returnType: void }
|
|
52
|
+
};
|
|
53
|
+
events: {};
|
|
54
|
+
}
|