@simplysm/sd-cli 7.0.248 → 7.0.266

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 (138) hide show
  1. package/README.md +95 -0
  2. package/assets/client-files/assets/icons/icon-128x128.png +0 -0
  3. package/assets/client-files/assets/icons/icon-144x144.png +0 -0
  4. package/assets/client-files/assets/icons/icon-152x152.png +0 -0
  5. package/assets/client-files/assets/icons/icon-192x192.png +0 -0
  6. package/assets/client-files/assets/icons/icon-384x384.png +0 -0
  7. package/assets/client-files/assets/icons/icon-512x512.png +0 -0
  8. package/assets/client-files/assets/icons/icon-72x72.png +0 -0
  9. package/assets/client-files/assets/icons/icon-96x96.png +0 -0
  10. package/assets/client-files/favicon.ico +0 -0
  11. package/dist/bin/sd-cli.mjs +212 -15
  12. package/dist/build-tool/SdCliCordova.mjs +3 -3
  13. package/dist/build-tool/SdCliElectron.mjs +3 -2
  14. package/dist/build-tool/SdCliIndexFileGenerator.mjs +2 -3
  15. package/dist/builder/SdCliClientBuilder.d.ts +2 -0
  16. package/dist/builder/SdCliClientBuilder.mjs +55 -18
  17. package/dist/builder/SdCliServerBuilder.d.ts +2 -0
  18. package/dist/builder/SdCliServerBuilder.mjs +27 -13
  19. package/dist/builder/SdCliTsLibBuilder.mjs +18 -12
  20. package/dist/commons.d.ts +6 -1
  21. package/dist/entry-points/SdCliPrepare.mjs +34 -34
  22. package/dist/entry-points/SdCliProjectGenerator.d.ts +44 -0
  23. package/dist/entry-points/SdCliProjectGenerator.mjs +320 -0
  24. package/dist/entry-points/SdCliWorkspace.d.ts +6 -6
  25. package/dist/entry-points/SdCliWorkspace.mjs +61 -107
  26. package/dist/entry-points/file/base/fc_package_eslintrc.d.ts +3 -0
  27. package/dist/entry-points/file/base/fc_package_eslintrc.mjs +31 -0
  28. package/dist/entry-points/file/base/fc_package_npmconfig.d.ts +9 -0
  29. package/dist/entry-points/file/base/fc_package_npmconfig.mjs +32 -0
  30. package/dist/entry-points/file/base/fc_package_tsconfig.d.ts +5 -0
  31. package/dist/entry-points/file/base/fc_package_tsconfig.mjs +13 -0
  32. package/dist/entry-points/file/client/fc_package_AppModule.d.ts +1 -0
  33. package/dist/entry-points/file/client/fc_package_AppModule.mjs +37 -0
  34. package/dist/entry-points/file/client/fc_package_AppPage.d.ts +1 -0
  35. package/dist/entry-points/file/client/fc_package_AppPage.mjs +14 -0
  36. package/dist/entry-points/file/client/fc_package_Page.d.ts +4 -0
  37. package/dist/entry-points/file/client/fc_package_Page.mjs +19 -0
  38. package/dist/entry-points/file/client/fc_package_client_main.d.ts +1 -0
  39. package/dist/entry-points/file/client/fc_package_client_main.mjs +19 -0
  40. package/dist/entry-points/file/client/fc_package_index.d.ts +3 -0
  41. package/dist/entry-points/file/client/fc_package_index.mjs +88 -0
  42. package/dist/entry-points/file/client/fc_package_manifest.d.ts +5 -0
  43. package/dist/entry-points/file/client/fc_package_manifest.mjs +54 -0
  44. package/dist/entry-points/file/client/fc_package_polyfills.d.ts +1 -0
  45. package/dist/entry-points/file/client/fc_package_polyfills.mjs +11 -0
  46. package/dist/entry-points/file/client/fc_package_styles.d.ts +1 -0
  47. package/dist/entry-points/file/client/fc_package_styles.mjs +7 -0
  48. package/dist/entry-points/file/db/fc_package_DbContext.d.ts +3 -0
  49. package/dist/entry-points/file/db/fc_package_DbContext.mjs +14 -0
  50. package/dist/entry-points/file/db/fc_package_DbModel.d.ts +4 -0
  51. package/dist/entry-points/file/db/fc_package_DbModel.mjs +12 -0
  52. package/dist/entry-points/file/project/fc_project_editor_config.d.ts +1 -0
  53. package/dist/entry-points/file/project/fc_project_editor_config.mjs +22 -0
  54. package/dist/entry-points/file/project/fc_project_eslintrc.d.ts +1 -0
  55. package/dist/entry-points/file/project/fc_project_eslintrc.mjs +30 -0
  56. package/dist/entry-points/file/project/fc_project_gitattributes.d.ts +1 -0
  57. package/dist/entry-points/file/project/fc_project_gitattributes.mjs +6 -0
  58. package/dist/entry-points/file/project/fc_project_gitignore.d.ts +1 -0
  59. package/dist/entry-points/file/project/fc_project_gitignore.mjs +17 -0
  60. package/dist/entry-points/file/project/fc_project_npmconfig.d.ts +7 -0
  61. package/dist/entry-points/file/project/fc_project_npmconfig.mjs +35 -0
  62. package/dist/entry-points/file/project/fc_project_readme.d.ts +3 -0
  63. package/dist/entry-points/file/project/fc_project_readme.mjs +13 -0
  64. package/dist/entry-points/file/project/fc_project_simplysm.d.ts +1 -0
  65. package/dist/entry-points/file/project/fc_project_simplysm.mjs +2 -0
  66. package/dist/entry-points/file/project/fc_project_tsconfig.d.ts +1 -0
  67. package/dist/entry-points/file/project/fc_project_tsconfig.mjs +26 -0
  68. package/dist/entry-points/file/server/fc_package_server_main.d.ts +4 -0
  69. package/dist/entry-points/file/server/fc_package_server_main.mjs +60 -0
  70. package/dist/index.d.ts +23 -0
  71. package/dist/index.mjs +24 -1
  72. package/dist/ng-tools/SdCliNgModuleGenerator.mjs +35 -36
  73. package/dist/packages/SdCliPackage.d.ts +1 -0
  74. package/dist/packages/SdCliPackage.mjs +69 -63
  75. package/dist/utils/SdCliBuildResultUtil.mjs +2 -2
  76. package/docs/client-add-page.md +8 -0
  77. package/docs/client-router.md +85 -0
  78. package/docs/client-sw.md +101 -0
  79. package/docs/conf-orm.md +81 -0
  80. package/docs/conf-usage.md +5 -0
  81. package/docs/lib-local-update.md +50 -0
  82. package/docs/lib-ts-paths.md +25 -0
  83. package/package.json +10 -8
  84. package/src/SdCliBuildResultError.ts +9 -9
  85. package/src/bin/sd-cli.ts +244 -15
  86. package/src/build-tool/SdCliCacheCompilerHost.ts +77 -77
  87. package/src/build-tool/SdCliCordova.ts +2 -2
  88. package/src/build-tool/SdCliElectron.ts +2 -1
  89. package/src/build-tool/SdCliGithubApi.ts +110 -110
  90. package/src/build-tool/SdCliIndexFileGenerator.ts +79 -80
  91. package/src/build-tool/SdCliNgCacheCompilerHost.ts +58 -58
  92. package/src/build-tool/SdCliPackageLinter.ts +74 -74
  93. package/src/builder/SdCliClientBuilder.ts +71 -20
  94. package/src/builder/SdCliJsLibBuilder.ts +70 -70
  95. package/src/builder/SdCliServerBuilder.ts +34 -14
  96. package/src/builder/SdCliTsLibBuilder.ts +450 -445
  97. package/src/commons.ts +6 -1
  98. package/src/entry-points/SdCliFileCrypto.ts +87 -87
  99. package/src/entry-points/SdCliPrepare.ts +55 -55
  100. package/src/entry-points/SdCliProjectGenerator.ts +395 -0
  101. package/src/entry-points/SdCliWorkspace.ts +74 -122
  102. package/src/entry-points/file/base/fc_package_eslintrc.ts +30 -0
  103. package/src/entry-points/file/base/fc_package_npmconfig.ts +43 -0
  104. package/src/entry-points/file/base/fc_package_tsconfig.ts +12 -0
  105. package/src/entry-points/file/client/fc_package_AppModule.ts +36 -0
  106. package/src/entry-points/file/client/fc_package_AppPage.ts +13 -0
  107. package/src/entry-points/file/client/fc_package_Page.ts +19 -0
  108. package/src/entry-points/file/client/fc_package_client_main.ts +18 -0
  109. package/src/entry-points/file/client/fc_package_index.ts +87 -0
  110. package/src/entry-points/file/client/fc_package_manifest.ts +53 -0
  111. package/src/entry-points/file/client/fc_package_polyfills.ts +10 -0
  112. package/src/entry-points/file/client/fc_package_styles.ts +6 -0
  113. package/src/entry-points/file/db/fc_package_DbContext.ts +14 -0
  114. package/src/entry-points/file/db/fc_package_DbModel.ts +11 -0
  115. package/src/entry-points/file/project/fc_project_editor_config.ts +21 -0
  116. package/src/entry-points/file/project/fc_project_eslintrc.ts +29 -0
  117. package/src/entry-points/file/project/fc_project_gitattributes.ts +5 -0
  118. package/src/entry-points/file/project/fc_project_gitignore.ts +16 -0
  119. package/src/entry-points/file/project/fc_project_npmconfig.ts +34 -0
  120. package/src/entry-points/file/project/fc_project_readme.ts +12 -0
  121. package/src/entry-points/file/project/fc_project_simplysm.ts +1 -0
  122. package/src/entry-points/file/project/fc_project_tsconfig.ts +25 -0
  123. package/src/entry-points/file/server/fc_package_server_main.ts +62 -0
  124. package/src/index.ts +55 -32
  125. package/src/ng-tools/SdCliNgModuleGenerator.ts +639 -640
  126. package/src/ng-tools/babel/SdCliBbFileMetadata.ts +568 -568
  127. package/src/ng-tools/babel/SdCliBbRootMetadata.ts +239 -239
  128. package/src/ng-tools/babel/SdCliBbUtil.ts +15 -15
  129. package/src/ng-tools/babel/TSdCliBbNgMetadata.ts +234 -234
  130. package/src/ng-tools/babel/TSdCliBbTypeMetadata.ts +177 -177
  131. package/src/ng-tools/commons.ts +3 -3
  132. package/src/ng-tools/typescript/SdCliTsFileMetadata.ts +384 -384
  133. package/src/ng-tools/typescript/SdCliTsRootMetadata.ts +32 -32
  134. package/src/ng-tools/typescript/SdCliTsUtil.ts +29 -29
  135. package/src/packages/SdCliPackage.ts +76 -59
  136. package/src/utils/SdCliBuildResultUtil.ts +76 -76
  137. package/src/utils/SdCliConfigUtil.ts +94 -94
  138. package/src/utils/SdCliNpmConfigUtil.ts +16 -16
