@simplysm/sd-cli 7.0.21 → 7.0.25

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 (33) hide show
  1. package/dist/bin/sd-cli.d.ts +1 -1
  2. package/dist/bin/sd-cli.mjs +54 -15
  3. package/dist/builder/SdCliServerBuilder.d.ts +22 -0
  4. package/dist/builder/SdCliServerBuilder.mjs +325 -0
  5. package/dist/builder/SdCliTsLibBuilder.mjs +2 -2
  6. package/dist/commons.d.ts +5 -4
  7. package/dist/entry-points/SdCliLocalUpdate.d.ts +7 -4
  8. package/dist/entry-points/SdCliLocalUpdate.mjs +6 -7
  9. package/dist/entry-points/SdCliNpm.d.ts +6 -0
  10. package/dist/entry-points/SdCliNpm.mjs +18 -0
  11. package/dist/entry-points/SdCliPrepare.d.ts +5 -0
  12. package/dist/entry-points/SdCliPrepare.mjs +54 -0
  13. package/dist/entry-points/SdCliWorkspace.d.ts +13 -5
  14. package/dist/entry-points/SdCliWorkspace.mjs +49 -13
  15. package/dist/packages/SdCliPackage.d.ts +6 -2
  16. package/dist/packages/SdCliPackage.mjs +34 -23
  17. package/dist/utils/SdCliBuildResultUtil.d.ts +4 -1
  18. package/dist/utils/SdCliBuildResultUtil.mjs +25 -2
  19. package/dist/utils/SdCliConfigUtil.d.ts +1 -1
  20. package/dist/utils/SdCliConfigUtil.mjs +5 -5
  21. package/package.json +20 -11
  22. package/src/bin/sd-cli.ts +62 -14
  23. package/src/builder/SdCliServerBuilder.ts +361 -0
  24. package/src/builder/SdCliTsLibBuilder.ts +1 -1
  25. package/src/commons.ts +3 -5
  26. package/src/entry-points/SdCliLocalUpdate.ts +5 -6
  27. package/src/entry-points/SdCliNpm.ts +22 -0
  28. package/src/entry-points/SdCliPrepare.ts +54 -0
  29. package/src/entry-points/SdCliWorkspace.ts +65 -15
  30. package/src/packages/SdCliPackage.ts +37 -26
  31. package/src/utils/SdCliBuildResultUtil.ts +31 -1
  32. package/src/utils/SdCliConfigUtil.ts +4 -4
  33. package/tsconfig.json +4 -1
@@ -2,14 +2,14 @@ import { FsUtil } from "@simplysm/sd-core-node";
2
2
  import { ObjectUtil } from "@simplysm/sd-core-common";
3
3
  import path from "path";
4
4
  export class SdCliConfigUtil {
5
- static loadConfig(confFilePath, isDev, opts) {
6
- const confFileCont = FsUtil.readJson(confFilePath);
5
+ static async loadConfigAsync(confFilePath, isDev, opts) {
6
+ const confFileCont = await FsUtil.readJsonAsync(confFilePath);
7
7
  let conf = this._getConfigFromFileContent(confFileCont, isDev, opts);
8
8
  // extends
9
9
  if (conf.extends) {
10
10
  for (const extConfFilePath of conf.extends) {
11
- const extConf = this.loadConfig(path.resolve(path.dirname(confFilePath), extConfFilePath), isDev, opts);
12
- conf = this._mergeObj(conf, extConf);
11
+ const extConf = await this.loadConfigAsync(path.resolve(path.dirname(confFilePath), extConfFilePath), isDev, opts);
12
+ conf = this._mergeObj(extConf, conf);
13
13
  }
14
14
  }
15
15
  delete conf["extends"];
@@ -66,4 +66,4 @@ export class SdCliConfigUtil {
66
66
  });
67
67
  }
68
68
  }
