@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,33 +1,34 @@
|
|
|
1
1
|
import esbuild from "esbuild";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { FsUtils,
|
|
3
|
+
import { FsUtils, HashUtils, PathUtils, SdLogger, TNormPath } from "@simplysm/sd-core-node";
|
|
4
4
|
import { SdCliConvertMessageUtils } from "../../utils/sd-cli-convert-message.utils";
|
|
5
5
|
import { ISdCliServerPluginResultCache } from "../../types/build-plugin.types";
|
|
6
6
|
import { ISdBuildMessage } from "../../types/build.types";
|
|
7
7
|
import { createSdServerPlugin } from "./sd-server.plugin-creator";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
BuildOutputFile,
|
|
10
|
+
BuildOutputFileType,
|
|
11
|
+
} from "@angular/build/src/tools/esbuild/bundler-context";
|
|
9
12
|
import { convertOutputFile } from "@angular/build/src/tools/esbuild/utils";
|
|
10
13
|
import { resolveAssets } from "@angular/build/src/utils/resolve-assets";
|
|
11
14
|
|
|
12
15
|
export class SdServerBundler {
|
|
13
|
-
|
|
16
|
+
private _logger = SdLogger.get(["simplysm", "sd-cli", "SdServerBundler"]);
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
private _context?: esbuild.BuildContext;
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
private _modifiedFileSet = new Set<TNormPath>();
|
|
21
|
+
private _resultCache: ISdCliServerPluginResultCache = {};
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
private _outputHashCache = new Map<TNormPath, string>();
|
|
21
24
|
|
|
22
|
-
constructor(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
},
|
|
30
|
-
) {
|
|
25
|
+
constructor(private _opt: {
|
|
26
|
+
dev: boolean;
|
|
27
|
+
pkgPath: TNormPath;
|
|
28
|
+
entryPoints: string[];
|
|
29
|
+
external?: string[];
|
|
30
|
+
watchScopePaths: TNormPath[];
|
|
31
|
+
}) {
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
async bundleAsync(modifiedFileSet?: Set<TNormPath>): Promise<{
|
|
@@ -36,13 +37,13 @@ export class SdServerBundler {
|
|
|
36
37
|
results: ISdBuildMessage[];
|
|
37
38
|
emitFileSet: Set<TNormPath>;
|
|
38
39
|
}> {
|
|
39
|
-
this
|
|
40
|
+
this._modifiedFileSet.clear();
|
|
40
41
|
if (modifiedFileSet) {
|
|
41
|
-
this
|
|
42
|
+
this._modifiedFileSet.adds(...modifiedFileSet);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
if (!this
|
|
45
|
-
this
|
|
45
|
+
if (!this._context) {
|
|
46
|
+
this._context = await esbuild.context({
|
|
46
47
|
entryPoints: this._opt.entryPoints,
|
|
47
48
|
keepNames: true,
|
|
48
49
|
bundle: true,
|
|
@@ -103,10 +104,10 @@ const __dirname = __path__.dirname(__filename);`.trim(),
|
|
|
103
104
|
},
|
|
104
105
|
plugins: [
|
|
105
106
|
createSdServerPlugin({
|
|
106
|
-
modifiedFileSet: this
|
|
107
|
+
modifiedFileSet: this._modifiedFileSet,
|
|
107
108
|
dev: this._opt.dev,
|
|
108
109
|
pkgPath: this._opt.pkgPath,
|
|
109
|
-
result: this
|
|
110
|
+
result: this._resultCache,
|
|
110
111
|
watchScopePaths: this._opt.watchScopePaths,
|
|
111
112
|
}),
|
|
112
113
|
],
|
|
@@ -116,17 +117,18 @@ const __dirname = __path__.dirname(__filename);`.trim(),
|
|
|
116
117
|
const emitFileSet = new Set<TNormPath>();
|
|
117
118
|
let result: esbuild.BuildResult | esbuild.BuildFailure;
|
|
118
119
|
try {
|
|
119
|
-
result = await this
|
|
120
|
+
result = await this._context.rebuild();
|
|
120
121
|
|
|
121
122
|
const outputFiles: BuildOutputFile[] =
|
|
122
123
|
result.outputFiles?.map((file) => convertOutputFile(file, BuildOutputFileType.Root)) ?? [];
|
|
123
124
|
|
|
124
125
|
for (const outputFile of outputFiles) {
|
|
125
126
|
const distFilePath = PathUtils.norm(this._opt.pkgPath, outputFile.path);
|
|
126
|
-
const
|
|
127
|
-
|
|
127
|
+
const prevHash = this._outputHashCache.get(distFilePath);
|
|
128
|
+
const currHash = HashUtils.get(outputFile.contents);
|
|
129
|
+
if (prevHash !== currHash) {
|
|
128
130
|
FsUtils.writeFile(distFilePath, outputFile.contents);
|
|
129
|
-
this
|
|
131
|
+
this._outputHashCache.set(distFilePath, currHash);
|
|
130
132
|
emitFileSet.add(distFilePath);
|
|
131
133
|
}
|
|
132
134
|
}
|
|
@@ -141,11 +143,14 @@ const __dirname = __path__.dirname(__filename);`.trim(),
|
|
|
141
143
|
);
|
|
142
144
|
|
|
143
145
|
for (const assetFile of assetFiles) {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
FsUtils.copy(
|
|
148
|
-
|
|
146
|
+
const prevHash = this._outputHashCache.get(PathUtils.norm(assetFile.source));
|
|
147
|
+
const currHash = FsUtils.hash(assetFile.source);
|
|
148
|
+
if (prevHash !== currHash) {
|
|
149
|
+
FsUtils.copy(
|
|
150
|
+
assetFile.source,
|
|
151
|
+
path.resolve(this._opt.pkgPath, "dist", assetFile.destination),
|
|
152
|
+
);
|
|
153
|
+
this._outputHashCache.set(PathUtils.norm(assetFile.source), currHash);
|
|
149
154
|
emitFileSet.add(PathUtils.norm(assetFile.destination));
|
|
150
155
|
}
|
|
151
156
|
}
|
|
@@ -154,15 +159,18 @@ const __dirname = __path__.dirname(__filename);`.trim(),
|
|
|
154
159
|
result = err;
|
|
155
160
|
for (const e of err.errors) {
|
|
156
161
|
if (e.detail != null) {
|
|
157
|
-
this
|
|
162
|
+
this._logger.error(e.detail);
|
|
158
163
|
}
|
|
159
164
|
}
|
|
160
165
|
}
|
|
161
166
|
|
|
162
167
|
return {
|
|
163
|
-
watchFileSet: this
|
|
164
|
-
affectedFileSet: this
|
|
165
|
-
results: SdCliConvertMessageUtils.convertToBuildMessagesFromEsbuild(
|
|
168
|
+
watchFileSet: this._resultCache.watchFileSet!,
|
|
169
|
+
affectedFileSet: this._resultCache.affectedFileSet!,
|
|
170
|
+
results: SdCliConvertMessageUtils.convertToBuildMessagesFromEsbuild(
|
|
171
|
+
result,
|
|
172
|
+
this._opt.pkgPath,
|
|
173
|
+
),
|
|
166
174
|
emitFileSet: emitFileSet,
|
|
167
175
|
};
|
|
168
176
|
}
|
package/src/sd-cli.ts
CHANGED
|
@@ -201,54 +201,25 @@ else {
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
if (argv._[0] === "local-update") {
|
|
204
|
-
await SdCliLocalUpdate.runAsync(
|
|
205
|
-
confFileRelPath: argv.config ?? "simplysm.js",
|
|
206
|
-
optNames: argv.options ?? [],
|
|
207
|
-
});
|
|
204
|
+
await SdCliLocalUpdate.runAsync(argv);
|
|
208
205
|
}
|
|
209
206
|
else if (argv._[0] === "watch") {
|
|
210
|
-
await SdCliProject.watchAsync(
|
|
211
|
-
confFileRelPath: argv.config ?? "simplysm.js",
|
|
212
|
-
optNames: argv.options ?? [],
|
|
213
|
-
pkgNames: argv.packages ?? [],
|
|
214
|
-
inspectNames: argv.inspects ?? [],
|
|
215
|
-
});
|
|
207
|
+
await SdCliProject.watchAsync(argv);
|
|
216
208
|
}
|
|
217
209
|
else if (argv._[0] === "build") {
|
|
218
|
-
await SdCliProject.buildAsync(
|
|
219
|
-
confFileRelPath: argv.config ?? "simplysm.js",
|
|
220
|
-
optNames: argv.options ?? [],
|
|
221
|
-
pkgNames: argv.packages ?? [],
|
|
222
|
-
});
|
|
210
|
+
await SdCliProject.buildAsync(argv);
|
|
223
211
|
}
|
|
224
212
|
else if (argv._[0] === "publish") {
|
|
225
|
-
await SdCliProject.publishAsync(
|
|
226
|
-
noBuild: argv.noBuild,
|
|
227
|
-
confFileRelPath: argv.config ?? "simplysm.js",
|
|
228
|
-
optNames: argv.options ?? [],
|
|
229
|
-
pkgNames: argv.packages ?? [],
|
|
230
|
-
});
|
|
213
|
+
await SdCliProject.publishAsync(argv);
|
|
231
214
|
}
|
|
232
215
|
else if (argv._[0] === "run-electron") {
|
|
233
|
-
await SdCliElectron.runAsync(
|
|
234
|
-
confFileRelPath: argv.config ?? "simplysm.js",
|
|
235
|
-
optNames: argv.options ?? [],
|
|
236
|
-
pkgName: argv.package,
|
|
237
|
-
});
|
|
216
|
+
await SdCliElectron.runAsync(argv);
|
|
238
217
|
}
|
|
239
218
|
else if (argv._[0] === "build-electron-for-dev") {
|
|
240
|
-
await SdCliElectron.buildForDevAsync(
|
|
241
|
-
confFileRelPath: argv.config ?? "simplysm.js",
|
|
242
|
-
optNames: argv.options ?? [],
|
|
243
|
-
pkgName: argv.package,
|
|
244
|
-
});
|
|
219
|
+
await SdCliElectron.buildForDevAsync(argv);
|
|
245
220
|
}
|
|
246
221
|
else if (argv._[0] === "run-cordova") {
|
|
247
|
-
await SdCliCordova.runWebviewOnDeviceAsync(
|
|
248
|
-
platform: argv.platform,
|
|
249
|
-
pkgName: argv.package,
|
|
250
|
-
url: argv.url,
|
|
251
|
-
});
|
|
222
|
+
await SdCliCordova.runWebviewOnDeviceAsync(argv);
|
|
252
223
|
}
|
|
253
224
|
else if (argv._[0] === "commit") {
|
|
254
225
|
await SdCliAiCommand.commitAsync();
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { SdDependencyCache } from "./sd-dependency-cache";
|
|
3
|
+
import { PathUtils, TNormPath } from "@simplysm/sd-core-node";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { NgtscProgram } from "@angular/compiler-cli";
|
|
6
|
+
|
|
7
|
+
export class SdDependencyAnalyzer {
|
|
8
|
+
static analyze(
|
|
9
|
+
program: ts.Program,
|
|
10
|
+
compilerHost: ts.CompilerHost,
|
|
11
|
+
scopePaths: TNormPath[],
|
|
12
|
+
depCache: SdDependencyCache,
|
|
13
|
+
): void {
|
|
14
|
+
const compilerOpts = program.getCompilerOptions();
|
|
15
|
+
const typeChecker = program.getTypeChecker();
|
|
16
|
+
|
|
17
|
+
const inScope = (filePath: string): boolean => {
|
|
18
|
+
return scopePaths.some((scope) => PathUtils.isChildPath(filePath, scope));
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const resolveModule = (text: string, base: string): TNormPath[] => {
|
|
22
|
+
const res = ts.resolveModuleName(
|
|
23
|
+
text,
|
|
24
|
+
base,
|
|
25
|
+
compilerOpts,
|
|
26
|
+
compilerHost,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (res.resolvedModule) {
|
|
30
|
+
return [
|
|
31
|
+
PathUtils.norm(res.resolvedModule.resolvedFileName),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const absPath = path.resolve(path.dirname(base), text);
|
|
36
|
+
if (!inScope(absPath)) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
else if (
|
|
40
|
+
// 지원되게할 .png등이면 그냥 가져오고 (bundling loader에 들어가는것들과 .ts, .json등)
|
|
41
|
+
// fallback일때는 absPath에 .ts, .d.ts, .js, .json 등 다붙여서 가져와야함
|
|
42
|
+
[
|
|
43
|
+
".ts",
|
|
44
|
+
".d.ts",
|
|
45
|
+
".js",
|
|
46
|
+
".json",
|
|
47
|
+
|
|
48
|
+
".html",
|
|
49
|
+
".scss",
|
|
50
|
+
".css",
|
|
51
|
+
|
|
52
|
+
".png",
|
|
53
|
+
".jpeg",
|
|
54
|
+
".jpg",
|
|
55
|
+
".jfif",
|
|
56
|
+
".gif",
|
|
57
|
+
".svg",
|
|
58
|
+
".woff",
|
|
59
|
+
".woff2",
|
|
60
|
+
".ttf",
|
|
61
|
+
".ttc",
|
|
62
|
+
".eot",
|
|
63
|
+
".ico",
|
|
64
|
+
".otf",
|
|
65
|
+
".csv",
|
|
66
|
+
".xlsx",
|
|
67
|
+
".xls",
|
|
68
|
+
".pptx",
|
|
69
|
+
".ppt",
|
|
70
|
+
".docx",
|
|
71
|
+
".doc",
|
|
72
|
+
".zip",
|
|
73
|
+
".pfx",
|
|
74
|
+
".pkl",
|
|
75
|
+
".mp3",
|
|
76
|
+
".ogg",
|
|
77
|
+
].some(ext => absPath.endsWith(ext))
|
|
78
|
+
) {
|
|
79
|
+
return [
|
|
80
|
+
PathUtils.norm(absPath),
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return [
|
|
85
|
+
PathUtils.norm(absPath + ".ts"),
|
|
86
|
+
PathUtils.norm(absPath + ".js"),
|
|
87
|
+
PathUtils.norm(absPath + ".d.ts"),
|
|
88
|
+
PathUtils.norm(absPath + ".json"),
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const isInImportOrExport = (node: ts.Node) => {
|
|
94
|
+
let curr = node as ts.Node | undefined;
|
|
95
|
+
while (curr) {
|
|
96
|
+
if (
|
|
97
|
+
ts.isImportDeclaration(curr) ||
|
|
98
|
+
ts.isExportDeclaration(curr) ||
|
|
99
|
+
ts.isImportSpecifier(curr) ||
|
|
100
|
+
ts.isExportSpecifier(curr) ||
|
|
101
|
+
ts.isNamespaceImport(curr)
|
|
102
|
+
) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
curr = curr.parent;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const typeCache = new WeakMap<ts.Node, ts.Type>();
|
|
111
|
+
|
|
112
|
+
const getCachedType = (node: ts.Node) => {
|
|
113
|
+
if (typeCache.has(node)) return typeCache.get(node);
|
|
114
|
+
const type = typeChecker.getTypeAtLocation(node) as ts.Type | undefined;
|
|
115
|
+
if (type) typeCache.set(node, type);
|
|
116
|
+
return type;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const collectDeps = (sf: ts.SourceFile) => {
|
|
120
|
+
const sfNPath = PathUtils.norm(sf.fileName);
|
|
121
|
+
if (depCache.hasCollected(sfNPath)) return;
|
|
122
|
+
depCache.addCollected(sfNPath);
|
|
123
|
+
|
|
124
|
+
const visit = (node: ts.Node) => {
|
|
125
|
+
// --- import ... from '...'
|
|
126
|
+
if (
|
|
127
|
+
ts.isImportDeclaration(node) &&
|
|
128
|
+
ts.isStringLiteral(node.moduleSpecifier)
|
|
129
|
+
) {
|
|
130
|
+
const resolvedNPaths = resolveModule(node.moduleSpecifier.text, sf.fileName);
|
|
131
|
+
for (const resolvedNPath of resolvedNPaths) {
|
|
132
|
+
if (
|
|
133
|
+
node.importClause &&
|
|
134
|
+
node.importClause.namedBindings &&
|
|
135
|
+
ts.isNamedImports(node.importClause.namedBindings)
|
|
136
|
+
) {
|
|
137
|
+
for (const element of node.importClause.namedBindings.elements) {
|
|
138
|
+
depCache.addImport(
|
|
139
|
+
sfNPath,
|
|
140
|
+
resolvedNPath,
|
|
141
|
+
element.propertyName?.text ?? element.name.text,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
depCache.addImport(sfNPath, resolvedNPath, 0);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// --- export * from '...'
|
|
152
|
+
else if (
|
|
153
|
+
ts.isExportDeclaration(node) &&
|
|
154
|
+
!node.exportClause &&
|
|
155
|
+
node.moduleSpecifier &&
|
|
156
|
+
ts.isStringLiteral(node.moduleSpecifier)
|
|
157
|
+
) {
|
|
158
|
+
const resolvedNPaths = resolveModule(node.moduleSpecifier.text, sf.fileName);
|
|
159
|
+
for (const resolvedNPath of resolvedNPaths) {
|
|
160
|
+
depCache.addReexport(sfNPath, resolvedNPath, 0);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// --- export { A as B } from '...'
|
|
165
|
+
if (
|
|
166
|
+
ts.isExportDeclaration(node) &&
|
|
167
|
+
node.exportClause &&
|
|
168
|
+
ts.isNamedExports(node.exportClause) &&
|
|
169
|
+
node.moduleSpecifier &&
|
|
170
|
+
ts.isStringLiteral(node.moduleSpecifier)
|
|
171
|
+
) {
|
|
172
|
+
const resolvedNPaths = resolveModule(node.moduleSpecifier.text, sf.fileName);
|
|
173
|
+
for (const resolvedNPath of resolvedNPaths) {
|
|
174
|
+
for (const element of node.exportClause.elements) {
|
|
175
|
+
const local = element.propertyName?.text ?? element.name.text;
|
|
176
|
+
const exported = element.name.text;
|
|
177
|
+
depCache.addReexport(sfNPath, resolvedNPath, {
|
|
178
|
+
importSymbol: local,
|
|
179
|
+
exportSymbol: exported,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// --- export const A = ...
|
|
186
|
+
else if (
|
|
187
|
+
ts.isVariableStatement(node) &&
|
|
188
|
+
node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword)
|
|
189
|
+
) {
|
|
190
|
+
for (const decl of node.declarationList.declarations) {
|
|
191
|
+
if (ts.isIdentifier(decl.name)) {
|
|
192
|
+
depCache.addExport(sfNPath, decl.name.text);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// --- export function/class/interface A ...
|
|
198
|
+
else if (
|
|
199
|
+
(
|
|
200
|
+
ts.isFunctionDeclaration(node) ||
|
|
201
|
+
ts.isClassDeclaration(node) ||
|
|
202
|
+
ts.isInterfaceDeclaration(node) ||
|
|
203
|
+
ts.isTypeAliasDeclaration(node) ||
|
|
204
|
+
ts.isEnumDeclaration(node)
|
|
205
|
+
) &&
|
|
206
|
+
node.modifiers?.some(mod => mod.kind === ts.SyntaxKind.ExportKeyword) &&
|
|
207
|
+
node.name
|
|
208
|
+
) {
|
|
209
|
+
depCache.addExport(sfNPath, node.name.text);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
else if (ts.isIdentifier(node) && !isInImportOrExport(node)) {
|
|
213
|
+
const orgValSymbol = typeChecker.getSymbolAtLocation(node);
|
|
214
|
+
|
|
215
|
+
// alias (import된 심볼)일 경우, 원본 심볼로 치환
|
|
216
|
+
const valSymbol = (orgValSymbol && (orgValSymbol.flags & ts.SymbolFlags.Alias))
|
|
217
|
+
? typeChecker.getAliasedSymbol(orgValSymbol)
|
|
218
|
+
: undefined;
|
|
219
|
+
|
|
220
|
+
for (const decl of valSymbol?.getDeclarations() ?? []) {
|
|
221
|
+
const declFile = decl.getSourceFile();
|
|
222
|
+
const declNPath = PathUtils.norm(declFile.fileName);
|
|
223
|
+
if (declNPath !== sfNPath && inScope(declNPath)) {
|
|
224
|
+
depCache.addImport(sfNPath, declNPath, 0);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else if (
|
|
229
|
+
ts.isPropertyAccessExpression(node)
|
|
230
|
+
) {
|
|
231
|
+
const type = getCachedType(node.expression);
|
|
232
|
+
const propSymbol = type?.getProperty(node.name.text);
|
|
233
|
+
|
|
234
|
+
if (propSymbol) {
|
|
235
|
+
for (const decl of propSymbol.getDeclarations() ?? []) {
|
|
236
|
+
const declFile = decl.getSourceFile();
|
|
237
|
+
const declNPath = PathUtils.norm(declFile.fileName);
|
|
238
|
+
if (declNPath !== sfNPath && inScope(declNPath)) {
|
|
239
|
+
depCache.addImport(sfNPath, declNPath, 0);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
else if (
|
|
245
|
+
ts.isElementAccessExpression(node) &&
|
|
246
|
+
ts.isStringLiteral(node.argumentExpression)
|
|
247
|
+
) {
|
|
248
|
+
const type = getCachedType(node.expression);
|
|
249
|
+
const propSymbol = type?.getProperty(node.argumentExpression.text);
|
|
250
|
+
|
|
251
|
+
if (propSymbol) {
|
|
252
|
+
for (const decl of propSymbol.getDeclarations() ?? []) {
|
|
253
|
+
const declFile = decl.getSourceFile();
|
|
254
|
+
const declNPath = PathUtils.norm(declFile.fileName);
|
|
255
|
+
if (declNPath !== sfNPath && inScope(declNPath)) {
|
|
256
|
+
depCache.addImport(sfNPath, declNPath, 0);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
ts.forEachChild(node, visit);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
ts.forEachChild(sf, visit);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const getOrgSourceFile = (sf: ts.SourceFile) => {
|
|
269
|
+
if (sf.fileName.endsWith(".ngtypecheck.ts")) {
|
|
270
|
+
const orgFileName = sf.fileName.slice(0, -15) + ".ts";
|
|
271
|
+
return program.getSourceFile(orgFileName);
|
|
272
|
+
}
|
|
273
|
+
return sf;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const sourceFileSet = new Set(
|
|
277
|
+
program.getSourceFiles()
|
|
278
|
+
.filter((sf) => inScope(sf.fileName))
|
|
279
|
+
.map((sf) => getOrgSourceFile(sf))
|
|
280
|
+
.filterExists(),
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
for (const sf of sourceFileSet) {
|
|
284
|
+
collectDeps(sf);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
static analyzeAngularResources(
|
|
290
|
+
ngProgram: NgtscProgram,
|
|
291
|
+
scopePaths: TNormPath[],
|
|
292
|
+
depCache: SdDependencyCache,
|
|
293
|
+
) {
|
|
294
|
+
const inScope = (filePath: string): boolean => {
|
|
295
|
+
return scopePaths.some((scope) => PathUtils.isChildPath(filePath, scope));
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
for (const sf of ngProgram.getTsProgram().getSourceFiles()) {
|
|
299
|
+
const fileNPath = PathUtils.norm(sf.fileName);
|
|
300
|
+
if (!inScope(fileNPath)) continue;
|
|
301
|
+
|
|
302
|
+
const dependencies = ngProgram.compiler.getResourceDependencies(sf);
|
|
303
|
+
for (const dep of dependencies) {
|
|
304
|
+
const depNPath = PathUtils.norm(dep);
|
|
305
|
+
if (!inScope(depNPath)) continue;
|
|
306
|
+
|
|
307
|
+
console.log(fileNPath, depNPath);
|
|
308
|
+
depCache.addImport(fileNPath, depNPath, 0);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|