@@ -1,58 +1,58 @@
1
- import ts from "typescript";
2
- import { PathUtil } from "@simplysm/sd-core-node";
3
- import sass from "sass";
4
- import { fileURLToPath, pathToFileURL, URL } from "url";
5
-
6
- export class SdCliNgCacheCompilerHost {
7
- public static wrap(compilerHost: ts.CompilerHost,
8
- sourceFileCache: Map<string, IFileCache>): ts.CompilerHost {
9
- const cacheCompilerHost = { ...compilerHost };
10
-
11
- cacheCompilerHost["readResource"] = (fileName: string) => {
12
- const cache = sourceFileCache.getOrCreate(PathUtil.posix(fileName), {});
13
- if (cache.content === undefined) {
14
- cache.content = compilerHost.readFile.call(cacheCompilerHost, fileName);
15
- }
16
- return cache.content;
17
- };
18
-
19
- cacheCompilerHost["transformResource"] = async (data, context) => {
20
- if (context.resourceFile != null || context.type !== "style") {
21
- return null;
22
- }
23
-
24
- const cache = sourceFileCache.getOrCreate(PathUtil.posix(context.containingFile), {});
25
- if (cache.styleContent === undefined) {
26
- const scssResult = await sass.compileStringAsync(data, {
27
- url: new URL((context.containingFile as string) + ".sd.scss"),
28
- importer: {
29
- findFileUrl: (url) => {
30
- if (!url.startsWith("~")) return pathToFileURL(url);
31
- return new URL(url.substring(1), pathToFileURL("node_modules"));
32
- }
33
- }
34
- });
35
-
36
- cache.styleContent = scssResult.css.toString();
37
-
38
- const deps = scssResult.loadedUrls.slice(1).map((item) => PathUtil.posix(fileURLToPath(item.href)));
39
- for (const dep of deps) {
40
- const depCache = sourceFileCache.getOrCreate(dep, {});
41
- depCache.importerSet = depCache.importerSet ?? new Set<string>();
42
- depCache.importerSet.add(PathUtil.posix(context.containingFile));
43
- }
44
- }
45
- return { content: cache.styleContent };
46
- };
47
-
48
- return cacheCompilerHost;
49
- }
50
- }
51
-
52
- interface IFileCache {
53
- exists?: boolean;
54
- sourceFile?: ts.SourceFile;
55
- content?: string;
56
- styleContent?: string;
57
- importerSet?: Set<string>;
58
- }
1
+ import ts from "typescript";
2
+ import { PathUtil } from "@simplysm/sd-core-node";
3
+ import sass from "sass";
4
+ import { fileURLToPath, pathToFileURL, URL } from "url";
5
+
6
+ export class SdCliNgCacheCompilerHost {
7
+ public static wrap(compilerHost: ts.CompilerHost,
8
+ sourceFileCache: Map<string, IFileCache>): ts.CompilerHost {
9
+ const cacheCompilerHost = { ...compilerHost };
10
+
11
+ cacheCompilerHost["readResource"] = (fileName: string) => {
12
+ const cache = sourceFileCache.getOrCreate(PathUtil.posix(fileName), {});
13
+ if (cache.content === undefined) {
14
+ cache.content = compilerHost.readFile.call(cacheCompilerHost, fileName);
15
+ }
16
+ return cache.content;
17
+ };
18
+
19
+ cacheCompilerHost["transformResource"] = async (data, context) => {
20
+ if (context.resourceFile != null || context.type !== "style") {
21
+ return null;
22
+ }
23
+
24
+ const cache = sourceFileCache.getOrCreate(PathUtil.posix(context.containingFile), {});
25
+ if (cache.styleContent === undefined) {
26
+ const scssResult = await sass.compileStringAsync(data, {
27
+ url: new URL((context.containingFile as string) + ".sd.scss"),
28
+ importer: {
29
+ findFileUrl: (url) => {
30
+ if (!url.startsWith("~")) return pathToFileURL(url);
31
+ return new URL(url.substring(1), pathToFileURL("node_modules"));
32
+ }
33
+ }
34
+ });
35
+
36
+ cache.styleContent = scssResult.css.toString();
37
+
38
+ const deps = scssResult.loadedUrls.slice(1).map((item) => PathUtil.posix(fileURLToPath(item.href)));
39
+ for (const dep of deps) {
40
+ const depCache = sourceFileCache.getOrCreate(dep, {});
41
+ depCache.importerSet = depCache.importerSet ?? new Set<string>();
42
+ depCache.importerSet.add(PathUtil.posix(context.containingFile));
43
+ }
44
+ }
45
+ return { content: cache.styleContent };
46
+ };
47
+
48
+ return cacheCompilerHost;
49
+ }
50
+ }
51
+
52
+ interface IFileCache {
53
+ exists?: boolean;
54
+ sourceFile?: ts.SourceFile;
55
+ content?: string;
56
+ styleContent?: string;
57
+ importerSet?: Set<string>;
58
+ }
@@ -1,74 +1,74 @@
1
- import { ISdCliPackageBuildResult } from "../commons";
2
- import ts from "typescript";
3
- import { FsUtil } from "@simplysm/sd-core-node";
4
- import path from "path";
5
- import { ESLint } from "eslint";
6
-
7
- export class SdCliPackageLinter {
8
- private readonly _lintResultCache = new Map<string, ISdCliPackageBuildResult[]>();
9
-
10
- public constructor(private readonly _rootPath: string) {
11
- }
12
-
13
- public async lintAsync(filePaths: string[], program?: ts.Program): Promise<ISdCliPackageBuildResult[]> {
14
- if (!FsUtil.exists(path.resolve(this._rootPath, ".eslintrc.cjs"))) return [];
15
-
16
- const linter = new ESLint(
17
- program && filePaths.some((item) => item.endsWith(".ts")) ? {
18
- overrideConfig: {
19
- overrides: [
20
- {
21
- files: ["*.ts"],
22
- parserOptions: {
23
- /*programs: [program],
24
- tsconfigRootDir: null,
25
- project: null*/
26
- tsconfigRootDir: this._rootPath,
27
- project: "tsconfig-build.json"
28
- },
29
- settings: {
30
- "import/resolver": {
31
- "typescript": {
32
- /*programs: [program],
33
- project: null*/
34
- project: path.resolve(this._rootPath, "tsconfig-build.json")
35
- }
36
- }
37
- }
38
- }
39
- ]
40
- }
41
- } : {}
42
- );
43
-
44
- const lintFilePaths = await filePaths
45
- .filterAsync(async (filePath) => (
46
- !filePath.endsWith(".d.ts") &&
47
- /\.[cm]?[tj]sx?$/.test(filePath) &&
48
- !(await linter.isPathIgnored(filePath))
49
- ));
50
- for (const lintFilePath of lintFilePaths) {
51
- this._lintResultCache.delete(lintFilePath);
52
- }
53
-
54
- const lintResults = await linter.lintFiles(lintFilePaths);
55
-
56
- const result = lintResults.map((lintResult) => ({
57
- filePath: lintResult.filePath,
58
- results: lintResult.messages.map((msg) => ({
59
- filePath: lintResult.filePath,
60
- line: msg.line,
61
- char: msg.column,
62
- code: msg.ruleId ?? undefined,
63
- severity: msg.severity === 1 ? "warning" as const : "error" as const,
64
- message: msg.message
65
- }))
66
- }));
67
-
68
- for (const resultItem of result) {
69
- this._lintResultCache.set(resultItem.filePath, resultItem.results);
70
- }
71
-
72
- return Array.from(this._lintResultCache.values()).mapMany();
73
- }
74
- }
1
+ import { ISdCliPackageBuildResult } from "../commons";
2
+ import ts from "typescript";
3
+ import { FsUtil } from "@simplysm/sd-core-node";
4
+ import path from "path";
5
+ import { ESLint } from "eslint";
6
+
7
+ export class SdCliPackageLinter {
8
+ private readonly _lintResultCache = new Map<string, ISdCliPackageBuildResult[]>();
9
+
10
+ public constructor(private readonly _rootPath: string) {
11
+ }
12
+
13
+ public async lintAsync(filePaths: string[], program?: ts.Program): Promise<ISdCliPackageBuildResult[]> {
14
+ if (!FsUtil.exists(path.resolve(this._rootPath, ".eslintrc.cjs"))) return [];
15
+
16
+ const linter = new ESLint(
17
+ program && filePaths.some((item) => item.endsWith(".ts")) ? {
18
+ overrideConfig: {
19
+ overrides: [
20
+ {
21
+ files: ["*.ts"],
22
+ parserOptions: {
23
+ /*programs: [program],
24
+ tsconfigRootDir: null,
25
+ project: null*/
26
+ tsconfigRootDir: this._rootPath,
27
+ project: "tsconfig-build.json"
28
+ },
29
+ settings: {
30
+ "import/resolver": {
31
+ "typescript": {
32
+ /*programs: [program],
33
+ project: null*/
34
+ project: path.resolve(this._rootPath, "tsconfig-build.json")
35
+ }
36
+ }
37
+ }
38
+ }
39
+ ]
40
+ }
41
+ } : {}
42
+ );
43
+
44
+ const lintFilePaths = await filePaths
45
+ .filterAsync(async (filePath) => (
46
+ !filePath.endsWith(".d.ts") &&
47
+ /\.[cm]?[tj]sx?$/.test(filePath) &&
48
+ !(await linter.isPathIgnored(filePath))
49
+ ));
50
+ for (const lintFilePath of lintFilePaths) {
51
+ this._lintResultCache.delete(lintFilePath);
52
+ }
53
+
54
+ const lintResults = await linter.lintFiles(lintFilePaths);
55
+
56
+ const result = lintResults.map((lintResult) => ({
57
+ filePath: lintResult.filePath,
58
+ results: lintResult.messages.map((msg) => ({
59
+ filePath: lintResult.filePath,
60
+ line: msg.line,
61
+ char: msg.column,
62
+ code: msg.ruleId ?? undefined,
63
+ severity: msg.severity === 1 ? "warning" as const : "error" as const,
64
+ message: msg.message
65
+ }))
66
+ }));
67
+
68
+ for (const resultItem of result) {
69
+ this._lintResultCache.set(resultItem.filePath, resultItem.results);
70
+ }
71
+
72
+ return Array.from(this._lintResultCache.values()).mapMany();
73
+ }
74
+ }
@@ -46,6 +46,8 @@ export class SdCliClientBuilder extends EventEmitter {
46
46
 
47
47
  private readonly _hasAngularRoute: boolean;
48
48
 
49
+ private readonly _cacheBasePath = path.resolve(this._rootPath, ".cache");
50
+
49
51
  public constructor(private readonly _rootPath: string,
50
52
  private readonly _config: ISdCliClientPackageConfig,
51
53
  private readonly _workspaceRootPath: string) {
@@ -92,11 +94,39 @@ export class SdCliClientBuilder extends EventEmitter {
92
94
  return super.on(event, listener);
93
95
  }
94
96
 
97
+ private async _checkCacheAsync(watch: boolean): Promise<void> {
98
+ const workspacePkgLockContent = await FsUtil.readFileAsync(path.resolve(this._workspaceRootPath, "package-lock.json"));
99
+
100
+ // const cachePath = path.resolve(cacheBasePath, pkgVersion);
101
+
102
+ const versionHash = createHash("sha1")
103
+ .update(workspacePkgLockContent)
104
+ .update(JSON.stringify(this._parsedTsconfig.options))
105
+ .update(JSON.stringify(this._config))
106
+ .update(watch.toString())
107
+ .digest("hex");
108
+ if (
109
+ !FsUtil.exists(path.resolve(this._cacheBasePath, "version")) // 버전파일이 없거나
110
+ || (
111
+ FsUtil.exists(path.resolve(this._cacheBasePath, "version")) &&
112
+ await FsUtil.readFileAsync(path.resolve(this._cacheBasePath, "version")) !== versionHash
113
+ ) // 버전이 현재 버전과 다르면
114
+ ) {
115
+ // 캐시 삭제
116
+ await FsUtil.removeAsync(path.resolve(this._cacheBasePath));
117
+ }
118
+ // 버전쓰기
119
+ await FsUtil.writeFileAsync(path.resolve(this._cacheBasePath, "version"), versionHash);
120
+ }
121
+
95
122
  public async watchAsync(): Promise<void> {
96
123
  // DIST 비우기
97
124
  await FsUtil.removeAsync(path.resolve(this._rootPath, ".electron"));
98
125
  await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
99
126
 
127
+ // 캐시체크
128
+ await this._checkCacheAsync(true);
129
+
100
130
  // NgModule 생성
101
131
  await this._ngModuleGenerator.runAsync();
102
132
 
@@ -111,11 +141,15 @@ export class SdCliClientBuilder extends EventEmitter {
111
141
  .map((builderType) => this._getWebpackConfig(true, builderType));
112
142
  const multiCompiler = webpack(webpackConfigs);
113
143
  await new Promise<void>((resolve, reject) => {
144
+ const invalidFiles: string[] = [];
114
145
  multiCompiler.hooks.invalid.tap(this.constructor.name, (fileName) => {
115
146
  if (fileName != null) {
116
147
  this._logger.debug("파일변경 감지", fileName);
148
+
117
149
  // NgModule 캐시 삭제
118
150
  this._ngModuleGenerator.removeCaches([path.resolve(fileName)]);
151
+
152
+ invalidFiles.push(fileName);
119
153
  }
120
154
  });
121
155
 
@@ -144,9 +178,6 @@ export class SdCliClientBuilder extends EventEmitter {
144
178
  return;
145
179
  }
146
180
 
147
- // 결과 반환
148
- const results = multiStats.stats.mapMany((stats) => SdCliBuildResultUtil.convertFromWebpackStats(stats));
149
-
150
181
  // .config.json 파일 쓰기
151
182
  const npmConfig = this._getNpmConfig(this._rootPath)!;
152
183
  const packageKey = npmConfig.name.split("/").last()!;
@@ -156,11 +187,14 @@ export class SdCliClientBuilder extends EventEmitter {
156
187
  : path.resolve(this._parsedTsconfig.options.outDir!, ".config.json");
157
188
  await FsUtil.writeFileAsync(configDistPath, JSON.stringify(this._config.configs ?? {}, undefined, 2));
158
189
 
159
- // 마무리
190
+ // 완료 로그
160
191
  this._logger.debug("Webpack 빌드 완료");
161
- resolve();
162
192
 
193
+ // 결과 반환
194
+ const results = multiStats.stats.mapMany((stats) => SdCliBuildResultUtil.convertFromWebpackStats(stats));
163
195
  this.emit("complete", results);
196
+
197
+ resolve();
164
198
  });
165
199
  });
166
200
  }
@@ -172,6 +206,9 @@ export class SdCliClientBuilder extends EventEmitter {
172
206
  this._logger.debug("removeAsync:2");
173
207
  await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
174
208
 
209
+ // 캐시체크
210
+ await this._checkCacheAsync(false);
211
+
175
212
  // NgModule 생성
176
213
  this._logger.debug("ngModule");
177
214
  await this._ngModuleGenerator.runAsync();
@@ -211,7 +248,7 @@ export class SdCliClientBuilder extends EventEmitter {
211
248
  await augmentAppWithServiceWorker(
212
249
  PathUtil.posix(path.relative(this._workspaceRootPath, this._rootPath)) as any,
213
250
  PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._parsedTsconfig.options.outDir!))) as any,
214
- `/${packageKey}/`,
251
+ `/${packageKey}/` as any,
215
252
  PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._rootPath, "ngsw-config.json")))