69
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2RDbGlDb25maWdVdGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL1NkQ2xpQ29uZmlnVXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUV4QixNQUFNLE9BQU8sZUFBZTtJQUNuQixNQUFNLENBQUMsVUFBVSxDQUFDLFlBQW9CLEVBQUUsS0FBYyxFQUFFLElBQWU7UUFDNUUsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNuRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztRQUVyRSxVQUFVO1FBQ1YsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLEtBQUssTUFBTSxlQUFlLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDMUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUUsZUFBZSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUN4RyxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDdEM7U0FDRjtRQUNELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXZCLE9BQU8sSUFBb0IsQ0FBQztJQUM5QixDQUFDO0lBRU8sTUFBTSxDQUFDLHlCQUF5QixDQUFDLFlBQXFDLEVBQUUsS0FBYyxFQUFFLElBQWU7UUFDN0csTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUU1QyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDakIsS0FBSyxNQUFNLE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFDaEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsNEJBQTRCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ3ZHO1NBQ0Y7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxNQUFNLENBQUMsNEJBQTRCLENBQUMsWUFBcUMsRUFBRSxlQUErQyxFQUFFLEtBQWMsRUFBRSxJQUFlO1FBQ2pLLElBQUksT0FBTyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFaEQsV0FBVztRQUNYLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7UUFDdEMsSUFBSSxXQUFXLEVBQUU7WUFDZixLQUFLLE1BQU0sVUFBVSxJQUFJLFdBQVcsRUFBRTtnQkFDcEMsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUNyRCxJQUFJLE9BQU8sRUFBRTtvQkFDWCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsNEJBQTRCLENBQUMsWUFBWSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBQ3RGLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztpQkFDNUM7YUFDRjtZQUNELE9BQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQztTQUMxQjtRQUdELFVBQVU7UUFDVixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ3BDLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLFNBQVMsRUFBRTtZQUMvQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsNEJBQTRCLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0YsT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQzdDO1FBQ0QsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEIsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFdkIsVUFBVTtRQUNWLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzNCLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV0SCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRTtnQkFDNUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLDRCQUE0QixDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUM5RixPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDNUM7WUFFRCxLQUFLLE1BQU0sTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2hGLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ3hCO1NBQ0Y7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRU8sTUFBTSxDQUFDLFNBQVMsQ0FBTyxHQUFNLEVBQUUsTUFBUztRQUM5QyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRTtZQUNuQyxZQUFZLEVBQUUsU0FBUztZQUN2QixxQkFBcUIsRUFBRSxJQUFJO1NBQzVCLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRiJ9
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2RDbGlDb25maWdVdGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL1NkQ2xpQ29uZmlnVXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUV4QixNQUFNLE9BQU8sZUFBZTtJQUNuQixNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxZQUFvQixFQUFFLEtBQWMsRUFBRSxJQUFlO1FBQ3ZGLE1BQU0sWUFBWSxHQUFHLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5RCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztRQUVyRSxVQUFVO1FBQ1YsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLEtBQUssTUFBTSxlQUFlLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDMUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxlQUFlLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ25ILElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQzthQUN0QztTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFdkIsT0FBTyxJQUFvQixDQUFDO0lBQzlCLENBQUM7SUFFTyxNQUFNLENBQUMseUJBQXlCLENBQUMsWUFBcUMsRUFBRSxLQUFjLEVBQUUsSUFBZTtRQUM3RyxNQUFN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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/sd-cli",
3
- "version": "7.0.21",
3
+ "version": "7.0.25",
4
4
  "description": "심플리즘 패키지 - CLI",
5
5
  "author": "김석래",
6
6
  "repository": {
@@ -20,22 +20,31 @@
20
20
  "node": "^16"
21
21
  },
22
22
  "dependencies": {
23
+ "@angular/compiler-cli": "^13.2.0",
24
+ "eslint": "^8.7.0",
25
+ "sass": "^1.49.0",
26
+ "semver": "^7.3.5",
27
+ "source-map-support": "^0.5.21",
23
28
  "ts-node": "^10.4.0",
24
29
  "tsconfig-paths": "^3.12.0",
25
- "yargs": "^17.3.1",
26
- "chokidar": "^3.5.3",
27
30
  "typescript": "~4.5.5",
28
- "eslint": "^8.7.0",
29
- "@angular/compiler-cli": "^13.2.0",
30
- "sass": "^1.49.0",
31
- "semver": "^7.3.5"
31
+ "yargs": "^17.3.1",
32
+ "webpack": "^5.68.0",
33
+ "ts-loader": "^9.2.6",
34
+ "webpack-merge": "^5.8.0",
35
+ "terser-webpack-plugin": "^5.3.1",
36
+ "copy-webpack-plugin": "^10.2.4",
37
+ "eslint-webpack-plugin": "^3.1.1",
38
+ "source-map-loader": "^3.0.1",
39
+ "license-webpack-plugin": "^4.0.1"
32
40
  },
