@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.
Files changed (78) hide show
  1. package/dist-node/bin/sd-cli.js +19 -4
  2. package/dist-node/bin/sd-cli.js.map +1 -1
  3. package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js +102 -49
  4. package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js.map +1 -1
  5. package/dist-node/build-tools/metadata/SdAotMetadataReader.js +6 -2
  6. package/dist-node/build-tools/metadata/SdAotMetadataReader.js.map +1 -1
  7. package/dist-node/build-tools/metadata/SdIvyMetadataReader.js +22 -5
  8. package/dist-node/build-tools/metadata/SdIvyMetadataReader.js.map +1 -1
  9. package/dist-node/build-tools/metadata/SdMetadataError.js +13 -0
  10. package/dist-node/build-tools/metadata/SdMetadataError.js.map +1 -0
  11. package/dist-node/build-tools/metadata/SdMyMetadataReader.js +22 -5
  12. package/dist-node/build-tools/metadata/SdMyMetadataReader.js.map +1 -1
  13. package/dist-node/builders/SdCliNgClientBuilder.js +73 -66
  14. package/dist-node/builders/SdCliNgClientBuilder.js.map +1 -1
  15. package/dist-node/builders/SdCliNgLibraryBuilder.js +52 -24
  16. package/dist-node/builders/SdCliNgLibraryBuilder.js.map +1 -1
  17. package/dist-node/builders/SdCliServerBuilder.js +45 -44
  18. package/dist-node/builders/SdCliServerBuilder.js.map +1 -1
  19. package/dist-node/builders/SdCliTypescriptBuilder.js +64 -59
  20. package/dist-node/builders/SdCliTypescriptBuilder.js.map +1 -1
  21. package/dist-node/entry-points/SdCliLocalUpdater.js +30 -29
  22. package/dist-node/entry-points/SdCliLocalUpdater.js.map +1 -1
  23. package/dist-node/entry-points/SdCliProject.js +10 -16
  24. package/dist-node/entry-points/SdCliProject.js.map +1 -1
  25. package/dist-node/packages/SdCliClientPackage.js +4 -3
  26. package/dist-node/packages/SdCliClientPackage.js.map +1 -1
  27. package/dist-node/packages/SdCliLibraryPackage.js +3 -2
  28. package/dist-node/packages/SdCliLibraryPackage.js.map +1 -1
  29. package/dist-node/packages/SdCliServerPackage.js +4 -3
  30. package/dist-node/packages/SdCliServerPackage.js.map +1 -1
  31. package/dist-node/utils/SdProjectConfigUtil.js +1 -1
  32. package/dist-node/utils/SdProjectConfigUtil.js.map +1 -1
  33. package/dist-node/utils/SdWebpackUtil.js +33 -13
  34. package/dist-node/utils/SdWebpackUtil.js.map +1 -1
  35. package/dist-node/workers/client-ng-gen-worker.js +54 -0
  36. package/dist-node/workers/client-ng-gen-worker.js.map +1 -0
  37. package/dist-node/workers/lib-build-worker.js +7 -6
  38. package/dist-node/workers/lib-build-worker.js.map +1 -1
  39. package/dist-types/build-tools/metadata/SdIvyMetadataReader.d.ts +1 -0
  40. package/dist-types/build-tools/metadata/SdMetadataError.d.ts +6 -0
  41. package/dist-types/build-tools/metadata/SdMyMetadataReader.d.ts +1 -0
  42. package/dist-types/builders/SdCliNgClientBuilder.d.ts +6 -2
  43. package/dist-types/builders/SdCliNgLibraryBuilder.d.ts +3 -1
  44. package/dist-types/builders/SdCliServerBuilder.d.ts +2 -1
  45. package/dist-types/builders/SdCliTypescriptBuilder.d.ts +5 -5
  46. package/dist-types/commons.d.ts +3 -1
  47. package/dist-types/entry-points/SdCliLocalUpdater.d.ts +1 -1
  48. package/dist-types/entry-points/SdCliProject.d.ts +2 -0
  49. package/dist-types/packages/SdCliClientPackage.d.ts +2 -1
  50. package/dist-types/packages/SdCliLibraryPackage.d.ts +2 -1
  51. package/dist-types/packages/SdCliServerPackage.d.ts +2 -1
  52. package/dist-types/utils/SdWebpackUtil.d.ts +1 -1
  53. package/dist-types/workers/client-ng-gen-worker.d.ts +1 -0
  54. package/package.json +7 -7
  55. package/schema/schema.json +185 -122
  56. package/sd-tsconfig.node.json +2 -1
  57. package/src/bin/sd-cli.ts +19 -4
  58. package/src/build-tools/SdCliNgModuleFilesGenerator.ts +118 -60
  59. package/src/build-tools/metadata/SdAotMetadataReader.ts +8 -2
  60. package/src/build-tools/metadata/SdIvyMetadataReader.ts +27 -4
  61. package/src/build-tools/metadata/SdMetadataError.ts +7 -0
  62. package/src/build-tools/metadata/SdMyMetadataReader.ts +25 -3
  63. package/src/builders/SdCliNgClientBuilder.ts +122 -58
  64. package/src/builders/SdCliNgLibraryBuilder.ts +102 -43
  65. package/src/builders/SdCliServerBuilder.ts +61 -44
  66. package/src/builders/SdCliTypescriptBuilder.ts +92 -73
  67. package/src/commons.ts +1 -1
  68. package/src/entry-points/SdCliLocalUpdater.ts +40 -33
  69. package/src/entry-points/SdCliProject.ts +14 -13
  70. package/src/packages/SdCliClientPackage.ts +3 -2
  71. package/src/packages/SdCliLibraryPackage.ts +2 -1
  72. package/src/packages/SdCliServerPackage.ts +4 -3
  73. package/src/utils/SdCliFileCrypto.ts +1 -1
  74. package/src/utils/SdProjectConfigUtil.ts +1 -1
  75. package/src/utils/SdWebpackUtil.ts +42 -22
  76. package/src/workers/client-ng-gen-worker.ts +60 -0
  77. package/src/workers/lib-build-worker.ts +7 -6
  78. 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, Logger, PathUtil } from "@simplysm/sd-core-node";
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="C:\\Program Files\\nodejs\\node.exe" watchedFiles="web.config;*.js" loggingEnabled="true" />
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: false
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
- ...watch ? [
318
- new CopyWebpackPlugin({
319
- patterns: ["assets/"].map((item) => ({
320
- context: this.rootPath,
321
- to: item,
322
- from: `src/${item}`,
323
- noErrorOnMissing: true,
324
- force: true,
325
- globOptions: {
326
- dot: true,
327
- followSymbolicLinks: false,
328
- ignore: [
329
- ".gitkeep",
330
- "**/.DS_Store",
331
- "**/Thumbs.db"
332
- ].map((i) => PathUtil.posix(this.rootPath, i))
333
- },
334
- priority: 0
335
- }))
336
- })
337
- ] : [],
338
- ...this.config.env ? [
339
- new webpack.EnvironmentPlugin(this.config.env)
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 _parsedTsconfig: ts.ParsedCommandLine;
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.EmitAndSemanticDiagnosticsBuilderProgram;
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 ignoreProcesses: string[];
29
+ public skipProcesses: string[];
30
30
 
31
31
  public constructor(public rootPath: string,
32
32
  public tsconfigFilePath: string,
33
- ignoreProcesses: ("emit" | "check" | "lint" | "genIndex")[],
33
+ skipProcesses: ("emit" | "check" | "lint" | "genIndex")[],
34
34
  public autoIndexConfig: ISdAutoIndexConfig | undefined) {
35
35
  super();
36
- this.ignoreProcesses = ignoreProcesses;
36
+ this.skipProcesses = skipProcesses;
37
37
 
38
- const tsconfig: ITsconfig = FsUtil.readJson(this.tsconfigFilePath);
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(this._parsedTsconfig.options.outDir!);
60
- if (this._parsedTsconfig.options.declarationDir !== undefined) {
61
- await FsUtil.removeAsync(this._parsedTsconfig.options.declarationDir);
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.ignoreProcesses.includes("genIndex") && this._indexFileGenerator && this.autoIndexConfig) {
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._logger.debug("LINT");
196
-
197
- const linter = new ESLint({
198
- overrideConfig: {
199
- overrides: [
200
- {
201
- files: ["*.ts"],
202
- parserOptions: {
203
- program: this._program
204
- } as ParserOptions,
205
- settings: {
206
- "import/resolver": {
207
- typescript: {
208
- project: this.tsconfigFilePath
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
- const result = lintResults.mapMany((report) => (
229
- report.messages.map((msg) => {
230
- const severity: "warning" | "error" = msg.severity === 1 ? "warning" : "error";
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
- return {
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
- this._logger.debug("LINT 결과", result);
244
+ return result;
245
+ }
241
246
 
242
- return result;
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.EmitAndSemanticDiagnosticsBuilderProgram;
265
+ // const builder = this._builder as ts.SemanticDiagnosticsBuilderProgram;
261
266
 
262
267
  const result: string[] = [];
263
- for (const sourceFile of builder.getSourceFiles()) {
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.ignoreProcesses.includes("check")) {
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 dirtyFilePath of dirtyFilePaths) {
305
- const sourceFile = this._builder.getSourceFile(dirtyFilePath);
306
- if (!sourceFile) continue;
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.ignoreProcesses.includes("emit")) {
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
- this._moduleResolutionCache = ts.createModuleResolutionCache(this.rootPath, (s) => s, this._parsedTsconfig.options);
361
- this._cacheCompilerHost = await this._createCacheCompilerHostAsync(this._parsedTsconfig, this._moduleResolutionCache);
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
- this._parsedTsconfig.fileNames,
365
- this._parsedTsconfig.options,
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
- const builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(
385
- this._program,
386
- this._cacheCompilerHost,
387
- this._builder as ts.EmitAndSemanticDiagnosticsBuilderProgram
388
- );
389
- this._builder = builder;
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.createCompilerHost(parsedTsconfig.options);
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
- compilerHost.writeFile.call(cacheCompilerHost, fileName, data, writeByteOrderMark, onError, sourceFiles);
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
@@ -32,7 +32,7 @@ export interface ISdServerPackageConfig {
32
32
  externalDependencies?: string[];
33
33
  configs?: Record<string, any>;
34
34
  pm2?: Record<string, any> | boolean;
35
- iis?: boolean;
35
+ iis?: boolean | { serverExeFilePath?: string };
36
36
  publish?: TSdPublishConfig;
37
37
  }
38
38
 
@@ -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._getUpdatePathsAsync(config.localUpdates);
17
- await updatePathInfos.parallelAsync(async (updatePathInfo) => {
18
- if (watch) {
19
- const watchPaths = await this._getWatchPathsAsync(updatePathInfo.source);
20
-
21
- const watcher = new SdFsWatcher();
22
- watcher
23
- .onChange(async (changedInfos) => {
24
- this._logger.log("로컬 라이브러리 변경감지...");
25
-
26
- const watchPaths2 = await this._getWatchPathsAsync(updatePathInfo.source);
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
- }
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
- const targetFilePath = path.resolve(updatePathInfo.target, path.relative(updatePathInfo.source, changedFilePath));
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
- if (FsUtil.exists(changedFilePath)) {
38
- this._logger.debug(`변경파일감지(복사): ${changedFilePath}`);
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
- else {
42
- this._logger.debug(`변경파일감지(삭제): ${changedFilePath}`);
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
- await this._runAsync(updatePathInfo);
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 _getUpdatePathsAsync(record: Record<string, string>): Promise<{ source: string; target: string }[]> {
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"하여 대상 패키지경로 목록 가져오기