216
253
  );
217
254
  }
@@ -264,7 +301,8 @@ export class SdCliClientBuilder extends EventEmitter {
264
301
  "NODE_ENV=production",
265
302
  `SD_VERSION=${npmConfig.version}`,
266
303
  (this._config.builder.electron.icon !== undefined) ? `SD_ELECTRON_ICON=${this._config.builder.electron.icon}` : `SD_ELECTRON_ICON=favicon.ico`,
267
- ...(this._config.env !== undefined) ? Object.keys(this._config.env).map((key) => `${key}=${this._config.env![key]}`) : []
304
+ ...(this._config.env !== undefined) ? Object.keys(this._config.env).map((key) => `${key}=${this._config.env![key]}`) : [],
305
+ ...(this._config.builder.electron.env !== undefined) ? Object.keys(this._config.builder.electron.env).map((key) => `${key}=${this._config.builder!.electron!.env![key]}`) : []
268
306
  ].filterExists().join("\n"));
269
307
 
270
308
  let electronTsFileContent = await FsUtil.readFileAsync(path.resolve(this._rootPath, `src/electron.ts`));
@@ -328,8 +366,6 @@ export class SdCliClientBuilder extends EventEmitter {
328
366
  const pkgKey = npmConfig.name.split("/").last()!;
329
367
  const publicPath = builderType === "web" ? `/${pkgKey}/` : watch ? `/${pkgKey}/${builderType}/` : ``;
330
368
 
331
- const cacheBasePath = path.resolve(this._rootPath, ".cache");
332
-
333
369
  const distPath = (builderType === "cordova" && !watch) ? path.resolve(this._cordova!.cordovaPath, "www")
334
370
  : (builderType === "electron" && !watch) ? path.resolve(this._rootPath, ".electron/src")
335
371
  : builderType === "web" ? this._parsedTsconfig.options.outDir
@@ -341,6 +377,25 @@ export class SdCliClientBuilder extends EventEmitter {
341
377
  const polyfillsFilePath = path.resolve(this._rootPath, "src/polyfills.ts");
342
378
  const stylesFilePath = path.resolve(this._rootPath, "src/styles.scss");
343
379
 
380
+ const versionHash = createHash("sha1")
381
+ .update(workspacePkgLockContent)
382
+ .update(JSON.stringify(this._parsedTsconfig.options))
383
+ .update(JSON.stringify(this._config))
384
+ .update(watch.toString())
385
+ .digest("hex");
386
+ if (
387
+ !FsUtil.exists(path.resolve(this._cacheBasePath, "version")) // 버전파일이 없거나
388
+ || (
389
+ FsUtil.exists(path.resolve(this._cacheBasePath, "version")) &&
390
+ FsUtil.readFile(path.resolve(this._cacheBasePath, "version")) !== versionHash
391
+ ) // 버전이 현재 버전과 다르면
392
+ ) {
393
+ // 캐시 삭제
394
+ FsUtil.remove(path.resolve(this._cacheBasePath));
395
+ }
396
+ // 버전쓰기
397
+ FsUtil.writeFile(path.resolve(this._cacheBasePath, "version"), versionHash);
398
+
344
399
  let prevProgressMessage = "";
345
400
  return {
346
401
  mode: watch ? "development" : "production",
@@ -395,14 +450,9 @@ export class SdCliClientBuilder extends EventEmitter {
395
450
  cache: {
396
451
  type: "filesystem",
397
452
  profile: undefined,
398
- cacheDirectory: path.resolve(cacheBasePath, "angular-webpack"),
453
+ cacheDirectory: this._cacheBasePath,
399
454
  maxMemoryGenerations: 1,
400
- name: createHash("sha1")
401
- .update(workspacePkgLockContent)
402
- .update(JSON.stringify(this._parsedTsconfig.options))
403
- .update(JSON.stringify(this._config))
404
- .update(watch.toString())
405
- .digest("hex")
455
+ name: "webpack"
406
456
  },
407
457
  snapshot: {
408
458
  immutablePaths: internalModuleCachePaths,
@@ -482,7 +532,7 @@ export class SdCliClientBuilder extends EventEmitter {
482
532
  {
483
533
  loader: "@angular-devkit/build-angular/src/babel/webpack-loader",
484
534
  options: {
485
- cacheDirectory: path.resolve(cacheBasePath, "babel-webpack"),
535
+ cacheDirectory: path.resolve(this._cacheBasePath, "webpack-babel"),
486
536
  scriptTarget: ts.ScriptTarget.ES2017,
487
537
  aot: true,
488
538
  optimize: !watch,
@@ -689,8 +739,8 @@ export class SdCliClientBuilder extends EventEmitter {
689
739
  sri: false,
690
740
  cache: {
691
741
  enabled: true,
692
- basePath: cacheBasePath,
693
- path: path.resolve(cacheBasePath, "index-webpack")
742
+ basePath: this._cacheBasePath,
743
+ path: path.resolve(this._cacheBasePath, "webpack-html")
694
744
  },
695
745
  postTransform: undefined,
696
746
  optimization: {
@@ -703,7 +753,8 @@ export class SdCliClientBuilder extends EventEmitter {
703
753
  }),
704
754
  new webpack.EnvironmentPlugin({
705
755
  SD_VERSION: this._getNpmConfig(this._rootPath)!.version,
706
- ...this._config.env
756
+ ...this._config.env,
757
+ ...this._config.builder?.[builderType]?.env
707
758
  }),
708
759
  new ESLintWebpackPlugin({
709
760
  context: this._rootPath,
@@ -1,70 +1,70 @@
1
- import { ISdCliPackageBuildResult } from "../commons";
2
- import { EventEmitter } from "events";
3
- import { FsUtil, Logger, SdFsWatcher } from "@simplysm/sd-core-node";
4
- import path from "path";
5
- import { SdCliPackageLinter } from "../build-tool/SdCliPackageLinter";
6
-
7
- export class SdCliJsLibBuilder extends EventEmitter {
8
- private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
9
-
10
- private readonly _linter: SdCliPackageLinter;
11
-
12
- public constructor(private readonly _rootPath: string) {
13
- super();
14
- this._linter = new SdCliPackageLinter(this._rootPath);
15
- }
16
-
17
- public override on(event: "change", listener: () => void): this;
18
- public override on(event: "complete", listener: (results: ISdCliPackageBuildResult[]) => void): this;
19
- public override on(event: string | symbol, listener: (...args: any[]) => void): this {
20
- return super.on(event, listener);
21
- }
22
-
23
- public async watchAsync(): Promise<void> {
24
- this.emit("change");
25
-
26
- const relatedPaths = await this.getRelatedPathsAsync();
27
- const watcher = SdFsWatcher.watch(relatedPaths);
28
- watcher.onChange({}, async (changedInfos) => {
29
- const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
30
- if (changeFilePaths.length === 0) return;
31
-
32
- this._logger.debug("파일 변경 감지");
33
- this.emit("change");
34
- const watchBuildResults: ISdCliPackageBuildResult[] = [];
35
-
36
- const lintFilePaths = changedInfos.filter((item) => ["add", "change"].includes(item.event)).map((item) => item.path);
37
- if (lintFilePaths.length > 0) {
38
- watchBuildResults.push(...await this._linter.lintAsync(lintFilePaths));
39
- }
40
-
41
- const watchRelatedPaths = await this.getRelatedPathsAsync();
42
- watcher.add(watchRelatedPaths);
43
-
44
- this.emit("complete", watchBuildResults);
45
- });
46
-
47
- // 빌드
48
- const buildResults = await this._linter.lintAsync(relatedPaths);
49
-
50
- this.emit("complete", buildResults);
51
- }
52
-
53
- public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
54
- const relatedPaths = await this.getRelatedPathsAsync();
55
- return await this._linter.lintAsync(relatedPaths);
56
- }
57
-
58
- private async getRelatedPathsAsync(): Promise<string[]> {
59
- const mySourceGlobPath = path.resolve(this._rootPath, "**", "+(*.js|*.cjs|*.mjs)");
60
- const mySourceFilePaths = await FsUtil.globAsync(mySourceGlobPath, {
61
- ignore: [
62
- "**/node_modules/**",
63
- "**/dist/**",
64
- "**/.*/**"
65
- ]
66
- });
67
-
68
- return [...mySourceFilePaths, path.resolve(this._rootPath, ".eslintrc.cjs")].distinct();
69
- }
70
- }
1
+ import { ISdCliPackageBuildResult } from "../commons";
2
+ import { EventEmitter } from "events";
3
+ import { FsUtil, Logger, SdFsWatcher } from "@simplysm/sd-core-node";
4
+ import path from "path";
5
+ import { SdCliPackageLinter } from "../build-tool/SdCliPackageLinter";
6
+
7
+ export class SdCliJsLibBuilder extends EventEmitter {
8
+ private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
9
+
10
+ private readonly _linter: SdCliPackageLinter;
11
+
12
+ public constructor(private readonly _rootPath: string) {
13
+ super();
14
+ this._linter = new SdCliPackageLinter(this._rootPath);
15
+ }
16
+
17
+ public override on(event: "change", listener: () => void): this;
18
+ public override on(event: "complete", listener: (results: ISdCliPackageBuildResult[]) => void): this;
19
+ public override on(event: string | symbol, listener: (...args: any[]) => void): this {
20
+ return super.on(event, listener);
21
+ }
22
+
23
+ public async watchAsync(): Promise<void> {
24
+ this.emit("change");
25
+
26
+ const relatedPaths = await this.getRelatedPathsAsync();
27
+ const watcher = SdFsWatcher.watch(relatedPaths);
28
+ watcher.onChange({}, async (changedInfos) => {
29
+ const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
30
+ if (changeFilePaths.length === 0) return;
31
+
32
+ this._logger.debug("파일 변경 감지");
33
+ this.emit("change");
34
+ const watchBuildResults: ISdCliPackageBuildResult[] = [];
35
+
36
+ const lintFilePaths = changedInfos.filter((item) => ["add", "change"].includes(item.event)).map((item) => item.path);
37
+ if (lintFilePaths.length > 0) {
38
+ watchBuildResults.push(...await this._linter.lintAsync(lintFilePaths));
39
+ }
40
+
41
+ const watchRelatedPaths = await this.getRelatedPathsAsync();
42
+ watcher.add(watchRelatedPaths);
43
+
44
+ this.emit("complete", watchBuildResults);
45
+ });
46
+
47
+ // 빌드
48
+ const buildResults = await this._linter.lintAsync(relatedPaths);
49
+
50
+ this.emit("complete", buildResults);
51
+ }
52
+
53
+ public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
54
+ const relatedPaths = await this.getRelatedPathsAsync();
55
+ return await this._linter.lintAsync(relatedPaths);
56
+ }
57
+
58
+ private async getRelatedPathsAsync(): Promise<string[]> {
59
+ const mySourceGlobPath = path.resolve(this._rootPath, "**", "+(*.js|*.cjs|*.mjs)");
60
+ const mySourceFilePaths = await FsUtil.globAsync(mySourceGlobPath, {
61
+ ignore: [
62
+ "**/node_modules/**",
63
+ "**/dist/**",
64
+ "**/.*/**"
65
+ ]
66
+ });
67
+
68
+ return [...mySourceFilePaths, path.resolve(this._rootPath, ".eslintrc.cjs")].distinct();
69
+ }
70
+ }