33
41
  "devDependencies": {
34
- "@types/yargs": "^17.0.8",
35
- "@types/semver": "^7.3.9"
42
+ "@types/semver": "^7.3.9",
43
+ "@types/yargs": "^17.0.8"
36
44
  },
37
45
  "peerDependencies": {
38
- "@simplysm/sd-core-common": "7.0.21",
39
- "@simplysm/sd-core-node": "7.0.21"
46
+ "@simplysm/sd-core-common": "7.0.25",
47
+ "@simplysm/sd-core-node": "7.0.25",
48
+ "@simplysm/sd-service": "7.0.25"
40
49
  }
41
50
  }
package/src/bin/sd-cli.ts CHANGED
@@ -1,10 +1,15 @@
1
- #!/usr/bin/env node --experimental-specifier-resolution=node
1
+ #!/usr/bin/env node --experimental-specifier-resolution=node --experimental-import-meta-resolve
2
2
 
3
3
  import yargs from "yargs";
4
4
  import { hideBin } from "yargs/helpers";
5
5
  import { Logger, LoggerSeverity } from "@simplysm/sd-core-node";
6
6
  import { SdCliWorkspace } from "../entry-points/SdCliWorkspace";
7
7
  import { SdCliLocalUpdate } from "../entry-points/SdCliLocalUpdate";
8
+ import sourceMapSupport from "source-map-support";
9
+ import { SdCliNpm } from "../entry-points/SdCliNpm";
10
+ import { SdCliPrepare } from "../entry-points/SdCliPrepare";
11
+
12
+ sourceMapSupport.install();
8
13
 
9
14
  Error.stackTraceLimit = Infinity;
10
15
 
@@ -19,6 +24,16 @@ const argv = yargs(hideBin(process.argv))
19
24
  default: false
20
25
  }
21
26
  })
27
+ .command(
28
+ "prepare",
29
+ "sd-cli 준비",
30
+ (cmd) => cmd.version(false)
31
+ )
32
+ .command(
33
+ "update",
34
+ "패키지 업데이트 (npm update)",
35
+ (cmd) => cmd.version(false)
36
+ )
22
37
  .command(
23
38
  "local-update",
24
39
  "로컬 라이브러리 업데이트를 수행합니다.",
@@ -38,6 +53,11 @@ const argv = yargs(hideBin(process.argv))
38
53
  config: {
39
54
  type: "string",
40
55
  describe: "simplysm.json 파일 경로"
56
+ },
57
+ options: {
58
+ type: "string",
59
+ array: true,
60
+ describe: "옵션 설정 (설정파일에서 @로 시작하는 부분)"
41
61
  }
42
62
  })
43
63
  )
@@ -49,6 +69,11 @@ const argv = yargs(hideBin(process.argv))
49
69
  config: {
50
70
  type: "string",
51
71
  describe: "simplysm.json 파일 경로"
72
+ },
73
+ options: {
74
+ type: "string",
75
+ array: true,
76
+ describe: "옵션 설정 (설정파일에서 @로 시작하는 부분)"
52
77
  }
53
78
  })
54
79
  )
@@ -57,14 +82,19 @@ const argv = yargs(hideBin(process.argv))
57
82
  "프로젝트의 각 패키지를 배포합니다.",
58
83
  (cmd) => cmd.version(false)
59
84
  .options({
85
+ noBuild: {
86
+ type: "boolean",
87
+ describe: "빌드를 하지않고 배포합니다.",
88
+ default: false
89
+ },
60
90
  config: {
61
91
  type: "string",
62
92
  describe: "simplysm.json 파일 경로"
63
93
  },
64
- "noBuild": {
65
- type: "boolean",
66
- describe: "빌드를 하지않고 배포합니다.",
67
- default: false
94
+ options: {
95
+ type: "string",
96
+ array: true,
97
+ describe: "옵션 설정 (설정파일에서 @로 시작하는 부분)"
68
98
  }
69
99
  })
70
100
  )
