@simplysm/sd-cli 6.0.26 → 6.0.30
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-node/bin/sd-cli.js +19 -4
- package/dist-node/bin/sd-cli.js.map +1 -1
- package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js +102 -49
- package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js.map +1 -1
- package/dist-node/build-tools/metadata/SdAotMetadataReader.js +6 -2
- package/dist-node/build-tools/metadata/SdAotMetadataReader.js.map +1 -1
- package/dist-node/build-tools/metadata/SdIvyMetadataReader.js +22 -5
- package/dist-node/build-tools/metadata/SdIvyMetadataReader.js.map +1 -1
- package/dist-node/build-tools/metadata/SdMetadataError.js +13 -0
- package/dist-node/build-tools/metadata/SdMetadataError.js.map +1 -0
- package/dist-node/build-tools/metadata/SdMyMetadataReader.js +22 -5
- package/dist-node/build-tools/metadata/SdMyMetadataReader.js.map +1 -1
- package/dist-node/builders/SdCliNgClientBuilder.js +73 -66
- package/dist-node/builders/SdCliNgClientBuilder.js.map +1 -1
- package/dist-node/builders/SdCliNgLibraryBuilder.js +52 -24
- package/dist-node/builders/SdCliNgLibraryBuilder.js.map +1 -1
- package/dist-node/builders/SdCliServerBuilder.js +45 -44
- package/dist-node/builders/SdCliServerBuilder.js.map +1 -1
- package/dist-node/builders/SdCliTypescriptBuilder.js +64 -59
- package/dist-node/builders/SdCliTypescriptBuilder.js.map +1 -1
- package/dist-node/entry-points/SdCliLocalUpdater.js +30 -29
- package/dist-node/entry-points/SdCliLocalUpdater.js.map +1 -1
- package/dist-node/entry-points/SdCliProject.js +10 -16
- package/dist-node/entry-points/SdCliProject.js.map +1 -1
- package/dist-node/packages/SdCliClientPackage.js +4 -3
- package/dist-node/packages/SdCliClientPackage.js.map +1 -1
- package/dist-node/packages/SdCliLibraryPackage.js +3 -2
- package/dist-node/packages/SdCliLibraryPackage.js.map +1 -1
- package/dist-node/packages/SdCliServerPackage.js +4 -3
- package/dist-node/packages/SdCliServerPackage.js.map +1 -1
- package/dist-node/utils/SdProjectConfigUtil.js +1 -1
- package/dist-node/utils/SdProjectConfigUtil.js.map +1 -1
- package/dist-node/utils/SdWebpackUtil.js +33 -13
- package/dist-node/utils/SdWebpackUtil.js.map +1 -1
- package/dist-node/workers/client-ng-gen-worker.js +54 -0
- package/dist-node/workers/client-ng-gen-worker.js.map +1 -0
- package/dist-node/workers/lib-build-worker.js +7 -6
- package/dist-node/workers/lib-build-worker.js.map +1 -1
- package/dist-types/build-tools/metadata/SdIvyMetadataReader.d.ts +1 -0
- package/dist-types/build-tools/metadata/SdMetadataError.d.ts +6 -0
- package/dist-types/build-tools/metadata/SdMyMetadataReader.d.ts +1 -0
- package/dist-types/builders/SdCliNgClientBuilder.d.ts +6 -2
- package/dist-types/builders/SdCliNgLibraryBuilder.d.ts +3 -1
- package/dist-types/builders/SdCliServerBuilder.d.ts +2 -1
- package/dist-types/builders/SdCliTypescriptBuilder.d.ts +5 -5
- package/dist-types/commons.d.ts +3 -1
- package/dist-types/entry-points/SdCliLocalUpdater.d.ts +1 -1
- package/dist-types/entry-points/SdCliProject.d.ts +2 -0
- package/dist-types/packages/SdCliClientPackage.d.ts +2 -1
- package/dist-types/packages/SdCliLibraryPackage.d.ts +2 -1
- package/dist-types/packages/SdCliServerPackage.d.ts +2 -1
- package/dist-types/utils/SdWebpackUtil.d.ts +1 -1
- package/dist-types/workers/client-ng-gen-worker.d.ts +1 -0
- package/package.json +7 -7
- package/schema/schema.json +185 -122
- package/sd-tsconfig.node.json +2 -1
- package/src/bin/sd-cli.ts +19 -4
- package/src/build-tools/SdCliNgModuleFilesGenerator.ts +118 -60
- package/src/build-tools/metadata/SdAotMetadataReader.ts +8 -2
- package/src/build-tools/metadata/SdIvyMetadataReader.ts +27 -4
- package/src/build-tools/metadata/SdMetadataError.ts +7 -0
- package/src/build-tools/metadata/SdMyMetadataReader.ts +25 -3
- package/src/builders/SdCliNgClientBuilder.ts +122 -58
- package/src/builders/SdCliNgLibraryBuilder.ts +102 -43
- package/src/builders/SdCliServerBuilder.ts +61 -44
- package/src/builders/SdCliTypescriptBuilder.ts +92 -73
- package/src/commons.ts +1 -1
- package/src/entry-points/SdCliLocalUpdater.ts +40 -33
- package/src/entry-points/SdCliProject.ts +14 -13
- package/src/packages/SdCliClientPackage.ts +3 -2
- package/src/packages/SdCliLibraryPackage.ts +2 -1
- package/src/packages/SdCliServerPackage.ts +4 -3
- package/src/utils/SdCliFileCrypto.ts +1 -1
- package/src/utils/SdProjectConfigUtil.ts +1 -1
- package/src/utils/SdWebpackUtil.ts +42 -22
- package/src/workers/client-ng-gen-worker.ts +60 -0
- package/src/workers/lib-build-worker.ts +7 -6
- package/tsconfig.json +2 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
2
|
import { INpmConfig, ISdPackageBuildResult, ISdServerPackageConfig, ITsconfig } from "../commons";
|
|
3
3
|
import * as ts from "typescript";
|
|
4
|
-
import { FsUtil,
|
|
4
|
+
import { FsUtil, PathUtil } from "@simplysm/sd-core-node";
|
|
5
5
|
import { ObjectUtil, StringUtil, Wait } from "@simplysm/sd-core-common";
|
|
6
6
|
import * as webpack from "webpack";
|
|
7
7
|
import * as path from "path";
|
|
@@ -27,7 +27,8 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
27
27
|
public constructor(public rootPath: string,
|
|
28
28
|
public tsconfigFilePath: string,
|
|
29
29
|
public projectRootPath: string,
|
|
30
|
-
public config: ISdServerPackageConfig
|
|
30
|
+
public config: ISdServerPackageConfig,
|
|
31
|
+
public useCache: boolean) {
|
|
31
32
|
super();
|
|
32
33
|
|
|
33
34
|
const tsconfig: ITsconfig = FsUtil.readJson(this.tsconfigFilePath);
|
|
@@ -93,13 +94,19 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
93
94
|
...this.config.env ? this.config.env : {}
|
|
94
95
|
}
|
|
95
96
|
},
|
|
96
|
-
(typeof this.config.pm2 !== "boolean") ? this.config.pm2 : {}
|
|
97
|
+
(typeof this.config.pm2 !== "boolean") ? this.config.pm2 : {},
|
|
98
|
+
{
|
|
99
|
+
arrayProcess: "concat"
|
|
100
|
+
}
|
|
97
101
|
), undefined, 2));
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
// iis 파일 쓰기
|
|
101
|
-
if (this.config.iis) {
|
|
105
|
+
if (this.config.iis !== undefined && this.config.iis !== false) {
|
|
102
106
|
const iisDistPath = path.resolve(this.parsedTsconfig.options.outDir!, "web.config");
|
|
107
|
+
const serverExeFilePath = (this.config.iis !== true && "serverExeFilePath" in this.config.iis)
|
|
108
|
+
? (this.config.iis.serverExeFilePath ?? "C:\\Program Files\\nodejs\\node.exe")
|
|
109
|
+
: "C:\\Program Files\\nodejs\\node.exe";
|
|
103
110
|
await FsUtil.writeFileAsync(iisDistPath, `
|
|
104
111
|
<configuration>
|
|
105
112
|
<system.webServer>
|
|
@@ -107,7 +114,10 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
107
114
|
<handlers>
|
|
108
115
|
<add name="iisnode" path="main.js" verb="*" modules="iisnode" />
|
|
109
116
|
</handlers>
|
|
110
|
-
<iisnode nodeProcessCommandLine="
|
|
117
|
+
<iisnode nodeProcessCommandLine="${serverExeFilePath}"
|
|
118
|
+
watchedFiles="web.config;*.js"
|
|
119
|
+
loggingEnabled="true"
|
|
120
|
+
devErrorsEnabled="true" />
|
|
111
121
|
<rewrite>
|
|
112
122
|
<rules>
|
|
113
123
|
<rule name="main">
|
|
@@ -115,9 +125,10 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
115
125
|
</rule>
|
|
116
126
|
</rules>
|
|
117
127
|
</rewrite>
|
|
118
|
-
<httpErrors errorMode="Detailed" />
|
|
128
|
+
<httpErrors errorMode="Detailed" />
|
|
119
129
|
</system.webServer>
|
|
120
130
|
</configuration>
|
|
131
|
+
|
|
121
132
|
`.trim());
|
|
122
133
|
}
|
|
123
134
|
|
|
@@ -133,12 +144,6 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
133
144
|
|
|
134
145
|
await FsUtil.writeFileAsync(path.resolve(this.parsedTsconfig.options.outDir!, "package.json"), JSON.stringify(distNpmConfig, undefined, 2));
|
|
135
146
|
|
|
136
|
-
// CopyWebpackPlugin 대신 직접 카피
|
|
137
|
-
|
|
138
|
-
for (const item of ["assets/"]) {
|
|
139
|
-
await FsUtil.copyAsync(path.resolve(this.rootPath, "src", item), path.resolve(this.parsedTsconfig.options.outDir!, item));
|
|
140
|
-
}
|
|
141
|
-
|
|
142
147
|
this.emit("complete", buildResults);
|
|
143
148
|
}
|
|
144
149
|
|
|
@@ -148,7 +153,6 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
148
153
|
const externalModuleNames = this._findExternalModuleNames(true);
|
|
149
154
|
|
|
150
155
|
// 빌드
|
|
151
|
-
|
|
152
156
|
const webpackConfig = this._getWebpackConfig(true, externalModuleNames);
|
|
153
157
|
const compiler = webpack(webpackConfig);
|
|
154
158
|
await new Promise<void>((resolve, reject) => {
|
|
@@ -209,9 +213,9 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
209
213
|
|
|
210
214
|
const mainFilePath = path.resolve(this.parsedTsconfig.options.outDir!, "main.js");
|
|
211
215
|
|
|
212
|
-
const prevLoggerConfigs = ObjectUtil.clone(Logger.configs);
|
|
216
|
+
// const prevLoggerConfigs = ObjectUtil.clone(Logger.configs);
|
|
213
217
|
this._server = require(mainFilePath) as SdServiceServer | undefined;
|
|
214
|
-
Logger.configs = prevLoggerConfigs;
|
|
218
|
+
// Logger.configs = prevLoggerConfigs;
|
|
215
219
|
|
|
216
220
|
if (!this._server) {
|
|
217
221
|
throw new Error(`${mainFilePath}(0, 0): 'SdServiceServer'를 'export'해야 합니다.`);
|
|
@@ -234,16 +238,16 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
234
238
|
resolve: {
|
|
235
239
|
extensions: [".ts", ".tsx", ".js"],
|
|
236
240
|
symlinks: true,
|
|
237
|
-
modules: [this.projectRootPath, "node_modules"],
|
|
241
|
+
// modules: [this.projectRootPath, "node_modules"],
|
|
238
242
|
mainFields: ["es2020", "main", "module"]
|
|
239
243
|
},
|
|
240
|
-
resolveLoader: {
|
|
244
|
+
/*resolveLoader: {
|
|
241
245
|
symlinks: true,
|
|
242
246
|
modules: [
|
|
243
247
|
"node_modules",
|
|
244
248
|
...this._findAllNodeModules(__dirname, this.projectRootPath)
|
|
245
249
|
]
|
|
246
|
-
}
|
|
250
|
+
},*/
|
|
247
251
|
context: this.projectRootPath,
|
|
248
252
|
entry: {
|
|
249
253
|
main: [
|
|
@@ -258,6 +262,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
258
262
|
// chunkFilename: watch ? "[name].js" : "[name].[chunkhash:20].js",
|
|
259
263
|
filename: "[name].js",
|
|
260
264
|
chunkFilename: "[name].js",
|
|
265
|
+
assetModuleFilename: "resources/[name][ext][query]",
|
|
261
266
|
libraryTarget: watch ? "umd" : "commonjs"
|
|
262
267
|
},
|
|
263
268
|
performance: { hints: false },
|
|
@@ -286,10 +291,14 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
286
291
|
return `${msg.file}(${msg.line}, ${msg.character}): ${msg.code}: ${msg.severity} ${msg.content}`;
|
|
287
292
|
}
|
|
288
293
|
}
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico|otf|xlsx?|pptx?|docx?|zip|pfx|pkl)$/,
|
|
297
|
+
type: "asset/resource"
|
|
289
298
|
}
|
|
290
299
|
]
|
|
291
300
|
},
|
|
292
|
-
cache: watch ? { type: "memory", maxGenerations: 1 } : false,
|
|
301
|
+
cache: (watch && this.useCache) ? { type: "memory", maxGenerations: 1 } : false,
|
|
293
302
|
optimization: {
|
|
294
303
|
minimizer: watch ? [] : [
|
|
295
304
|
new JavaScriptOptimizerPlugin({
|
|
@@ -302,7 +311,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
302
311
|
],
|
|
303
312
|
moduleIds: "deterministic",
|
|
304
313
|
chunkIds: watch ? "named" : "deterministic",
|
|
305
|
-
emitOnErrors:
|
|
314
|
+
emitOnErrors: watch
|
|
306
315
|
},
|
|
307
316
|
plugins: [
|
|
308
317
|
new DedupeModuleResolvePlugin({ verbose: false }) as any,
|
|
@@ -314,30 +323,29 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
314
323
|
skipChildCompilers: true
|
|
315
324
|
})
|
|
316
325
|
],
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
] : [],
|
|
326
|
+
new CopyWebpackPlugin({
|
|
327
|
+
patterns: ["assets/"].map((item) => ({
|
|
328
|
+
context: this.rootPath,
|
|
329
|
+
to: item,
|
|
330
|
+
from: `src/${item}`,
|
|
331
|
+
noErrorOnMissing: true,
|
|
332
|
+
force: true,
|
|
333
|
+
globOptions: {
|
|
334
|
+
dot: true,
|
|
335
|
+
followSymbolicLinks: false,
|
|
336
|
+
ignore: [
|
|
337
|
+
".gitkeep",
|
|
338
|
+
"**/.DS_Store",
|
|
339
|
+
"**/Thumbs.db"
|
|
340
|
+
].map((i) => PathUtil.posix(this.rootPath, i))
|
|
341
|
+
},
|
|
342
|
+
priority: 0
|
|
343
|
+
}))
|
|
344
|
+
}),
|
|
345
|
+
new webpack.EnvironmentPlugin({
|
|
346
|
+
SD_VERSION: this._getNpmConfig(this.rootPath)!.version,
|
|
347
|
+
...this.config.env
|
|
348
|
+
}),
|
|
341
349
|
new ESLintWebpackPlugin({
|
|
342
350
|
context: this.rootPath,
|
|
343
351
|
eslintPath: path.resolve(this.projectRootPath, "node_modules", "eslint"),
|
|
@@ -365,6 +373,15 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
365
373
|
};
|
|
366
374
|
}
|
|
367
375
|
|
|
376
|
+
/*private _findAllInternalModuleCachePaths(): string[] {
|
|
377
|
+
return this._findAllNodeModules(this.rootPath, this.projectRootPath)
|
|
378
|
+
.mapMany((item) => (
|
|
379
|
+
FsUtil.readdir(item)
|
|
380
|
+
.filter((item1) => !item1.startsWith("@simplysm"))
|
|
381
|
+
.map((item1) => path.resolve(item, item1))
|
|
382
|
+
));
|
|
383
|
+
}*/
|
|
384
|
+
|
|
368
385
|
private _findAllNodeModules(from: string, root: string): string[] {
|
|
369
386
|
const nodeModules: string[] = [];
|
|
370
387
|
|
|
@@ -13,30 +13,29 @@ import { ParserOptions } from "@typescript-eslint/types";
|
|
|
13
13
|
export class SdCliTypescriptBuilder extends EventEmitter {
|
|
14
14
|
protected readonly _logger: Logger;
|
|
15
15
|
|
|
16
|
-
protected
|
|
16
|
+
protected _tsconfig: ITsconfig;
|
|
17
17
|
public readonly npmConfig: INpmConfig;
|
|
18
18
|
|
|
19
19
|
protected _moduleResolutionCache?: ts.ModuleResolutionCache;
|
|
20
20
|
protected _cacheCompilerHost?: ts.CompilerHost;
|
|
21
21
|
protected _program?: ts.Program;
|
|
22
|
-
protected _builder?: ts.BuilderProgram | ts.
|
|
22
|
+
protected _builder?: ts.BuilderProgram | ts.SemanticDiagnosticsBuilderProgram;
|
|
23
23
|
protected readonly _fileCache = new Map<string, ITsBuildFileCache>();
|
|
24
24
|
|
|
25
25
|
private readonly _indexFileGenerator?: SdCliIndexFileGenerator;
|
|
26
26
|
|
|
27
27
|
private _watcher?: SdFsWatcher;
|
|
28
28
|
|
|
29
|
-
public
|
|
29
|
+
public skipProcesses: string[];
|
|
30
30
|
|
|
31
31
|
public constructor(public rootPath: string,
|
|
32
32
|
public tsconfigFilePath: string,
|
|
33
|
-
|
|
33
|
+
skipProcesses: ("emit" | "check" | "lint" | "genIndex")[],
|
|
34
34
|
public autoIndexConfig: ISdAutoIndexConfig | undefined) {
|
|
35
35
|
super();
|
|
36
|
-
this.
|
|
36
|
+
this.skipProcesses = skipProcesses;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
this._parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this.rootPath);
|
|
38
|
+
this._tsconfig = FsUtil.readJson(this.tsconfigFilePath);
|
|
40
39
|
|
|
41
40
|
this.npmConfig = FsUtil.readJson(path.resolve(this.rootPath, "package.json"));
|
|
42
41
|
this._logger = Logger.get(["simplysm", "sd-cli", this.constructor.name, this.npmConfig.name]);
|
|
@@ -55,10 +54,12 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
55
54
|
public async buildAsync(watch: boolean): Promise<void> {
|
|
56
55
|
this.emit("change");
|
|
57
56
|
|
|
57
|
+
const parsedTsconfig = ts.parseJsonConfigFileContent(this._tsconfig, ts.sys, this.rootPath);
|
|
58
|
+
|
|
58
59
|
// DIST 비우기
|
|
59
|
-
await FsUtil.removeAsync(
|
|
60
|
-
if (
|
|
61
|
-
await FsUtil.removeAsync(
|
|
60
|
+
await FsUtil.removeAsync(parsedTsconfig.options.outDir!);
|
|
61
|
+
if (parsedTsconfig.options.declarationDir !== undefined) {
|
|
62
|
+
await FsUtil.removeAsync(parsedTsconfig.options.declarationDir);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
// 프로그램 리로드
|
|
@@ -163,7 +164,7 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
163
164
|
|
|
164
165
|
const result: ITsGenResult = { dirtyFilePaths: [], result: [] };
|
|
165
166
|
|
|
166
|
-
if (!this.
|
|
167
|
+
if (!this.skipProcesses.includes("genIndex") && this._indexFileGenerator && this.autoIndexConfig) {
|
|
167
168
|
const generateResult = await this._indexFileGenerator.generateAsync();
|
|
168
169
|
result.result.push(...generateResult.result);
|
|
169
170
|
if (generateResult.changed) {
|
|
@@ -192,54 +193,58 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
protected async _lintAsync(dirtyFilePaths: string[]): Promise<ISdPackageBuildResult[]> {
|
|
195
|
-
this.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
196
|
+
if (!this.skipProcesses.includes("lint")) {
|
|
197
|
+
this._logger.debug("LINT");
|
|
198
|
+
|
|
199
|
+
const linter = new ESLint({
|
|
200
|
+
overrideConfig: {
|
|
201
|
+
overrides: [
|
|
202
|
+
{
|
|
203
|
+
files: ["*.ts"],
|
|
204
|
+
parserOptions: {
|
|
205
|
+
program: this._program
|
|
206
|
+
} as ParserOptions,
|
|
207
|
+
settings: {
|
|
208
|
+
"import/resolver": {
|
|
209
|
+
typescript: {
|
|
210
|
+
project: this.tsconfigFilePath
|
|
211
|
+
}
|
|
209
212
|
}
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
const filePaths = await dirtyFilePaths
|
|
218
|
-
.filterAsync(async (item) => (
|
|
219
|
-
!item.includes("node_modules")
|
|
220
|
-
&& PathUtil.isChildPath(item, this.rootPath)
|
|
221
|
-
&& FsUtil.exists(item)
|
|
222
|
-
&& !FsUtil.isDirectory(item)
|
|
223
|
-
&& !await linter.isPathIgnored(item)
|
|
224
|
-
));
|
|
225
|
-
|
|
226
|
-
const lintResults = await linter.lintFiles(filePaths);
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
});
|
|
227
218
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
219
|
+
const filePaths = await dirtyFilePaths
|
|
220
|
+
.filterAsync(async (item) => (
|
|
221
|
+
!item.includes("node_modules")
|
|
222
|
+
&& PathUtil.isChildPath(item, this.rootPath)
|
|
223
|
+
&& FsUtil.exists(item)
|
|
224
|
+
&& !FsUtil.isDirectory(item)
|
|
225
|
+
&& !await linter.isPathIgnored(item)
|
|
226
|
+
));
|
|
227
|
+
|
|
228
|
+
const lintResults = await linter.lintFiles(filePaths);
|
|
229
|
+
|
|
230
|
+
const result = lintResults.mapMany((report) => (
|
|
231
|
+
report.messages.map((msg) => {
|
|
232
|
+
const severity: "warning" | "error" = msg.severity === 1 ? "warning" : "error";
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
filePath: report.filePath,
|
|
236
|
+
severity,
|
|
237
|
+
message: `${report.filePath}(${msg.line}, ${msg.column}): ${msg.ruleId ?? ""}: ${severity} ${msg.message}`
|
|
238
|
+
};
|
|
239
|
+
})
|
|
240
|
+
));
|
|
231
241
|
|
|
232
|
-
|
|
233
|
-
filePath: report.filePath,
|
|
234
|
-
severity,
|
|
235
|
-
message: `${report.filePath}(${msg.line}, ${msg.column}): ${msg.ruleId ?? ""}: ${severity} ${msg.message}`
|
|
236
|
-
};
|
|
237
|
-
})
|
|
238
|
-
));
|
|
242
|
+
this._logger.debug("LINT 결과", result);
|
|
239
243
|
|
|
240
|
-
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
241
246
|
|
|
242
|
-
return
|
|
247
|
+
return [];
|
|
243
248
|
}
|
|
244
249
|
|
|
245
250
|
/*protected _getAllDependencies(filePath: string): string[] {
|
|
@@ -257,10 +262,10 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
257
262
|
}*/
|
|
258
263
|
|
|
259
264
|
public getWatchPaths(): string[] {
|
|
260
|
-
const builder = this._builder as ts.
|
|
265
|
+
// const builder = this._builder as ts.SemanticDiagnosticsBuilderProgram;
|
|
261
266
|
|
|
262
267
|
const result: string[] = [];
|
|
263
|
-
for (const sourceFile of
|
|
268
|
+
for (const sourceFile of this._builder!.getSourceFiles()) {
|
|
264
269
|
// result.push(sourceFile.fileName, ...this._getAllDependencies(sourceFile.fileName));
|
|
265
270
|
result.push(sourceFile.fileName);
|
|
266
271
|
}
|
|
@@ -295,15 +300,16 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
295
300
|
|
|
296
301
|
const diagnostics: ts.Diagnostic[] = [];
|
|
297
302
|
|
|
298
|
-
if (!this.
|
|
303
|
+
if (!this.skipProcesses.includes("check")) {
|
|
299
304
|
diagnostics.push(
|
|
300
305
|
...this._builder.getOptionsDiagnostics(),
|
|
301
306
|
...this._builder.getGlobalDiagnostics()
|
|
302
307
|
);
|
|
303
308
|
|
|
304
|
-
for (const
|
|
305
|
-
const
|
|
306
|
-
|
|
309
|
+
for (const sourceFile of this._builder.getSourceFiles()) {
|
|
310
|
+
/*for (const dirtyFilePath of dirtyFilePaths) {
|
|
311
|
+
const sourceFile = this._builder.getSourceFile(dirtyFilePath);
|
|
312
|
+
if (!sourceFile) continue;*/
|
|
307
313
|
|
|
308
314
|
if (sourceFile.isDeclarationFile) continue;
|
|
309
315
|
|
|
@@ -314,7 +320,7 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
314
320
|
}
|
|
315
321
|
}
|
|
316
322
|
|
|
317
|
-
if (!this.
|
|
323
|
+
if (!this.skipProcesses.includes("emit")) {
|
|
318
324
|
for (const dirtyFilePath of dirtyFilePaths) {
|
|
319
325
|
const sourceFile = this._builder.getSourceFile(dirtyFilePath);
|
|
320
326
|
if (!sourceFile) continue;
|
|
@@ -347,8 +353,8 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
347
353
|
this._reloadWatchPaths();
|
|
348
354
|
}
|
|
349
355
|
|
|
350
|
-
dirtyFilePaths.push(...changedFilePaths.filter((key) => this._fileCache.has(key)));
|
|
351
|
-
dirtyFilePaths.distinctThis()
|
|
356
|
+
/*dirtyFilePaths.push(...changedFilePaths.filter((key) => this._fileCache.has(key)));
|
|
357
|
+
dirtyFilePaths.distinctThis();*/
|
|
352
358
|
|
|
353
359
|
this._logger.debug("변경 프로그램 리로드 결과", dirtyFilePaths);
|
|
354
360
|
return dirtyFilePaths;
|
|
@@ -357,12 +363,14 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
357
363
|
public async reloadProgramAsync(watch: boolean): Promise<string[]> {
|
|
358
364
|
this._logger.debug("프로그램 리로드");
|
|
359
365
|
|
|
360
|
-
|
|
361
|
-
|
|
366
|
+
const parsedTsconfig = ts.parseJsonConfigFileContent(this._tsconfig, ts.sys, this.rootPath);
|
|
367
|
+
|
|
368
|
+
this._moduleResolutionCache = ts.createModuleResolutionCache(this.rootPath, (s) => s, parsedTsconfig.options);
|
|
369
|
+
this._cacheCompilerHost = await this._createCacheCompilerHostAsync(parsedTsconfig, this._moduleResolutionCache);
|
|
362
370
|
|
|
363
371
|
this._program = ts.createProgram(
|
|
364
|
-
|
|
365
|
-
|
|
372
|
+
parsedTsconfig.fileNames,
|
|
373
|
+
parsedTsconfig.options,
|
|
366
374
|
this._cacheCompilerHost,
|
|
367
375
|
this._program
|
|
368
376
|
);
|
|
@@ -381,12 +389,21 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
381
389
|
};
|
|
382
390
|
|
|
383
391
|
if (watch) {
|
|
384
|
-
|
|
385
|
-
this.
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
392
|
+
if (this.skipProcesses.includes("emit")) {
|
|
393
|
+
this._builder = ts.createSemanticDiagnosticsBuilderProgram(
|
|
394
|
+
this._program,
|
|
395
|
+
this._cacheCompilerHost,
|
|
396
|
+
this._builder as ts.SemanticDiagnosticsBuilderProgram
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
this._builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(
|
|
401
|
+
this._program,
|
|
402
|
+
this._cacheCompilerHost,
|
|
403
|
+
this._builder as ts.EmitAndSemanticDiagnosticsBuilderProgram
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
const builder = this._builder as ts.SemanticDiagnosticsBuilderProgram;
|
|
390
407
|
|
|
391
408
|
const affectedFilePaths: string[] = [];
|
|
392
409
|
while (true) {
|
|
@@ -417,7 +434,7 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
417
434
|
|
|
418
435
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
419
436
|
protected async _createCacheCompilerHostAsync(parsedTsconfig: ts.ParsedCommandLine, moduleResolutionCache: ts.ModuleResolutionCache): Promise<ts.CompilerHost> {
|
|
420
|
-
const compilerHost = ts.
|
|
437
|
+
const compilerHost = ts.createIncrementalCompilerHost(parsedTsconfig.options);
|
|
421
438
|
|
|
422
439
|
const cacheCompilerHost = { ...compilerHost };
|
|
423
440
|
cacheCompilerHost.fileExists = (fileName: string) => {
|
|
@@ -448,7 +465,9 @@ export class SdCliTypescriptBuilder extends EventEmitter {
|
|
|
448
465
|
});
|
|
449
466
|
}
|
|
450
467
|
|
|
451
|
-
|
|
468
|
+
if (!FsUtil.exists(fileName) || FsUtil.readFile(fileName) !== data) {
|
|
469
|
+
compilerHost.writeFile.call(cacheCompilerHost, fileName, data, writeByteOrderMark, onError, sourceFiles);
|
|
470
|
+
}
|
|
452
471
|
};
|
|
453
472
|
|
|
454
473
|
cacheCompilerHost.readFile = (fileName: string) => {
|
package/src/commons.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FsUtil, Logger, SdFsWatcher } from "@simplysm/sd-core-node";
|
|
1
|
+
import { FsUtil, Logger, PathUtil, SdFsWatcher } from "@simplysm/sd-core-node";
|
|
2
2
|
import { SdProjectConfigUtil } from "../utils/SdProjectConfigUtil";
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
|
|
@@ -13,46 +13,53 @@ export class SdCliLocalUpdater {
|
|
|
13
13
|
const config = await SdProjectConfigUtil.loadConfigAsync(this._rootPath, watch, undefined, opt?.config);
|
|
14
14
|
|
|
15
15
|
if (config.localUpdates) {
|
|
16
|
-
const updatePathInfos = await this.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
16
|
+
const updatePathInfos = await this._getUpdatePathInfosAsync(config.localUpdates);
|
|
17
|
+
|
|
18
|
+
if (watch) {
|
|
19
|
+
const watchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
20
|
+
|
|
21
|
+
const watcher = new SdFsWatcher();
|
|
22
|
+
watcher
|
|
23
|
+
.onChange(async (changedInfos) => {
|
|
24
|
+
this._logger.log("로컬 라이브러리 변경감지...");
|
|
25
|
+
|
|
26
|
+
const watchPaths2 = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
27
|
+
watcher.replaceWatchPaths(watchPaths2);
|
|
28
|
+
|
|
29
|
+
const changedFilePaths = changedInfos.map((item) => item.filePath).distinct();
|
|
30
|
+
for (const changedFilePath of changedFilePaths) {
|
|
31
|
+
if (changedFilePath.includes("node_modules") || changedFilePath.endsWith("package.json")) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const currentUpdatePathInfos = updatePathInfos.filter((item) => PathUtil.isChildPath(changedFilePath, item.source));
|
|
36
|
+
const targetFilePaths = currentUpdatePathInfos.map((item) => path.resolve(item.target, path.relative(item.source, changedFilePath)));
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
if (FsUtil.exists(changedFilePath)) {
|
|
39
|
+
this._logger.debug(`변경파일감지(복사): ${changedFilePath}`);
|
|
40
|
+
for (const targetFilePath of targetFilePaths) {
|
|
39
41
|
await FsUtil.copyAsync(changedFilePath, targetFilePath);
|
|
40
42
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
}
|
|
44
|
+
/*else {
|
|
45
|
+
this._logger.debug(`변경파일감지(삭제): ${changedFilePath}`);
|
|
46
|
+
for (const targetFilePath of targetFilePaths) {
|
|
43
47
|
await FsUtil.removeAsync(targetFilePath);
|
|
44
48
|
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
this._logger.info("로컬 라이브러리 변경감지 및 복사 완료");
|
|
48
|
-
})
|
|
49
|
-
.watch(watchPaths);
|
|
50
|
-
}
|
|
49
|
+
}*/
|
|
50
|
+
}
|
|
51
51
|
|
|
52
|
+
this._logger.info("로컬 라이브러리 변경감지 및 복사 완료");
|
|
53
|
+
})
|
|
54
|
+
.watch(watchPaths);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
52
57
|
this._logger.log("로컬 라이브러리 업데이트 시작...");
|
|
53
|
-
|
|
58
|
+
for (const updatePathInfo of updatePathInfos) {
|
|
59
|
+
await this._runAsync(updatePathInfo);
|
|
60
|
+
}
|
|
54
61
|
this._logger.info("로컬 라이브러리 업데이트 완료");
|
|
55
|
-
}
|
|
62
|
+
}
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
|
|
@@ -77,7 +84,7 @@ export class SdCliLocalUpdater {
|
|
|
77
84
|
));
|
|
78
85
|
}
|
|
79
86
|
|
|
80
|
-
private async
|
|
87
|
+
private async _getUpdatePathInfosAsync(record: Record<string, string>): Promise<{ source: string; target: string }[]> {
|
|
81
88
|
return (
|
|
82
89
|
await Object.keys(record).parallelAsync(async (packageGlobPath) => {
|
|
83
90
|
// "node_modules'에서 로컬업데이트 설정에 맞는 패키지를 "glob"하여 대상 패키지경로 목록 가져오기
|