@simplysm/sd-cli 12.8.20 → 12.8.21
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-cordova.d.ts +30 -0
- package/dist/entry/sd-cli-cordova.js +309 -249
- package/dist/entry/sd-cli-cordova.js.map +1 -1
- package/dist/entry/sd-cli-project.d.ts +1 -1
- package/dist/entry/sd-cli-project.js +8 -9
- package/dist/entry/sd-cli-project.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pkg-builders/client/sd-ng.bundler.d.ts +15 -1
- package/dist/pkg-builders/client/sd-ng.bundler.js +60 -70
- package/dist/pkg-builders/client/sd-ng.bundler.js.map +1 -1
- package/dist/pkg-builders/client/sd-ng.plugin-creator.js +49 -29
- package/dist/pkg-builders/client/sd-ng.plugin-creator.js.map +1 -1
- package/dist/pkg-builders/lib/sd-ts-lib.builder.js +7 -4
- package/dist/pkg-builders/lib/sd-ts-lib.builder.js.map +1 -1
- package/dist/ts-compiler/sd-ts-compiler.d.ts +24 -2
- package/dist/ts-compiler/sd-ts-compiler.js +267 -575
- package/dist/ts-compiler/sd-ts-compiler.js.map +1 -1
- package/dist/ts-compiler/sd-ts-dependency-analyzer.d.ts +10 -0
- package/dist/ts-compiler/sd-ts-dependency-analyzer.js +140 -0
- package/dist/ts-compiler/sd-ts-dependency-analyzer.js.map +1 -0
- package/dist/types/ts-compiler.types.d.ts +12 -7
- package/dist/types/worker.types.d.ts +13 -0
- package/dist/utils/sd-cli-performance-time.js +1 -1
- package/package.json +5 -7
- package/src/entry/sd-cli-cordova.ts +394 -281
- package/src/entry/sd-cli-project.ts +11 -23
- package/src/index.ts +1 -0
- package/src/pkg-builders/client/sd-ng.bundler.ts +70 -69
- package/src/pkg-builders/client/sd-ng.plugin-creator.ts +47 -27
- package/src/pkg-builders/lib/sd-ts-lib.builder.ts +14 -7
- package/src/ts-compiler/sd-ts-compiler.ts +334 -705
- package/src/ts-compiler/sd-ts-dependency-analyzer.ts +176 -0
- package/src/types/ts-compiler.types.ts +11 -6
- package/src/types/worker.types.ts +7 -6
- package/src/utils/sd-cli-performance-time.ts +1 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { PathUtils, TNormPath } from "@simplysm/sd-core-node";
|
|
3
|
+
import { ISdBuildMessage } from "../types/build.types";
|
|
4
|
+
import * as module from "node:module";
|
|
5
|
+
import path from "path";
|
|
6
|
+
|
|
7
|
+
export class SdTsDependencyAnalyzer {
|
|
8
|
+
static analyze(
|
|
9
|
+
program: ts.Program,
|
|
10
|
+
compilerHost: ts.CompilerHost,
|
|
11
|
+
scopePaths: TNormPath[],
|
|
12
|
+
) {
|
|
13
|
+
const compilerOpts = program.getCompilerOptions();
|
|
14
|
+
const allDepMap = new Map<TNormPath, Set<TNormPath>>();
|
|
15
|
+
const visited = new Set<TNormPath>();
|
|
16
|
+
const messages: ISdBuildMessage[] = [];
|
|
17
|
+
|
|
18
|
+
const getOrgSourceFile = (sf: ts.SourceFile) => {
|
|
19
|
+
if (sf.fileName.endsWith(".ngtypecheck.ts")) {
|
|
20
|
+
const orgFileName = sf.fileName.slice(0, -15) + ".ts";
|
|
21
|
+
return program.getSourceFile(orgFileName);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return sf;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const inScope = (filePath: string): boolean => {
|
|
28
|
+
return scopePaths.some((scope) => PathUtils.isChildPath(filePath, scope));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const resolveModule = (text: string, base: string): {
|
|
32
|
+
resolvedFileName: string,
|
|
33
|
+
isFallback: boolean
|
|
34
|
+
} | undefined => {
|
|
35
|
+
const res = ts.resolveModuleName(text, base, compilerOpts, compilerHost);
|
|
36
|
+
if (res.resolvedModule) {
|
|
37
|
+
return { resolvedFileName: res.resolvedModule.resolvedFileName, isFallback: false };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const absPath = path.resolve(path.dirname(base), text);
|
|
41
|
+
if (compilerHost.fileExists(absPath)) {
|
|
42
|
+
return { resolvedFileName: absPath, isFallback: true };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return undefined;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const error = (sf: ts.SourceFile, node: ts.Node, msg: string) => {
|
|
49
|
+
try {
|
|
50
|
+
const pos = ts.getLineAndCharacterOfPosition(sf, node.getStart());
|
|
51
|
+
messages.push({
|
|
52
|
+
filePath: PathUtils.norm(sf.fileName),
|
|
53
|
+
line: pos.line,
|
|
54
|
+
char: pos.character,
|
|
55
|
+
code: undefined,
|
|
56
|
+
severity: "error",
|
|
57
|
+
message: msg,
|
|
58
|
+
type: "deps",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
messages.push({
|
|
63
|
+
filePath: PathUtils.norm(sf.fileName),
|
|
64
|
+
line: 0,
|
|
65
|
+
char: 0,
|
|
66
|
+
code: undefined,
|
|
67
|
+
severity: "error",
|
|
68
|
+
message: `${msg} (pos unknown)`,
|
|
69
|
+
type: "deps",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const collectDeps = (sf: ts.SourceFile, fromFile: TNormPath) => {
|
|
75
|
+
if (allDepMap.has(fromFile)) return;
|
|
76
|
+
const deps = new Set<TNormPath>();
|
|
77
|
+
|
|
78
|
+
const pushDep = (raw: string, node: ts.Node) => {
|
|
79
|
+
if (module.builtinModules.includes(raw.replace(/^node:/, ""))) return;
|
|
80
|
+
|
|
81
|
+
const resolved = resolveModule(raw, sf.fileName);
|
|
82
|
+
if (!resolved) {
|
|
83
|
+
error(sf, node, `파일 "${sf.fileName}"에서 "${raw}" 모듈을 해석할 수 없습니다.`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!inScope(resolved.resolvedFileName)) return;
|
|
88
|
+
|
|
89
|
+
const norm = PathUtils.norm(resolved.resolvedFileName);
|
|
90
|
+
deps.add(norm);
|
|
91
|
+
|
|
92
|
+
if (!visited.has(norm) && !resolved.isFallback) {
|
|
93
|
+
visited.add(norm);
|
|
94
|
+
const targetSf = program.getSourceFile(norm);
|
|
95
|
+
if (!targetSf) {
|
|
96
|
+
error(
|
|
97
|
+
sf,
|
|
98
|
+
node,
|
|
99
|
+
`모듈 "${raw}"은(는) "${resolved}" 파일로 해석되었으나, 해당 파일의 ts.SourceFile이 없습니다.`,
|
|
100
|
+
);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
collectDeps(targetSf, norm);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const visit = (node: ts.Node) => {
|
|
109
|
+
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
110
|
+
const spec = node.moduleSpecifier;
|
|
111
|
+
if (spec && ts.isStringLiteral(spec)) pushDep(spec.text, node);
|
|
112
|
+
}
|
|
113
|
+
else if (
|
|
114
|
+
ts.isCallExpression(node) &&
|
|
115
|
+
node.expression.kind === ts.SyntaxKind.ImportKeyword &&
|
|
116
|
+
ts.isStringLiteral(node.arguments[0])
|
|
117
|
+
) {
|
|
118
|
+
pushDep(node.arguments[0].text, node);
|
|
119
|
+
}
|
|
120
|
+
else if (
|
|
121
|
+
ts.isCallExpression(node) &&
|
|
122
|
+
ts.isIdentifier(node.expression) &&
|
|
123
|
+
node.expression.text === "require" &&
|
|
124
|
+
node.arguments.length === 1 &&
|
|
125
|
+
ts.isStringLiteral(node.arguments[0])
|
|
126
|
+
) {
|
|
127
|
+
pushDep(node.arguments[0].text, node);
|
|
128
|
+
}
|
|
129
|
+
else if (
|
|
130
|
+
ts.isCallExpression(node) &&
|
|
131
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
132
|
+
ts.isIdentifier(node.expression.expression) &&
|
|
133
|
+
node.expression.expression.text === "require" &&
|
|
134
|
+
node.expression.name.text === "resolve" &&
|
|
135
|
+
node.arguments.length === 1 &&
|
|
136
|
+
ts.isStringLiteral(node.arguments[0])
|
|
137
|
+
) {
|
|
138
|
+
pushDep(node.arguments[0].text, node);
|
|
139
|
+
}
|
|
140
|
+
else if (
|
|
141
|
+
ts.isCallExpression(node) &&
|
|
142
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
143
|
+
ts.isMetaProperty(node.expression.expression) &&
|
|
144
|
+
node.expression.expression.keywordToken === ts.SyntaxKind.ImportKeyword &&
|
|
145
|
+
node.expression.name.text === "meta" &&
|
|
146
|
+
node.arguments.length === 1 &&
|
|
147
|
+
ts.isStringLiteral(node.arguments[0])
|
|
148
|
+
) {
|
|
149
|
+
pushDep(node.arguments[0].text, node);
|
|
150
|
+
}
|
|
151
|
+
ts.forEachChild(node, visit);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
ts.forEachChild(sf, visit);
|
|
155
|
+
allDepMap.set(fromFile, deps);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const sourceFileSet = new Set(
|
|
159
|
+
program.getSourceFiles()
|
|
160
|
+
.map((sf) => getOrgSourceFile(sf))
|
|
161
|
+
.filterExists()
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
for (const sf of sourceFileSet) {
|
|
165
|
+
if (!inScope(sf.fileName)) continue;
|
|
166
|
+
const normFile = PathUtils.norm(sf.fileName);
|
|
167
|
+
collectDeps(sf, normFile);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
allDepMap,
|
|
172
|
+
sourceFileSet,
|
|
173
|
+
messages,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -18,16 +18,21 @@ export interface SdTsCompilerOptions {
|
|
|
18
18
|
|
|
19
19
|
export interface ISdTsCompilerResult {
|
|
20
20
|
messages: ISdBuildMessage[];
|
|
21
|
-
stylesheetBundlingResultMap: Map<TNormPath,
|
|
21
|
+
stylesheetBundlingResultMap: Map<TNormPath, TStylesheetBundlingResult>;
|
|
22
22
|
emittedFilesCacheMap: Map<TNormPath, { outAbsPath?: TNormPath; text: string }[]>;
|
|
23
23
|
emitFileSet: Set<TNormPath>;
|
|
24
24
|
watchFileSet: Set<TNormPath>;
|
|
25
25
|
affectedFileSet: Set<TNormPath>;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
export type TStylesheetBundlingResult = {
|
|
29
|
+
errors: esbuild.PartialMessage[];
|
|
30
|
+
warnings: esbuild.PartialMessage[];
|
|
31
|
+
contents?: string;
|
|
32
|
+
} | {
|
|
33
|
+
errors: undefined;
|
|
34
|
+
warnings: esbuild.PartialMessage[];
|
|
35
|
+
metafile: esbuild.Metafile;
|
|
36
|
+
outputFiles: esbuild.OutputFile[];
|
|
37
|
+
contents: string;
|
|
33
38
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ISdBuildRunnerWorkerRequest } from "./build-runner.types";
|
|
2
2
|
import { ISdBuildMessage, ISdBuildRunnerResult } from "./build.types";
|
|
3
|
+
import { ESLint } from "eslint";
|
|
3
4
|
|
|
4
5
|
export interface TServerWorkerType {
|
|
5
6
|
methods: {
|
|
@@ -10,12 +11,12 @@ export interface TServerWorkerType {
|
|
|
10
11
|
events: {};
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
export interface TSdLintWorkerType {
|
|
15
|
+
methods: {
|
|
16
|
+
lint: { params: [{ cwd: string; fileSet: Set<string> }]; returnType: ESLint.LintResult[] };
|
|
17
|
+
};
|
|
18
|
+
events: {};
|
|
19
|
+
}
|
|
19
20
|
|
|
20
21
|
// export interface TSdTsCompileWorkerType {
|
|
21
22
|
// methods: {
|
|
@@ -32,7 +32,7 @@ export class SdCliPerformanceTimer {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
toString() {
|
|
35
|
-
return `${this._name}
|
|
35
|
+
return `${this._name} 성능 보고서
|
|
36
36
|
------------------------------------
|
|
37
37
|
${Array.from(this.#resultMap.entries())
|
|
38
38
|
.map((en) => `${en[0]}: ${en[1].toLocaleString()}ms`)
|