@@ -88,22 +118,40 @@ else {
88
118
  const logger = Logger.get(["simplysm", "sd-cli", "bin", "sd-cli"]);
89
119
 
90
120
  (async () => {
91
- if (argv._[0] === "local-update") {
92
- await new SdCliLocalUpdate(process.cwd(), argv.config)
93
- .runAsync();
121
+ if (argv._[0] === "prepare") {
122
+ await new SdCliPrepare()
123
+ .prepareAsync();
124
+ }
125
+ else if (argv._[0] === "update") {
126
+ await new SdCliNpm(process.cwd())
127
+ .updateAsync();
128
+ }
129
+ else if (argv._[0] === "local-update") {
130
+ await new SdCliLocalUpdate(process.cwd())
131
+ .runAsync({
132
+ confFileRelPath: argv.config ?? "simplysm.json"
133
+ });
94
134
  }
95
135
  else if (argv._[0] === "watch") {
96
- await new SdCliWorkspace(process.cwd(), argv.config)
97
- .watchAsync();
136
+ await new SdCliWorkspace(process.cwd())
137
+ .watchAsync({
138
+ confFileRelPath: argv.config ?? "simplysm.json",
139
+ optNames: argv.options ?? []
140
+ });
98
141
  }
99
142
  else if (argv._[0] === "build") {
100
- await new SdCliWorkspace(process.cwd(), argv.config)
101
- .buildAsync();
143
+ await new SdCliWorkspace(process.cwd())
144
+ .buildAsync({
145
+ confFileRelPath: argv.config ?? "simplysm.json",
146
+ optNames: argv.options ?? []
147
+ });
102
148
  }
103
149
  else if (argv._[0] === "publish") {
104
- await new SdCliWorkspace(process.cwd(), argv.config)
150
+ await new SdCliWorkspace(process.cwd())
105
151
  .publishAsync({
106
- noBuild: argv.noBuild
152
+ noBuild: argv.noBuild,
153
+ confFileRelPath: argv.config ?? "simplysm.json",
154
+ optNames: argv.options ?? []
107
155
  });
108
156
  }
109
157
  else {
@@ -0,0 +1,361 @@
1
+ import { INpmConfig, ISdCliPackageBuildResult, ISdCliServerPackageConfig } from "../commons";
2
+ import { EventEmitter } from "events";
3
+ import { FsUtil, Logger, PathUtil } from "@simplysm/sd-core-node";
4
+ import webpack from "webpack";
5
+ import path from "path";
6
+ import ts from "typescript";
7
+ import { SdCliBuildResultUtil } from "../utils/SdCliBuildResultUtil";
8
+ import { ErrorInfo } from "ts-loader/dist/interfaces";
9
+ import os from "os";
10
+ import { ESLint } from "eslint";
11
+ import * as webpackMerge from "webpack-merge";
12
+ import TerserPlugin from "terser-webpack-plugin";
13
+ import { StringUtil } from "@simplysm/sd-core-common";
14
+ import ESLintWebpackPlugin from "eslint-webpack-plugin";
15
+ import CopyWebpackPlugin from "copy-webpack-plugin";
16
+ import { LicenseWebpackPlugin } from "license-webpack-plugin";
17
+ import LintResult = ESLint.LintResult;
18
+
19
+ export class SdCliServerBuilder extends EventEmitter {
20
+ private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
21
+
22
+ private readonly _tsconfigFilePath: string;
23
+ private readonly _parsedTsconfig: ts.ParsedCommandLine;
24
+ private readonly _npmConfigMap = new Map<string, INpmConfig>();
25
+
26
+ public constructor(private readonly _rootPath: string,
27
+ private readonly _config: ISdCliServerPackageConfig,
28
+ private readonly _workspaceRootPath: string) {
29
+ super();
30
+
31
+ // tsconfig
32
+ this._tsconfigFilePath = path.resolve(this._rootPath, "tsconfig-build.json");
33
+ const tsconfig = FsUtil.readJson(this._tsconfigFilePath);
34
+ this._parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._rootPath);
35
+ }
36
+
37
+ public override on(event: "change", listener: () => void): this;
38
+ public override on(event: "complete", listener: (results: ISdCliPackageBuildResult[]) => void): this;
39
+ public override on(event: string | symbol, listener: (...args: any[]) => void): this {
40
+ return super.on(event, listener);
41
+ }
42
+
43
+ public async watchAsync(): Promise<void> {
44
+ // DIST 비우기
45
+ await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
46
+
47
+ // 빌드 준비
48
+ const webpackConfig = this._getWebpackWatchConfig();
49
+ const compiler = webpack(webpackConfig);
50
+ await new Promise<void>((resolve, reject) => {
51
+ compiler.hooks.watchRun.tapAsync(this.constructor.name, (args, callback) => {
52
+ this.emit("change");
53
+ callback();
54
+
55
+ this._logger.debug("Webpack 빌드 수행...");
56
+ });
57
+
58
+ compiler.watch({}, (err, stats) => {
59
+ if (err != null || stats == null) {
60
+ reject(err);
61
+ return;
62
+ }
63
+
64
+ const results = SdCliBuildResultUtil.convertFromWebpackStats(stats);
65
+ this.emit("complete", results);
66
+
67
+ this._logger.debug("Webpack 빌드 완료");
68
+ resolve();
69
+ });
70
+ });
71
+ }
72
+
73
+ public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
74
+ // DIST 비우기
75
+ await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
76
+
77
+ // 빌드
78
+ this._logger.debug("Webpack 빌드 수행...");
79
+ const webpackConfig = this._getWebpackBuildConfig();
80
+ const compiler = webpack(webpackConfig);
81
+ const buildResults = await new Promise<ISdCliPackageBuildResult[]>((resolve, reject) => {
82
+ compiler.run((err, stats) => {
83
+ if (err != null || stats == null) {
84
+ reject(err);
85
+ return;
86
+ }
87
+
88
+ // 결과 리턴
89
+ const results = SdCliBuildResultUtil.convertFromWebpackStats(stats);
90
+ resolve(results);
91
+ });
92
+ });
93
+ this._logger.debug("Webpack 빌드 완료");
94
+
95
+ return buildResults;
96
+ }
97
+
98
+ private get _webpackCommonConfig(): webpack.Configuration {
99
+ return {
100
+ devtool: false,
101
+ target: ["node", "es2020"],
102
+ profile: false,
103
+ resolve: {
104
+ roots: [this._rootPath],
105
+ extensions: [".ts", ".js", ".mjs", ".cjs"],
106
+ symlinks: true,
107
+ mainFields: ["es2020", "default", "module", "main"]
108
+ },
109
+ context: this._workspaceRootPath,
110
+ entry: {
111
+ main: [
112
+ path.resolve(this._rootPath, "src/main.ts")
113
+ ]
114
+ },
115
+ output: {
116
+ clean: true,
117
+ path: this._parsedTsconfig.options.outDir,
118
+ filename: "[name].mjs",
119
+ chunkFilename: "[name].mjs",
120
+ assetModuleFilename: "res/[name][ext][query]",
121
+ libraryTarget: "module"
122
+ },
123
+ experiments: {
124
+ outputModule: true
125
+ },
126
+ performance: { hints: false },
127
+ node: false,
128
+ stats: "errors-warnings",
129
+ module: {
130
+ strictExportPresence: true,
131
+ rules: [
132
+ {
133
+ test: /\.m?js/,
134
+ resolve: {
135
+ fullySpecified: false
136
+ }
137
+ },
138
+ {
139
+ test: /\.ts$/,
140
+ exclude: /node_modules/,
141
+ loader: "ts-loader",
142
+ options: {
143
+ configFile: this._tsconfigFilePath,
144
+ errorFormatter: (msg: ErrorInfo) => {
145
+ return SdCliBuildResultUtil.getMessage({
146
+ filePath: msg.file,
147
+ line: msg.line,
148
+ char: msg.character,
149
+ code: "TS" + msg.code.toString(),
150
+ severity: msg.severity,
151
+ message: msg.content
152
+ });
153
+ }
154
+ }
155
+ },
156
+ {
157
+ test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico|otf|xlsx?|pptx?|docx?|zip|pfx|pkl)$/,
158
+ type: "asset/resource"
159
+ }
160
+ ]
161
+ },
162
+ plugins: [
163
+ new CopyWebpackPlugin({
164
+ patterns: ["assets/"].map((item) => ({
165
+ context: this._rootPath,
166
+ to: item,
167
+ from: `src/${item}`,
168
+ noErrorOnMissing: true,
169
+ force: true,
170
+ globOptions: {
171
+ dot: true,
172
+ followSymbolicLinks: false,
173
+ ignore: [
174
+ ".gitkeep",
175
+ "**/.DS_Store",
176
+ "**/Thumbs.db"
177
+ ].map((i) => PathUtil.posix(this._rootPath, i))
178
+ },
179
+ priority: 0
180
+ }))
181
+ }),
182
+ new webpack.EnvironmentPlugin({
183
+ SD_VERSION: this._getNpmConfig(this._rootPath)!.version,
184
+ ...this._config.env
185
+ }),
186
+ new ESLintWebpackPlugin({
187
+ context: this._rootPath,
188
+ extensions: ["ts", "js", "mjs", "cjs"],
189
+ fix: false,
190
+ threads: false,
191
+ formatter: (results: LintResult[]) => {
192
+ const resultMessages: string[] = [];
193
+ for (const result of results) {
194
+ for (const msg of result.messages) {
195
+ const severity = msg.severity === 1 ? "warning" : msg.severity === 2 ? "error" : undefined;
196
+ if (severity === undefined) continue;
197
+
198
+ resultMessages.push(SdCliBuildResultUtil.getMessage({
199
+ filePath: result.filePath,
200
+ line: msg.line,
201
+ char: msg.column,
202
+ code: msg.ruleId?.toString(),
203
+ severity,
204
+ message: msg.message
205
+ }));
206
+ }
207
+ }
208
+ return resultMessages.join(os.EOL);
209
+ }
210
+ }),
211
+ new webpack.ProgressPlugin({
212
+ handler: (per: number, msg: string, ...args: string[]) => {
213
+ const phaseText = msg ? ` - phase: ${msg}` : "";
214
+ const argsText = args.length > 0 ? ` - args: [${args.join(", ")}]` : "";
215
+ this._logger.debug(`Webpack 빌드 수행중...(${Math.round(per * 100)}%)${phaseText}${argsText}`);
216
+ }
217
+ })
218
+ ]
219
+ };
220
+ }
221
+
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 }[] {
298
+ const loadedModuleNames: string[] = [];
299
+ const externalModules: { name: string; path?: string }[] = [];
300
+
301
+ const fn = (currPath: string): void => {
302
+ const npmConfig = this._getNpmConfig(currPath);
303
+ if (!npmConfig) return;
304
+
305
+ const moduleNames = [
306
+ ...Object.keys(npmConfig.dependencies ?? {}),
307
+ ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => !npmConfig.peerDependenciesMeta?.[item].optional)
308
+ ];
309
+ const optModuleNames = [
310
+ ...Object.keys(npmConfig.optionalDependencies ?? {}),
311
+ ...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => npmConfig.peerDependenciesMeta?.[item].optional)
312
+ ].distinct();
313
+
314
+ for (const moduleName of moduleNames) {
315
+ if (loadedModuleNames.includes(moduleName)) continue;
316
+ loadedModuleNames.push(moduleName);
317
+
318
+ const modulePath = FsUtil.findAllParentChildDirPaths("node_modules/" + moduleName, currPath, this._workspaceRootPath).first();
319
+ if (StringUtil.isNullOrEmpty(modulePath)) {
320
+ console.log(2, currPath, moduleName);
321
+ continue;
322
+ }
323
+
324
+ if (all || FsUtil.exists(path.resolve(modulePath, "binding.gyp"))) {
325
+ externalModules.push({ path: modulePath, name: moduleName });
326
+ }
327
+
328
+ fn(modulePath);
329
+ }
330
+
331
+ for (const optModuleName of optModuleNames) {
332
+ if (loadedModuleNames.includes(optModuleName)) continue;
333
+ loadedModuleNames.push(optModuleName);
334
+
335
+ const optModulePath = FsUtil.findAllParentChildDirPaths("node_modules/" + optModuleName, currPath, this._workspaceRootPath).first();
336
+ if (StringUtil.isNullOrEmpty(optModulePath)) {
337
+ console.log(1, currPath, optModuleName);
338
+ externalModules.push({ path: optModulePath, name: optModuleName });
339
+ continue;
340
+ }
341
+
342
+ if (all || FsUtil.exists(path.resolve(optModulePath, "binding.gyp"))) {
343
+ externalModules.push({ path: optModulePath, name: optModuleName });
344
+ }
345
+
346
+ fn(optModulePath);
347
+ }
348
+ };
349
+
350
+ fn(this._rootPath);
351
+
352
+ return externalModules.distinct();
353
+ }
354
+
355
+ private _getNpmConfig(pkgPath: string): INpmConfig | undefined {
356
+ if (!this._npmConfigMap.has(pkgPath)) {
357
+ this._npmConfigMap.set(pkgPath, FsUtil.readJson(path.resolve(pkgPath, "package.json")));
358
+ }
359
+ return this._npmConfigMap.get(pkgPath);
360
+ }
361
+ }
@@ -165,7 +165,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
165
165
  results.push(
166
166
  ...diagnostics
167
167
  .filter((item) => [ts.DiagnosticCategory.Error, ts.DiagnosticCategory.Warning].includes(item.category))
168
- .map((item) => SdCliBuildResultUtil.convertDiagsToResult(item))
168
+ .map((item) => SdCliBuildResultUtil.convertFromTsDiag(item))
169
169
  .filterExists()
170
170
  );
