@simplysm/sd-cli 7.0.26 → 7.0.37

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.
@@ -8,9 +8,8 @@ import { SdCliBuildResultUtil } from "../utils/SdCliBuildResultUtil";
8
8
  import { ErrorInfo } from "ts-loader/dist/interfaces";
9
9
  import os from "os";
10
10
  import { ESLint } from "eslint";
11
- import * as webpackMerge from "webpack-merge";
12
11
  import TerserPlugin from "terser-webpack-plugin";
13
- import { StringUtil } from "@simplysm/sd-core-common";
12
+ import { ObjectUtil, StringUtil } from "@simplysm/sd-core-common";
14
13
  import ESLintWebpackPlugin from "eslint-webpack-plugin";
15
14
  import CopyWebpackPlugin from "copy-webpack-plugin";
16
15
  import { LicenseWebpackPlugin } from "license-webpack-plugin";
@@ -45,7 +44,8 @@ export class SdCliServerBuilder extends EventEmitter {
45
44
  await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
46
45
 
47
46
  // 빌드 준비
48
- const webpackConfig = this._getWebpackWatchConfig();
47
+ const extModuleNames = this._getExternalModuleNames();
48
+ const webpackConfig = this._getWebpackConfig(true, extModuleNames);
49
49
  const compiler = webpack(webpackConfig);
50
50
  await new Promise<void>((resolve, reject) => {
51
51
  compiler.hooks.watchRun.tapAsync(this.constructor.name, (args, callback) => {
@@ -55,15 +55,20 @@ export class SdCliServerBuilder extends EventEmitter {
55
55
  this._logger.debug("Webpack 빌드 수행...");
56
56
  });
57
57
 
58
- compiler.watch({}, (err, stats) => {
58
+ compiler.watch({}, async (err, stats) => {
59
59
  if (err != null || stats == null) {
60
60
  reject(err);
61
61
  return;
62
62
  }
63
63
 
64
+ // .config.json 파일 쓰기
65
+ await this._writeDistConfigFileAsync();
66
+
67
+ // 결과 반환
64
68
  const results = SdCliBuildResultUtil.convertFromWebpackStats(stats);
65
69
  this.emit("complete", results);
66
70
 
71
+ // 마무리
67
72
  this._logger.debug("Webpack 빌드 완료");
68
73
  resolve();
69
74
  });
@@ -76,7 +81,8 @@ export class SdCliServerBuilder extends EventEmitter {
76
81
 
77
82
  // 빌드
78
83
  this._logger.debug("Webpack 빌드 수행...");
79
- const webpackConfig = this._getWebpackBuildConfig();
84
+ const extModuleNames = this._getExternalModuleNames();
85
+ const webpackConfig = this._getWebpackConfig(false, extModuleNames);
80
86
  const compiler = webpack(webpackConfig);
81
87
  const buildResults = await new Promise<ISdCliPackageBuildResult[]>((resolve, reject) => {
82
88
  compiler.run((err, stats) => {
@@ -85,18 +91,127 @@ export class SdCliServerBuilder extends EventEmitter {
85
91
  return;
86
92
  }
87
93
 
88
- // 결과 리턴
94
+ // 결과 반환
89
95
  const results = SdCliBuildResultUtil.convertFromWebpackStats(stats);
90
96
  resolve(results);
91
97
  });
92
98
  });
93
- this._logger.debug("Webpack 빌드 완료");
94
99
 
100
+ // .config.json 파일 쓰기
101
+ await this._writeDistConfigFileAsync();
102
+
103
+ // pm2.json 파일 쓰기
104
+ await this._writeDistPm2ConfigFileAsync();
105
+
106
+ // iis 파일 쓰기
107
+ await this._writeDistIisConfigFileAsync();
108
+
109
+ // 배포용 package.json 파일 생성
110
+ await this._writeDistNpmConfigFileAsync(extModuleNames);
111
+
112
+ // 마무리
113
+ this._logger.debug("Webpack 빌드 완료");
95
114
  return buildResults;
96
115
  }
97
116
 
98
- private get _webpackCommonConfig(): webpack.Configuration {
117
+ private async _writeDistConfigFileAsync(): Promise<void> {
118
+ const configDistPath = path.resolve(this._parsedTsconfig.options.outDir!, ".config.json");
119
+ await FsUtil.writeFileAsync(configDistPath, JSON.stringify(this._config.configs ?? {}, undefined, 2));
120
+ }
121
+
122
+ private async _writeDistPm2ConfigFileAsync(): Promise<void> {
123
+ if (this._config.pm2 === undefined || this._config.pm2 === false) return;
124
+
125
+ const npmConfig = this._getNpmConfig(this._rootPath)!;
126
+ const pm2DistPath = path.resolve(this._parsedTsconfig.options.outDir!, "pm2.json");
127
+ await FsUtil.writeFileAsync(
128
+ pm2DistPath,
129
+ JSON.stringify(
130
+ ObjectUtil.merge(
131
+ {
132
+ "name": npmConfig.name.replace(/@/g, "").replace(/\//g, "-"),
133
+ "script": path.basename(path.resolve(this._parsedTsconfig.options.outDir!, "main.mjs")),
134
+ "watch": true,
135
+ "watch_delay": 2000,
136
+ "ignore_watch": [
137
+ "node_modules",
138
+ "www"
139
+ ].distinct(),
140
+ "interpreter": "node@" + process.versions.node,
141
+ "env": {
142
+ NODE_ENV: "production",
143
+ SD_VERSION: npmConfig.version,
144
+ TZ: "Asia/Seoul",
145
+ ...this._config.env ? this._config.env : {}
146
+ }
147
+ },
148
+ (typeof this._config.pm2 !== "boolean") ? this._config.pm2 : {},
149
+ {
150
+ arrayProcess: "concat"
151
+ }),
152
+ undefined,
153
+ 2
154
+ )
155
+ );
156
+ }
157
+
158
+ private async _writeDistIisConfigFileAsync(): Promise<void> {
159
+ if (this._config.iis === undefined || this._config.iis === false) return;
160
+
161
+ const iisDistPath = path.resolve(this._parsedTsconfig.options.outDir!, "web.config");
162
+ const serverExeFilePath = (this._config.iis !== true && "serverExeFilePath" in this._config.iis)
163
+ ? (this._config.iis.serverExeFilePath ?? "C:\\Program Files\\nodejs\\node.exe")
164
+ : "C:\\Program Files\\nodejs\\node.exe";
165
+ await FsUtil.writeFileAsync(iisDistPath, `
166
+ <configuration>
167
+ <system.webServer>
168
+ <webSocket enabled="false" />
169
+ <handlers>
170
+ <add name="iisnode" path="main.js" verb="*" modules="iisnode" />
171
+ </handlers>
172
+ <iisnode nodeProcessCommandLine="${serverExeFilePath}"
173
+ watchedFiles="web.config;*.js"
174
+ loggingEnabled="true"
175
+ devErrorsEnabled="true" />
176
+ <rewrite>
177
+ <rules>
178
+ <rule name="main">
179
+ <action type="Rewrite" url="main.mjs" />
180
+ </rule>
181
+ </rules>
182
+ </rewrite>
183
+ <httpErrors errorMode="Detailed" />
184
+ </system.webServer>
185
+ </configuration>`.trim());
186
+ }
187
+
188
+ private async _writeDistNpmConfigFileAsync(deps: string[]): Promise<void> {
189
+ const distNpmConfig = ObjectUtil.clone(this._getNpmConfig(this._rootPath))!;
190
+ distNpmConfig.dependencies = {};
191
+ for (const dep of deps) {
192
+ distNpmConfig.dependencies[dep] = "*";
193
+ }
194
+ delete distNpmConfig.optionalDependencies;
195
+ delete distNpmConfig.devDependencies;
196
+ delete distNpmConfig.peerDependencies;
197
+
198
+ if (this._config.pm2 !== undefined) {
199
+ distNpmConfig.scripts = { "start": "pm2 start pm2.json" };
200
+ }
201
+
202
+ await FsUtil.writeFileAsync(
203
+ path.resolve(this._parsedTsconfig.options.outDir!, "package.json"),
204
+ JSON.stringify(distNpmConfig, undefined, 2)
205
+ );
206
+ }
207
+
208
+ private _getWebpackConfig(watch: boolean, extModuleNames: string[]): webpack.Configuration {
209
+ const internalModuleCachePaths = watch
210
+ ? FsUtil.findAllParentChildDirPaths("node_modules/!(@simplysm)", this._rootPath, this._workspaceRootPath)
211
+ : undefined;
212
+
99
213
  return {
214
+ mode: watch ? "development" : "production",
100
215
  devtool: false,
101
216
  target: ["node", "es2020"],
102
217
  profile: false,
@@ -126,6 +241,42 @@ export class SdCliServerBuilder extends EventEmitter {
126
241
  performance: { hints: false },
127
242
  node: false,
128
243
  stats: "errors-warnings",
244
+ externals: extModuleNames,
245
+ ...watch ? {
246
+ cache: { type: "memory", maxGenerations: 1 },
247
+ snapshot: {
248
+ immutablePaths: internalModuleCachePaths,
249
+ managedPaths: internalModuleCachePaths
250
+ }
251
+ } : {
252
+ cache: false
253
+ },
254
+ optimization: {
255
+ ...watch ? {} : {
256
+ minimize: true,
257
+ minimizer: [
258
+ new TerserPlugin({
259
+ extractComments: false,
260
+ terserOptions: {
261
+ compress: true,
262
+ ecma: 2020,
263
+ sourceMap: false,
264
+ keep_classnames: true,
265
+ keep_fnames: true,
266
+ ie8: false,
267
+ safari10: false,
268
+ module: true,
269
+ format: {
270
+ comments: false
271
+ }
272
+ }
273
+ })
274
+ ]
275
+ },
276
+ moduleIds: "deterministic",
277
+ chunkIds: watch ? "named" : "deterministic",
278
+ emitOnErrors: watch
279
+ },
129
280
  module: {
130
281
  strictExportPresence: true,
131
282
  rules: [
@@ -135,6 +286,18 @@ export class SdCliServerBuilder extends EventEmitter {
135
286
  fullySpecified: false
136
287
  }
137
288
  },
289
+ ...watch ? [
290
+ {
291
+ test: /\.m?js$/,
292
+ enforce: "pre" as const,
293
+ loader: "source-map-loader",
294
+ options: {
295
+ filterSourceMappingUrl: (mapUri: string, resourcePath: string) => {
296
+ return !resourcePath.includes("node_modules") || (/@simplysm[\\/]sd/).test(resourcePath);
297
+ }
298
+ }
299
+ }
300
+ ] : [],
138
301
  {
139
302
  test: /\.ts$/,
140
303
  exclude: /node_modules/,
@@ -160,6 +323,14 @@ export class SdCliServerBuilder extends EventEmitter {
160
323
  ]
161
324
  },
162
325
  plugins: [
326
+ ...watch ? [] : [
327
+ new LicenseWebpackPlugin({
328
+ stats: { warnings: false, errors: false },
329
+ perChunkOutput: false,
330
+ outputFilename: "3rd_party_licenses.txt",
331
+ skipChildCompilers: true
332
+ }) as any
333
+ ],
163
334
  new CopyWebpackPlugin({
164
335
  patterns: ["assets/"].map((item) => ({
165
336
  context: this._rootPath,
@@ -185,6 +356,8 @@ export class SdCliServerBuilder extends EventEmitter {
185
356
  }),
186
357
  new ESLintWebpackPlugin({
187
358
  context: this._rootPath,
359
+ eslintPath: path.resolve(this._workspaceRootPath, "node_modules", "eslint"),
360
+ exclude: ["node_modules"],
188
361
  extensions: ["ts", "js", "mjs", "cjs"],
189
362
  fix: false,
190
363
  threads: false,
@@ -207,96 +380,21 @@ export class SdCliServerBuilder extends EventEmitter {
207
380
  }
208
381
  return resultMessages.join(os.EOL);
209
382
  }
210
- }),
383
+ })/*,
211
384
  new webpack.ProgressPlugin({
212
385
  handler: (per: number, msg: string, ...args: string[]) => {
213
386
  const phaseText = msg ? ` - phase: ${msg}` : "";
214
387
  const argsText = args.length > 0 ? ` - args: [${args.join(", ")}]` : "";
215
388
  this._logger.debug(`Webpack 빌드 수행중...(${Math.round(per * 100)}%)${phaseText}${argsText}`);
216
389
  }
217
- })
390
+ })*/
218
391
  ]
219
392
  };
220
393
  }
221
394
 
222
- private _getWebpackWatchConfig(): webpack.Configuration {
223
- const internalModuleCachePaths = FsUtil.findAllParentChildDirPaths("node_modules/!(@simplysm)", this._rootPath, this._workspaceRootPath);
224
-
225
- const extModuleNames = this._findExternalModules(true).map((item) => item.name);
226
- return webpackMerge.merge(this._webpackCommonConfig, {
227
- mode: "development",
228
- module: {
229
- rules: [
230
- {
231
- test: /\.m?js$/,
232
- enforce: "pre",
233
- loader: "source-map-loader",
234
- options: {
235
- filterSourceMappingUrl: (mapUri: string, resourcePath: string) => {
236
- return !resourcePath.includes("node_modules") || (/@simplysm[\\/]sd/).test(resourcePath);
237
- }
238
- }
239
- }
240
- ]
241
- },
242
- cache: { type: "memory", maxGenerations: 1 },
243
- snapshot: {
244
- immutablePaths: internalModuleCachePaths,
245
- managedPaths: internalModuleCachePaths
246
- },
247
- optimization: {
248
- moduleIds: "deterministic",
249
- chunkIds: "named",
250
- emitOnErrors: true
251
- },
252
- externals: extModuleNames
253
- });
254
- }
255
-
256
- private _getWebpackBuildConfig(): webpack.Configuration {
257
- const extModuleNames = this._findExternalModules(false).map((item) => item.name);
258
- return webpackMerge.merge(this._webpackCommonConfig, {
259
- mode: "production",
260
- cache: false,
261
- optimization: {
262
- minimize: true,
263
- minimizer: [
264
- new TerserPlugin({
265
- extractComments: false,
266
- terserOptions: {
267
- compress: true,
268
- ecma: 2020,
269
- sourceMap: false,
270
- keep_classnames: true,
271
- keep_fnames: true,
272
- ie8: false,
273
- safari10: false,
274
- module: true,
275
- format: {
276
- comments: false
277
- }
278
- }
279
- })
280
- ],
281
- moduleIds: "deterministic",
282
- chunkIds: "deterministic",
283
- emitOnErrors: false
284
- },
285
- plugins: [
286
- new LicenseWebpackPlugin({
287
- stats: { warnings: false, errors: false },
288
- perChunkOutput: false,
289
- outputFilename: "3rd_party_licenses.txt",
290
- skipChildCompilers: true
291
- }) as any
292
- ],
293
- externals: extModuleNames
294
- });
295
- }
296
-
297
- private _findExternalModules(all: boolean): { name: string; path?: string }[] {
395
+ private _getExternalModuleNames(): string[] {
298
396
  const loadedModuleNames: string[] = [];
299
- const externalModules: { name: string; path?: string }[] = [];
397
+ const resultSet = new Set<string>();
300
398
 
301
399
  const fn = (currPath: string): void => {
302
400
  const npmConfig = this._getNpmConfig(currPath);
@@ -320,8 +418,8 @@ export class SdCliServerBuilder extends EventEmitter {
320
418
  continue;
321
419
  }
322
420
 
323
- if (all || FsUtil.exists(path.resolve(modulePath, "binding.gyp"))) {
324
- externalModules.push({ path: modulePath, name: moduleName });
421
+ if (FsUtil.exists(path.resolve(modulePath, "binding.gyp"))) {
422
+ resultSet.add(moduleName);
325
423
  }
326
424
 
327
425
  fn(modulePath);
@@ -333,12 +431,12 @@ export class SdCliServerBuilder extends EventEmitter {
333
431
 
334
432
  const optModulePath = FsUtil.findAllParentChildDirPaths("node_modules/" + optModuleName, currPath, this._workspaceRootPath).first();
335
433
  if (StringUtil.isNullOrEmpty(optModulePath)) {
336
- externalModules.push({ path: optModulePath, name: optModuleName });
434
+ resultSet.add(optModuleName);
337
435
  continue;
338
436
  }
339
437
 
340
- if (all || FsUtil.exists(path.resolve(optModulePath, "binding.gyp"))) {
341
- externalModules.push({ path: optModulePath, name: optModuleName });
438
+ if (FsUtil.exists(path.resolve(optModulePath, "binding.gyp"))) {
439
+ resultSet.add(optModuleName);
342
440
  }
343
441
 
344
442
  fn(optModulePath);
@@ -347,7 +445,7 @@ export class SdCliServerBuilder extends EventEmitter {
347
445
 
348
446
  fn(this._rootPath);
349
447
 
350
- return externalModules.distinct();
448
+ return Array.from(resultSet.values());
351
449
  }
352
450
 
353
451
  private _getNpmConfig(pkgPath: string): INpmConfig | undefined {
@@ -1,4 +1,4 @@
1
- import { ISdCliPackageBuildResult } from "../commons";
1
+ import { INpmConfig, ISdCliPackageBuildResult } from "../commons";
2
2
  import { EventEmitter } from "events";
3
3
  import ts from "typescript";
4
4
  import { FsUtil, Logger, PathUtil, SdFsWatcher } from "@simplysm/sd-core-node";
@@ -11,6 +11,7 @@ import { SdCliPackageLinter } from "../build-tool/SdCliPackageLinter";
11
11
  import { SdCliCacheCompilerHost } from "../build-tool/SdCliCacheCompilerHost";
12
12
  import { SdCliNgCacheCompilerHost } from "../build-tool/SdCliNgCacheCompilerHost";
13
13
  import { NgCompiler } from "@angular/compiler-cli/src/ngtsc/core";
14
+ import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
14
15
 
15
16
  export class SdCliTsLibBuilder extends EventEmitter {
16
17
  private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
@@ -26,10 +27,26 @@ export class SdCliTsLibBuilder extends EventEmitter {
26
27
  private _ngProgram?: NgtscProgram;
27
28
  private _builder?: ts.EmitAndSemanticDiagnosticsBuilderProgram;
28
29
 
29
- public constructor(private readonly _rootPath,
30
- private readonly _isAngular: boolean) {
30
+ private readonly _tsconfigFilePath: string;
31
+ private readonly _parsedTsconfig: ts.ParsedCommandLine;
32
+ private readonly _npmConfig: INpmConfig;
33
+
34
+ private readonly _isAngular: boolean;
35
+
36
+ public constructor(private readonly _rootPath) {
31
37
  super();
32
38
  this._linter = new SdCliPackageLinter(this._rootPath);
39
+
40
+ // tsconfig
41
+ this._tsconfigFilePath = path.resolve(this._rootPath, "tsconfig-build.json");
42
+ const tsconfig = FsUtil.readJson(this._tsconfigFilePath);
43
+ this._parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._rootPath);
44
+
45
+ // package.json
46
+ this._npmConfig = FsUtil.readJson(path.resolve(this._rootPath, "package.json"));
47
+
48
+ // else
49
+ this._isAngular = SdCliNpmConfigUtil.getDependencies(this._npmConfig).defaults.includes("@angular/core");
33
50
  }
34
51
 
35
52
  public override on(event: "change", listener: () => void): this;
@@ -41,14 +58,11 @@ export class SdCliTsLibBuilder extends EventEmitter {
41
58
  public async watchAsync(): Promise<void> {
42
59
  this.emit("change");
43
60
 
44
- // TSCONFIG 읽기
45
- const parsedTsconfig = await this._getParsedTsconfigAsync();
46
-
47
61
  // DIST 비우기
48
- await FsUtil.removeAsync(parsedTsconfig.options.outDir!);
62
+ await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
49
63
 
50
64
  // 프로그램 리로드
51
- const buildPack = this._createSdBuildPack(parsedTsconfig);
65
+ const buildPack = this._createSdBuildPack(this._parsedTsconfig);
52
66
 
53
67
  const relatedPaths = await this.getAllRelatedPathsAsync();
54
68
  const watcher = SdFsWatcher.watch(relatedPaths);
@@ -65,7 +79,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
65
79
  }
66
80
 
67
81
  // 빌드
68
- const watchBuildPack = this._createSdBuildPack(parsedTsconfig);
82
+ const watchBuildPack = this._createSdBuildPack(this._parsedTsconfig);
69
83
 
70
84
  // 린트
71
85
  const watchBuildResults = await this._runBuilderAsync(watchBuildPack.builder, watchBuildPack.ngCompiler);
@@ -90,14 +104,11 @@ export class SdCliTsLibBuilder extends EventEmitter {
90
104
  }
91
105
 
92
106
  public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
93
- // TSCONFIG 읽기
94
- const parsedTsconfig = await this._getParsedTsconfigAsync();
95
-
96
107
  // DIST 비우기
97
- await FsUtil.removeAsync(parsedTsconfig.options.outDir!);
108
+ await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
98
109
 
99
110
  // 프로그램 리로드
100
- const buildPack = this._createSdBuildPack(parsedTsconfig);
111
+ const buildPack = this._createSdBuildPack(this._parsedTsconfig);
101
112
 
102
113
  // 빌드
103
114
  const buildResults = await this._runBuilderAsync(buildPack.builder, buildPack.ngCompiler);
@@ -312,12 +323,6 @@ export class SdCliTsLibBuilder extends EventEmitter {
312
323
  return compilerHost;
313
324
  }
314
325
  }
315
-
316
- private async _getParsedTsconfigAsync(): Promise<ts.ParsedCommandLine> {
317
- const tsconfigFilePath = path.resolve(this._rootPath, "tsconfig-build.json");
318
- const tsconfig = await FsUtil.readJsonAsync(tsconfigFilePath);
319
- return ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._rootPath);
320
- }
321
326
  }
322
327
 
323
328
  interface IFileCache {
package/src/commons.ts CHANGED
@@ -50,4 +50,7 @@ export interface ISdCliLibPackageConfig {
50
50
  export interface ISdCliServerPackageConfig {
51
51
  type: "server";
52
52
  env?: Record<string, string>;
53
+ configs?: Record<string, any>;
54
+ pm2?: Record<string, any> | boolean;
55
+ iis?: { serverExeFilePath?: string } | boolean;
53
56
  }
@@ -8,11 +8,15 @@ export class SdCliNpm {
8
8
  }
9
9
 
10
10
  public async updateAsync(): Promise<void> {
11
- this._logger.debug("업데이트할 패키지 확인...");
12
- await SdProcess.execAsync("npm outdated", { cwd: this._rootPath });
11
+ try {
12
+ this._logger.debug("업데이트할 패키지 확인...");
13
+ await SdProcess.spawnAsync("npm outdated", { cwd: this._rootPath });
14
+ }
15
+ catch (err) {
16
+ }
13
17
 
14
18
  this._logger.debug("업데이트 시작...");
15
- await SdProcess.execAsync("npm update", { cwd: this._rootPath });
19
+ await SdProcess.spawnAsync("npm update", { cwd: this._rootPath });
16
20
 
17
21
  this._logger.debug("sd-cli 준비...");
18
22
  await new SdCliPrepare().prepareAsync();
@@ -9,6 +9,7 @@ import semver from "semver/preload";
9
9
  import { SdCliConfigUtil } from "../utils/SdCliConfigUtil";
10
10
  import { SdServiceServer } from "@simplysm/sd-service/server";
11
11
  import { SdCliNpm } from "./SdCliNpm";
12
+ import { SdCliLocalUpdate } from "./SdCliLocalUpdate";
12
13
 
13
14
  export class SdCliWorkspace {
14
15
  private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
@@ -25,6 +26,11 @@ export class SdCliWorkspace {
25
26
  this._logger.debug("프로젝트 설정 가져오기...");
26
27
  const config = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), true, opt.optNames);
27
28
 
29
+ if (config.localUpdates) {
30
+ this._logger.debug("로컬 라이브러리 업데이트 변경감지 시작...");
31
+ await new SdCliLocalUpdate(this._rootPath).watchAsync({ confFileRelPath: opt.confFileRelPath });
32
+ }
33
+
28
34
  this._logger.debug("패키지 목록 구성...");
29
35
  const pkgs = await this._getPackagesAsync(config);
30
36
 
@@ -148,9 +154,9 @@ export class SdCliWorkspace {
148
154
  // GIT 사용중일 경우, 커밋되지 않은 수정사항이 있는지 확인
149
155
  if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
150
156
  this._logger.debug("GIT 커밋여부 확인...");
151
- const gitStatusResult = await SdProcess.execAsync("git status");
157
+ const gitStatusResult = await SdProcess.spawnAsync("git status");
152
158
  if (gitStatusResult.includes("Changes") || gitStatusResult.includes("Untracked")) {
153
- throw new Error("커밋되지 않은 정보가 있습니다.");
159
+ throw new Error("커밋되지 않은 정보가 있습니다.\n" + gitStatusResult);
154
160
  }
155
161
  }
156
162
 
@@ -172,9 +178,9 @@ export class SdCliWorkspace {
172
178
  // GIT 사용중일경우, 새 버전 커밋 및 TAG 생성
173
179
  if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
174
180
  this._logger.debug("새 버전 커밋 및 TAG 생성...");
175
- await SdProcess.execAsync("git add .");
176
- await SdProcess.execAsync(`git commit -m "v${this._npmConfig.version}"`);
177
- await SdProcess.execAsync(`git tag -a "v${this._npmConfig.version}" -m "v${this._npmConfig.version}"`);
181
+ await SdProcess.spawnAsync("git add .");
182
+ await SdProcess.spawnAsync(`git commit -m "v${this._npmConfig.version}"`);
183
+ await SdProcess.spawnAsync(`git tag -a "v${this._npmConfig.version}" -m "v${this._npmConfig.version}"`);
178
184
  }
179
185
 
180
186
  this._logger.debug("배포 시작...");
@@ -6,6 +6,7 @@ import { ObjectUtil } from "@simplysm/sd-core-common";
6
6
  import { SdCliTsLibBuilder } from "../builder/SdCliTsLibBuilder";
7
7
  import { SdCliJsLibBuilder } from "../builder/SdCliJsLibBuilder";
8
8
  import { SdCliServerBuilder } from "../builder/SdCliServerBuilder";
9
+ import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
9
10
 
10
11
  export class SdCliPackage extends EventEmitter {
11
12
  private readonly _npmConfig: INpmConfig;
@@ -28,10 +29,8 @@ export class SdCliPackage extends EventEmitter {
28
29
 
29
30
  public get allDependencies(): string[] {
30
31
  return [
31
- ...Object.keys(this._npmConfig.dependencies ?? {}),
32
- ...Object.keys(this._npmConfig.optionalDependencies ?? {}),
33
- // ...Object.keys(this._npmConfig.devDependencies ?? {}),
34
- ...Object.keys(this._npmConfig.peerDependencies ?? {})
32
+ ...SdCliNpmConfigUtil.getDependencies(this._npmConfig).defaults,
33
+ ...SdCliNpmConfigUtil.getDependencies(this._npmConfig).optionals
35
34
  ].distinct();
36
35
  }
37
36
 
@@ -87,7 +86,7 @@ export class SdCliPackage extends EventEmitter {
87
86
 
88
87
  public async publishAsync(): Promise<void> {
89
88
  if (this._config.type === "library" && this._config.publish === "npm") {
90
- await SdProcess.execAsync("npm publish --quiet --access public", { cwd: this.rootPath });
89
+ await SdProcess.spawnAsync("npm publish --quiet --access public", { cwd: this.rootPath });
91
90
  }
92
91
  }
93
92
 
@@ -99,8 +98,8 @@ export class SdCliPackage extends EventEmitter {
99
98
  }
100
99
 
101
100
  if (this._config.type === "library") {
102
- const isAngular = isTs && this.allDependencies.includes("@angular/core");
103
- return isTs ? new SdCliTsLibBuilder(this.rootPath, isAngular) : new SdCliJsLibBuilder(this.rootPath);
101
+ // const isAngular = isTs && this.allDependencies.includes("@angular/core");
102
+ return isTs ? new SdCliTsLibBuilder(this.rootPath) : new SdCliJsLibBuilder(this.rootPath);
104
103
  }
105
104
  else {
106
105
  return new SdCliServerBuilder(this.rootPath, this._config, this._workspaceRootPath);
@@ -0,0 +1,16 @@
1
+ import { INpmConfig } from "../commons";
2
+
3
+ export class SdCliNpmConfigUtil {
4
+ public static getDependencies(npmConfig: INpmConfig): { defaults: string[]; optionals: string[] } {
5
+ return {
6
+ defaults: [
7
+ ...Object.keys(npmConfig.dependencies ?? {}),
8
+ ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => !npmConfig.peerDependenciesMeta?.[item].optional)
9
+ ].distinct(),
10
+ optionals: [
11
+ ...Object.keys(npmConfig.optionalDependencies ?? {}),
12
+ ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => npmConfig.peerDependenciesMeta?.[item].optional)
13
+ ].distinct()
14
+ };
15
+ }
16
+ }