171
171
 
package/src/commons.ts CHANGED
@@ -15,6 +15,7 @@ export interface INpmConfig {
15
15
  optionalDependencies?: Record<string, string>;
16
16
  devDependencies?: Record<string, string>;
17
17
  peerDependencies?: Record<string, string>;
18
+ peerDependenciesMeta?: Record<string, { optional?: boolean }>;
18
19
  }
19
20
 
20
21
  export interface ITsconfig {
@@ -39,17 +40,14 @@ export interface ISdCliConfig {
39
40
  localUpdates?: Record<string, string>;
40
41
  }
41
42
 
42
- export type TSdCliPackageConfig = ISdCliLibPackageConfig | ISdCliNgLibPackageConfig;
43
+ export type TSdCliPackageConfig = ISdCliLibPackageConfig | ISdCliServerPackageConfig;
43
44
 
44
45
  export interface ISdCliLibPackageConfig {
45
46
  type: "library";
46
47
  publish?: "npm";
47
48
  }
48
49
 
49
- export interface ISdCliNgLibPackageConfig {
50
- type: "angular";
51
- }
52
-
53
50
  export interface ISdCliServerPackageConfig {
54
51
  type: "server";
52
+ env?: Record<string, string>;
55
53
  }
@@ -5,13 +5,12 @@ import * as path from "path";
5
5
  export class SdCliLocalUpdate {
6
6
  private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
7
7
 
8
- public constructor(private readonly _rootPath: string,
9
- private readonly _configFilePath?: string) {
8
+ public constructor(private readonly _rootPath: string) {
10
9
  }
11
10
 
12
- public async runAsync(): Promise<void> {
11
+ public async runAsync(opt: { confFileRelPath: string }): Promise<void> {
13
12
  this._logger.debug("프로젝트 설정 가져오기...");
14
- const conf = SdCliConfigUtil.loadConfig(path.resolve(this._rootPath, this._configFilePath ?? "simplysm.json"), false);
13
+ const conf = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false);
15
14
  if (!conf.localUpdates) return;
16
15
 
17
16
  const updatePathInfos = await this._getUpdatePathInfosAsync(conf.localUpdates);
@@ -31,9 +30,9 @@ export class SdCliLocalUpdate {
31
30
  this._logger.info("로컬 라이브러리 업데이트 완료");
32
31
  }
33
32
 
34
- public async watchAsync(): Promise<void> {
33
+ public async watchAsync(opt: { confFileRelPath: string }): Promise<void> {
35
34
  this._logger.debug("프로젝트 설정 가져오기...");
36
- const conf = SdCliConfigUtil.loadConfig(path.resolve(this._rootPath, this._configFilePath ?? "simplysm.json"), false);
35
+ const conf = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false);
37
36
  if (!conf.localUpdates) return;
38
37
 
39
38
  const updatePathInfos = await this._getUpdatePathInfosAsync(conf.localUpdates);
@@ -0,0 +1,22 @@
1
+ import { Logger, SdProcess } from "@simplysm/sd-core-node";
2
+ import { SdCliPrepare } from "./SdCliPrepare";
3
+
4
+ export class SdCliNpm {
5
+ private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
6
+
7
+ public constructor(private readonly _rootPath: string) {
8
+ }
9
+
10
+ public async updateAsync(): Promise<void> {
11
+ this._logger.debug("업데이트할 패키지 확인...");
12
+ await SdProcess.execAsync("npm outdated", { cwd: this._rootPath });
13
+
14
+ this._logger.debug("업데이트 시작...");
15
+ await SdProcess.execAsync("npm update", { cwd: this._rootPath });
16
+
17
+ this._logger.debug("sd-cli 준비...");
18
+ await new SdCliPrepare().prepareAsync();
19
+
20
+ this._logger.info("노드 패키지 업데이트 완료");
21
+ }
22
+ }