@simplysm/sd-cli 6.0.26 → 6.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-node/bin/sd-cli.js +19 -4
- package/dist-node/bin/sd-cli.js.map +1 -1
- package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js +102 -49
- package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js.map +1 -1
- package/dist-node/build-tools/metadata/SdAotMetadataReader.js +6 -2
- package/dist-node/build-tools/metadata/SdAotMetadataReader.js.map +1 -1
- package/dist-node/build-tools/metadata/SdIvyMetadataReader.js +22 -5
- package/dist-node/build-tools/metadata/SdIvyMetadataReader.js.map +1 -1
- package/dist-node/build-tools/metadata/SdMetadataError.js +13 -0
- package/dist-node/build-tools/metadata/SdMetadataError.js.map +1 -0
- package/dist-node/build-tools/metadata/SdMyMetadataReader.js +22 -5
- package/dist-node/build-tools/metadata/SdMyMetadataReader.js.map +1 -1
- package/dist-node/builders/SdCliNgClientBuilder.js +73 -66
- package/dist-node/builders/SdCliNgClientBuilder.js.map +1 -1
- package/dist-node/builders/SdCliNgLibraryBuilder.js +52 -24
- package/dist-node/builders/SdCliNgLibraryBuilder.js.map +1 -1
- package/dist-node/builders/SdCliServerBuilder.js +45 -44
- package/dist-node/builders/SdCliServerBuilder.js.map +1 -1
- package/dist-node/builders/SdCliTypescriptBuilder.js +64 -59
- package/dist-node/builders/SdCliTypescriptBuilder.js.map +1 -1
- package/dist-node/entry-points/SdCliLocalUpdater.js +30 -29
- package/dist-node/entry-points/SdCliLocalUpdater.js.map +1 -1
- package/dist-node/entry-points/SdCliProject.js +10 -16
- package/dist-node/entry-points/SdCliProject.js.map +1 -1
- package/dist-node/packages/SdCliClientPackage.js +4 -3
- package/dist-node/packages/SdCliClientPackage.js.map +1 -1
- package/dist-node/packages/SdCliLibraryPackage.js +3 -2
- package/dist-node/packages/SdCliLibraryPackage.js.map +1 -1
- package/dist-node/packages/SdCliServerPackage.js +4 -3
- package/dist-node/packages/SdCliServerPackage.js.map +1 -1
- package/dist-node/utils/SdProjectConfigUtil.js +1 -1
- package/dist-node/utils/SdProjectConfigUtil.js.map +1 -1
- package/dist-node/utils/SdWebpackUtil.js +33 -13
- package/dist-node/utils/SdWebpackUtil.js.map +1 -1
- package/dist-node/workers/client-ng-gen-worker.js +54 -0
- package/dist-node/workers/client-ng-gen-worker.js.map +1 -0
- package/dist-node/workers/lib-build-worker.js +7 -6
- package/dist-node/workers/lib-build-worker.js.map +1 -1
- package/dist-types/build-tools/metadata/SdIvyMetadataReader.d.ts +1 -0
- package/dist-types/build-tools/metadata/SdMetadataError.d.ts +6 -0
- package/dist-types/build-tools/metadata/SdMyMetadataReader.d.ts +1 -0
- package/dist-types/builders/SdCliNgClientBuilder.d.ts +6 -2
- package/dist-types/builders/SdCliNgLibraryBuilder.d.ts +3 -1
- package/dist-types/builders/SdCliServerBuilder.d.ts +2 -1
- package/dist-types/builders/SdCliTypescriptBuilder.d.ts +5 -5
- package/dist-types/commons.d.ts +3 -1
- package/dist-types/entry-points/SdCliLocalUpdater.d.ts +1 -1
- package/dist-types/entry-points/SdCliProject.d.ts +2 -0
- package/dist-types/packages/SdCliClientPackage.d.ts +2 -1
- package/dist-types/packages/SdCliLibraryPackage.d.ts +2 -1
- package/dist-types/packages/SdCliServerPackage.d.ts +2 -1
- package/dist-types/utils/SdWebpackUtil.d.ts +1 -1
- package/dist-types/workers/client-ng-gen-worker.d.ts +1 -0
- package/package.json +7 -7
- package/schema/schema.json +185 -122
- package/sd-tsconfig.node.json +2 -1
- package/src/bin/sd-cli.ts +19 -4
- package/src/build-tools/SdCliNgModuleFilesGenerator.ts +118 -60
- package/src/build-tools/metadata/SdAotMetadataReader.ts +8 -2
- package/src/build-tools/metadata/SdIvyMetadataReader.ts +27 -4
- package/src/build-tools/metadata/SdMetadataError.ts +7 -0
- package/src/build-tools/metadata/SdMyMetadataReader.ts +25 -3
- package/src/builders/SdCliNgClientBuilder.ts +122 -58
- package/src/builders/SdCliNgLibraryBuilder.ts +102 -43
- package/src/builders/SdCliServerBuilder.ts +61 -44
- package/src/builders/SdCliTypescriptBuilder.ts +92 -73
- package/src/commons.ts +1 -1
- package/src/entry-points/SdCliLocalUpdater.ts +40 -33
- package/src/entry-points/SdCliProject.ts +14 -13
- package/src/packages/SdCliClientPackage.ts +3 -2
- package/src/packages/SdCliLibraryPackage.ts +2 -1
- package/src/packages/SdCliServerPackage.ts +4 -3
- package/src/utils/SdCliFileCrypto.ts +1 -1
- package/src/utils/SdProjectConfigUtil.ts +1 -1
- package/src/utils/SdWebpackUtil.ts +42 -22
- package/src/workers/client-ng-gen-worker.ts +60 -0
- package/src/workers/lib-build-worker.ts +7 -6
- package/tsconfig.json +2 -1
|
@@ -3,18 +3,16 @@ import { INpmConfig, ISdClientPackageConfig, ISdPackageBuildResult, ITsconfig }
|
|
|
3
3
|
import * as webpack from "webpack";
|
|
4
4
|
import * as path from "path";
|
|
5
5
|
import * as ts from "typescript";
|
|
6
|
-
import { FsUtil, PathUtil } from "@simplysm/sd-core-node";
|
|
6
|
+
import { FsUtil, Logger, PathUtil, SdProcessWorker } from "@simplysm/sd-core-node";
|
|
7
7
|
import { JavaScriptOptimizerPlugin } from "@angular-devkit/build-angular/src/webpack/plugins/javascript-optimizer-plugin";
|
|
8
8
|
import * as CssMinimizerPlugin from "css-minimizer-webpack-plugin";
|
|
9
9
|
import * as esbuild from "esbuild";
|
|
10
10
|
import {
|
|
11
|
-
AnyComponentStyleBudgetChecker,
|
|
12
11
|
CommonJsUsageWarnPlugin,
|
|
13
12
|
DedupeModuleResolvePlugin,
|
|
14
13
|
SuppressExtractedTextChunksWebpackPlugin
|
|
15
14
|
} from "@angular-devkit/build-angular/src/webpack/plugins";
|
|
16
15
|
import { LicenseWebpackPlugin } from "license-webpack-plugin";
|
|
17
|
-
import { Type } from "@angular-devkit/build-angular";
|
|
18
16
|
import { SassWorkerImplementation } from "@angular-devkit/build-angular/src/sass/sass-service";
|
|
19
17
|
import * as MiniCssExtractPlugin from "mini-css-extract-plugin";
|
|
20
18
|
import { AngularWebpackPlugin } from "@ngtools/webpack";
|
|
@@ -28,7 +26,6 @@ import { StringUtil, Wait } from "@simplysm/sd-core-common";
|
|
|
28
26
|
import { augmentAppWithServiceWorker } from "@angular-devkit/build-angular/src/utils/service-worker";
|
|
29
27
|
import * as browserslist from "browserslist";
|
|
30
28
|
import * as WebpackHotMiddleware from "webpack-hot-middleware";
|
|
31
|
-
import { SdCliNgLibraryBuilder } from "./SdCliNgLibraryBuilder";
|
|
32
29
|
import * as os from "os";
|
|
33
30
|
import { LintResult } from "eslint-webpack-plugin/declarations/options";
|
|
34
31
|
|
|
@@ -39,10 +36,15 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
39
36
|
public parsedTsconfig: ts.ParsedCommandLine;
|
|
40
37
|
public readonly npmConfig: INpmConfig;
|
|
41
38
|
|
|
39
|
+
private _ngGenWorker?: SdProcessWorker;
|
|
40
|
+
|
|
41
|
+
protected readonly _logger: Logger;
|
|
42
|
+
|
|
42
43
|
public constructor(public rootPath: string,
|
|
43
44
|
public tsconfigFilePath: string,
|
|
44
45
|
public projectRootPath: string,
|
|
45
|
-
public config: ISdClientPackageConfig
|
|
46
|
+
public config: ISdClientPackageConfig,
|
|
47
|
+
public useCache: boolean) {
|
|
46
48
|
super();
|
|
47
49
|
|
|
48
50
|
const tsconfig: ITsconfig = FsUtil.readJson(this.tsconfigFilePath);
|
|
@@ -56,6 +58,8 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
56
58
|
};
|
|
57
59
|
|
|
58
60
|
this.npmConfig = FsUtil.readJson(path.resolve(this.rootPath, "package.json"));
|
|
61
|
+
|
|
62
|
+
this._logger = Logger.get(["simplysm", "sd-cli", this.constructor.name, this.npmConfig.name]);
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
public on(event: "change", listener: () => void): this;
|
|
@@ -72,12 +76,16 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
72
76
|
const buildResult: ISdPackageBuildResult[] = [];
|
|
73
77
|
|
|
74
78
|
// GENERATOR
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
const
|
|
79
|
+
this._logger.debug("NgGen 수행");
|
|
80
|
+
const genResult = await this._runNgGenWorkerAsync(false);
|
|
81
|
+
// const ngGenerator = new SdCliNgLibraryBuilder(this.rootPath, this.tsconfigFilePath, ["emit", "check", "lint"], undefined);
|
|
82
|
+
// const genFilePaths = await ngGenerator.reloadProgramAsync(false);
|
|
83
|
+
// const genResult = await ngGenerator.generateAdditionalFilesAsync(genFilePaths, false);
|
|
78
84
|
buildResult.push(...genResult.result);
|
|
85
|
+
this._logger.debug("NgGen 수행 결과", genResult);
|
|
79
86
|
|
|
80
87
|
// WEBPACK 빌드
|
|
88
|
+
this._logger.debug("Webpack 빌드 수행");
|
|
81
89
|
const webpackConfig = this._getWebpackConfig(false);
|
|
82
90
|
const compiler = webpack(webpackConfig);
|
|
83
91
|
const webpackBuildResults = await new Promise<ISdPackageBuildResult[]>((resolve, reject) => {
|
|
@@ -91,6 +99,7 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
91
99
|
resolve(results);
|
|
92
100
|
});
|
|
93
101
|
});
|
|
102
|
+
this._logger.debug("Webpack 빌드 결과", webpackBuildResults);
|
|
94
103
|
buildResult.push(...webpackBuildResults);
|
|
95
104
|
|
|
96
105
|
// .config.json 파일 쓰기
|
|
@@ -100,14 +109,16 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
100
109
|
|
|
101
110
|
// service-worker 처리
|
|
102
111
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
if (FsUtil.exists(path.resolve(this.rootPath, "ngsw-config.json"))) {
|
|
113
|
+
const packageKey = this.npmConfig.name.split("/").last()!;
|
|
114
|
+
await augmentAppWithServiceWorker(
|
|
115
|
+
PathUtil.posix(this.projectRootPath) as any,
|
|
116
|
+
PathUtil.posix(path.relative(this.projectRootPath, this.rootPath)) as any,
|
|
117
|
+
PathUtil.posix(path.relative(this.projectRootPath, this.parsedTsconfig.options.outDir!)) as any,
|
|
118
|
+
`/${packageKey}/`,
|
|
119
|
+
PathUtil.posix(path.relative(this.projectRootPath, path.resolve(this.rootPath, "ngsw-config.json")))
|
|
120
|
+
);
|
|
121
|
+
}
|
|
111
122
|
|
|
112
123
|
this.emit("complete", buildResult.distinct());
|
|
113
124
|
}
|
|
@@ -115,66 +126,73 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
115
126
|
public async watchAsync(serverPath?: string): Promise<NextHandleFunction[]> {
|
|
116
127
|
await FsUtil.removeAsync(this.parsedTsconfig.options.outDir!);
|
|
117
128
|
|
|
118
|
-
let
|
|
129
|
+
let ngGenResults: ISdPackageBuildResult[] = [];
|
|
119
130
|
|
|
120
|
-
const ngGenerator = new SdCliNgLibraryBuilder(this.rootPath, this.tsconfigFilePath, ["emit", "check", "lint"], undefined);
|
|
131
|
+
// const ngGenerator = new SdCliNgLibraryBuilder(this.rootPath, this.tsconfigFilePath, ["emit", "check", "lint", "genIndex"], undefined);
|
|
121
132
|
|
|
122
133
|
// WEBPACK 빌드
|
|
134
|
+
let invalidFiles = new Set<string>();
|
|
123
135
|
const webpackConfig = this._getWebpackConfig(true);
|
|
124
136
|
const compiler = webpack(webpackConfig);
|
|
125
137
|
return await new Promise<NextHandleFunction[]>((resolve, reject) => {
|
|
138
|
+
compiler.hooks.invalid.tap(this.constructor.name, (fileName) => {
|
|
139
|
+
if (fileName != null) {
|
|
140
|
+
invalidFiles.add(fileName);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
126
144
|
compiler.hooks.watchRun.tapAsync(this.constructor.name, async (compiler1, callback) => {
|
|
127
145
|
this.emit("change");
|
|
128
146
|
|
|
129
|
-
|
|
147
|
+
ngGenResults = [];
|
|
130
148
|
|
|
131
149
|
// -- FIRST
|
|
132
150
|
|
|
133
151
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition,@typescript-eslint/strict-boolean-expressions
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
const genResult = await
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
if (invalidFiles.size === 0) {
|
|
153
|
+
this._logger.debug("첫 NgGen 수행");
|
|
154
|
+
const genResult = await this._runNgGenWorkerAsync(true);
|
|
155
|
+
// const genDirtyFilePaths = await ngGenerator.reloadProgramAsync(true);
|
|
156
|
+
// const genResult = await ngGenerator.generateAdditionalFilesAsync(genDirtyFilePaths, true);
|
|
157
|
+
ngGenResults.push(...genResult.result);
|
|
158
|
+
this._logger.debug("첫 NgGen 수행 결과", genResult);
|
|
159
|
+
|
|
160
|
+
this._logger.debug("Webpack 빌드 수행");
|
|
139
161
|
callback();
|
|
140
162
|
}
|
|
141
163
|
|
|
142
164
|
// -- NOT FIRST
|
|
143
|
-
|
|
144
165
|
else {
|
|
145
|
-
const changedFiles = [...compiler.modifiedFiles, ...compiler.removedFiles];
|
|
146
|
-
|
|
147
166
|
// 변경파일 중, 유효한 파일 추출
|
|
148
|
-
const
|
|
167
|
+
const changedFiles = [...invalidFiles];
|
|
168
|
+
invalidFiles = new Set<string>();
|
|
169
|
+
|
|
149
170
|
const changedFilePaths = changedFiles
|
|
150
171
|
.map((item) => PathUtil.posix(item))
|
|
151
172
|
.filter((item) => path.basename(item).includes("."))
|
|
152
|
-
.filter((item) => watchPaths.includes(path.dirname(item)))
|
|
153
173
|
.distinct();
|
|
154
174
|
if (changedFilePaths.length === 0) {
|
|
175
|
+
this._logger.debug("Webpack 빌드 수행");
|
|
155
176
|
callback();
|
|
156
177
|
return;
|
|
157
178
|
}
|
|
158
179
|
|
|
159
|
-
|
|
160
|
-
const genDirtyFilePaths = await ngGenerator.reloadChangedProgramAsync(changedFilePaths, true);
|
|
161
|
-
if (genDirtyFilePaths.length === 0) {
|
|
162
|
-
callback();
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
180
|
+
this._logger.debug("변경파일에 대한, NgGen 수행", changedFilePaths);
|
|
165
181
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
buildResult.push(...genResult.result);
|
|
182
|
+
const genResult = await this._runNgGenWorkerAsync(true, changedFilePaths);
|
|
183
|
+
ngGenResults.push(...genResult.result);
|
|
169
184
|
if (genResult.dirtyFilePaths.length === 0) {
|
|
185
|
+
this._logger.debug("변경파일에 대한, NgGen 결과", genResult);
|
|
186
|
+
this._logger.debug("Webpack 빌드 수행");
|
|
170
187
|
callback();
|
|
171
188
|
return;
|
|
172
189
|
}
|
|
173
|
-
|
|
190
|
+
|
|
191
|
+
this._logger.debug("변경파일에 대한, NgGen 결과", genResult);
|
|
174
192
|
|
|
175
193
|
const modifiedFiles = [...compiler.modifiedFiles];
|
|
176
194
|
const removedFiles = [...compiler.removedFiles];
|
|
177
|
-
for (const genFilePath of
|
|
195
|
+
for (const genFilePath of genResult.dirtyFilePaths.distinct()) {
|
|
178
196
|
if (FsUtil.exists(genFilePath)) {
|
|
179
197
|
modifiedFiles.push(genFilePath);
|
|
180
198
|
}
|
|
@@ -185,6 +203,7 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
185
203
|
compiler.modifiedFiles = new Set(modifiedFiles.distinct());
|
|
186
204
|
compiler.removedFiles = new Set(removedFiles.distinct());
|
|
187
205
|
|
|
206
|
+
this._logger.debug("Webpack 빌드 수행");
|
|
188
207
|
callback();
|
|
189
208
|
}
|
|
190
209
|
});
|
|
@@ -196,7 +215,9 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
196
215
|
|
|
197
216
|
compiler.hooks.failed.tap(this.constructor.name, (err) => {
|
|
198
217
|
const results = SdWebpackUtil.getWebpackResults(err);
|
|
199
|
-
|
|
218
|
+
const allResults = [...ngGenResults, ...results].distinct();
|
|
219
|
+
this.emit("complete", allResults);
|
|
220
|
+
this._logger.debug("Webpack 빌드 수행 결과", allResults);
|
|
200
221
|
reject(err);
|
|
201
222
|
});
|
|
202
223
|
|
|
@@ -212,7 +233,9 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
212
233
|
|
|
213
234
|
|
|
214
235
|
await Wait.true(() => devMiddleware !== undefined && hotMiddleware !== undefined);
|
|
215
|
-
|
|
236
|
+
const allResults = [...ngGenResults, ...results].distinct();
|
|
237
|
+
this.emit("complete", allResults);
|
|
238
|
+
this._logger.debug("Webpack 빌드 수행 결과", allResults);
|
|
216
239
|
resolve([devMiddleware!, hotMiddleware!]);
|
|
217
240
|
});
|
|
218
241
|
|
|
@@ -242,19 +265,16 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
242
265
|
profile: false,
|
|
243
266
|
resolve: {
|
|
244
267
|
roots: [this.rootPath],
|
|
245
|
-
extensions: [".ts", ".
|
|
268
|
+
extensions: [".ts", ".js"],
|
|
246
269
|
symlinks: true,
|
|
247
|
-
modules:
|
|
270
|
+
// modules: allNodeModulePaths,
|
|
248
271
|
mainFields: ["es2015", "browser", "module", "main"],
|
|
249
272
|
fallback: this.config.resolveFallback
|
|
250
273
|
},
|
|
251
|
-
resolveLoader: {
|
|
274
|
+
/*resolveLoader: {
|
|
252
275
|
symlinks: true,
|
|
253
|
-
modules:
|
|
254
|
-
|
|
255
|
-
...this._findAllNodeModules(__dirname, this.projectRootPath)
|
|
256
|
-
]
|
|
257
|
-
},
|
|
276
|
+
modules: allNodeModulePaths
|
|
277
|
+
},*/
|
|
258
278
|
context: this.projectRootPath,
|
|
259
279
|
entry: {
|
|
260
280
|
main: [
|
|
@@ -278,6 +298,7 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
278
298
|
// chunkFilename: watch ? "[name].js" : "[name].[chunkhash:20].js",
|
|
279
299
|
filename: "[name].js",
|
|
280
300
|
chunkFilename: "[name].js",
|
|
301
|
+
assetModuleFilename: "resources/[name][ext][query]",
|
|
281
302
|
crossOriginLoading: false,
|
|
282
303
|
trustedTypes: "angular#bundler"
|
|
283
304
|
},
|
|
@@ -377,18 +398,22 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
377
398
|
{
|
|
378
399
|
test: /\.[jt]sx?$/,
|
|
379
400
|
loader: "@ngtools/webpack"
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico|otf|xlsx?|pptx?|docx?|zip|pfx|pkl)$/,
|
|
404
|
+
type: "asset/resource"
|
|
380
405
|
}
|
|
381
406
|
]
|
|
382
407
|
},
|
|
383
408
|
experiments: { syncWebAssembly: true, asyncWebAssembly: true },
|
|
384
|
-
cache: watch ? { type: "memory", maxGenerations: 1 } : false,
|
|
409
|
+
cache: (watch && this.useCache) ? { type: "memory", maxGenerations: 1 } : false,
|
|
385
410
|
optimization: {
|
|
386
411
|
minimizer: watch ? [] : [
|
|
387
412
|
new JavaScriptOptimizerPlugin({
|
|
388
413
|
define: { ngDevMode: false, ngI18nClosureMode: false, ngJitMode: false },
|
|
389
414
|
sourcemap: false,
|
|
390
415
|
target: this.parsedTsconfig.options.target,
|
|
391
|
-
keepNames:
|
|
416
|
+
keepNames: true,
|
|
392
417
|
removeLicenses: true,
|
|
393
418
|
advanced: true
|
|
394
419
|
}) as any,
|
|
@@ -403,9 +428,9 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
403
428
|
minify: true,
|
|
404
429
|
sourcefile,
|
|
405
430
|
target: browserslist([
|
|
406
|
-
"last
|
|
431
|
+
"last 1 Chrome versions",
|
|
407
432
|
"last 2 Edge major versions"
|
|
408
|
-
])
|
|
433
|
+
]).map((item) => item.replace(/ /g, ""))
|
|
409
434
|
});
|
|
410
435
|
|
|
411
436
|
return {
|
|
@@ -437,7 +462,7 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
437
462
|
],
|
|
438
463
|
moduleIds: "deterministic",
|
|
439
464
|
chunkIds: watch ? "named" : "deterministic",
|
|
440
|
-
emitOnErrors:
|
|
465
|
+
emitOnErrors: watch,
|
|
441
466
|
runtimeChunk: "single",
|
|
442
467
|
splitChunks: {
|
|
443
468
|
maxAsyncRequests: Infinity,
|
|
@@ -504,13 +529,13 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
504
529
|
append: undefined
|
|
505
530
|
})
|
|
506
531
|
] : [],
|
|
507
|
-
new AnyComponentStyleBudgetChecker(watch ? [] : [
|
|
532
|
+
/*new AnyComponentStyleBudgetChecker(watch ? [] : [
|
|
508
533
|
{
|
|
509
534
|
type: Type.Any,
|
|
510
535
|
maximumWarning: "2kb",
|
|
511
536
|
maximumError: "4kb"
|
|
512
537
|
}
|
|
513
|
-
])
|
|
538
|
+
]),*/
|
|
514
539
|
{
|
|
515
540
|
apply(compiler) {
|
|
516
541
|
compiler.hooks.shutdown.tap("sass-worker", () => {
|
|
@@ -584,13 +609,37 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
584
609
|
}),
|
|
585
610
|
...watch ? [
|
|
586
611
|
new webpack.HotModuleReplacementPlugin()
|
|
587
|
-
] : []
|
|
612
|
+
] : [],
|
|
613
|
+
/*...watch ? [
|
|
614
|
+
new webpack.WatchIgnorePlugin({
|
|
615
|
+
paths: [
|
|
616
|
+
path.resolve(this.rootPath, "src/_modules/"),
|
|
617
|
+
path.resolve(this.rootPath, "src/_routes.ts")
|
|
618
|
+
]
|
|
619
|
+
})
|
|
620
|
+
] : [],*/
|
|
621
|
+
new webpack.ProgressPlugin({
|
|
622
|
+
handler: (per: number, msg: string, ...args: string[]) => {
|
|
623
|
+
const phaseText = msg ? ` - phase: ${msg}` : "";
|
|
624
|
+
const argsText = args.length > 0 ? ` - args: [${args.join(", ")}]` : "";
|
|
625
|
+
this._logger.debug(`Webpack 빌드 수행중...(${Math.round(per * 100)}%)${phaseText}${argsText}`);
|
|
626
|
+
}
|
|
627
|
+
})
|
|
588
628
|
],
|
|
589
629
|
node: false,
|
|
590
630
|
stats: "errors-warnings"
|
|
591
631
|
};
|
|
592
632
|
}
|
|
593
633
|
|
|
634
|
+
/*private _findAllInternalModuleCachePaths(): string[] {
|
|
635
|
+
return this._findAllNodeModules(this.rootPath, this.projectRootPath)
|
|
636
|
+
.mapMany((item) => (
|
|
637
|
+
FsUtil.readdir(item)
|
|
638
|
+
.filter((item1) => !item1.startsWith("@simplysm"))
|
|
639
|
+
.map((item1) => path.resolve(item, item1))
|
|
640
|
+
));
|
|
641
|
+
}
|
|
642
|
+
|
|
594
643
|
private _findAllNodeModules(from: string, root: string): string[] {
|
|
595
644
|
const nodeModules: string[] = [];
|
|
596
645
|
|
|
@@ -609,5 +658,20 @@ export class SdCliNgClientBuilder extends EventEmitter {
|
|
|
609
658
|
}
|
|
610
659
|
|
|
611
660
|
return nodeModules;
|
|
661
|
+
}*/
|
|
662
|
+
|
|
663
|
+
private async _runNgGenWorkerAsync(watch: boolean, changedFilePaths?: string[]): Promise<{ dirtyFilePaths: string[]; result: ISdPackageBuildResult[] }> {
|
|
664
|
+
if (!this._ngGenWorker) {
|
|
665
|
+
this._ngGenWorker = await SdProcessWorker.createAsync(path.resolve(__dirname, `../workers/client-ng-gen-worker`), []);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const sender = this._ngGenWorker.createWorkSender();
|
|
669
|
+
return await new Promise<{ dirtyFilePaths: string[]; result: ISdPackageBuildResult[] }>(async (resolve) => {
|
|
670
|
+
await sender
|
|
671
|
+
.on("complete", (result) => {
|
|
672
|
+
resolve(result);
|
|
673
|
+
})
|
|
674
|
+
.sendAsync(this.rootPath, watch, changedFilePaths);
|
|
675
|
+
});
|
|
612
676
|
}
|
|
613
677
|
}
|
|
@@ -6,7 +6,7 @@ import { NgccProcessingCache } from "ng-packagr/lib/ng-package/ngcc-cache";
|
|
|
6
6
|
import { NgccProcessor } from "ng-packagr/lib/ngc/ngcc-processor";
|
|
7
7
|
import { EntryPointNode } from "ng-packagr/lib/ng-package/nodes";
|
|
8
8
|
import { ngccTransformCompilerHost } from "ng-packagr/lib/ts/ngcc-transform-compiler-host";
|
|
9
|
-
import { NgtscProgram } from "@angular/compiler-cli";
|
|
9
|
+
import { MetadataCollector, NgtscProgram } from "@angular/compiler-cli";
|
|
10
10
|
import { ITsBuildFileCache, ITsGenResult, SdCliTypescriptBuilder } from "./SdCliTypescriptBuilder";
|
|
11
11
|
import { NgCompiler } from "@angular/compiler-cli/src/ngtsc/core";
|
|
12
12
|
import { NeverEntryError, StringUtil } from "@simplysm/sd-core-common";
|
|
@@ -16,6 +16,7 @@ import * as nodeSass from "node-sass";
|
|
|
16
16
|
import { createHash } from "crypto";
|
|
17
17
|
import { SdCliNgModuleFilesGenerator } from "../build-tools/SdCliNgModuleFilesGenerator";
|
|
18
18
|
import { OptimizeFor } from "@angular/compiler-cli/src/ngtsc/typecheck/api";
|
|
19
|
+
import { ModuleMetadata } from "@angular/compiler-cli/src/metadata/schema";
|
|
19
20
|
|
|
20
21
|
export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
21
22
|
protected _ngProgram?: NgtscProgram;
|
|
@@ -28,17 +29,17 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
28
29
|
|
|
29
30
|
public constructor(public rootPath: string,
|
|
30
31
|
public tsconfigFilePath: string,
|
|
31
|
-
|
|
32
|
+
skipProcesses: ("emit" | "check" | "lint" | "genIndex" | "genNgModule")[],
|
|
32
33
|
public autoIndexConfig: ISdAutoIndexConfig | undefined) {
|
|
33
|
-
super(rootPath, tsconfigFilePath,
|
|
34
|
-
this.
|
|
34
|
+
super(rootPath, tsconfigFilePath, skipProcesses as ("emit" | "check" | "lint" | "genIndex")[], autoIndexConfig);
|
|
35
|
+
this.skipProcesses = skipProcesses;
|
|
35
36
|
|
|
36
37
|
const tsconfig: ITsconfig = FsUtil.readJson(this.tsconfigFilePath);
|
|
37
|
-
this.
|
|
38
|
-
...
|
|
39
|
-
|
|
38
|
+
this._tsconfig = {
|
|
39
|
+
...tsconfig,
|
|
40
|
+
compilerOptions: {
|
|
40
41
|
baseUrl: path.dirname(this.tsconfigFilePath),
|
|
41
|
-
...
|
|
42
|
+
...tsconfig.compilerOptions,
|
|
42
43
|
...tsconfig.angularCompilerOptions
|
|
43
44
|
}
|
|
44
45
|
};
|
|
@@ -52,7 +53,7 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
52
53
|
|
|
53
54
|
const diagnostics: ts.Diagnostic[] = [];
|
|
54
55
|
|
|
55
|
-
if (!this.
|
|
56
|
+
if (!this.skipProcesses.includes("check")) {
|
|
56
57
|
diagnostics.push(
|
|
57
58
|
...this._ngCompiler.getOptionDiagnostics(),
|
|
58
59
|
...this._builder.getOptionsDiagnostics(),
|
|
@@ -61,9 +62,10 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
61
62
|
|
|
62
63
|
await this._ngCompiler.analyzeAsync();
|
|
63
64
|
|
|
64
|
-
for (const
|
|
65
|
-
const
|
|
66
|
-
|
|
65
|
+
for (const sourceFile of this._builder.getSourceFiles()) {
|
|
66
|
+
/*for (const filePath of dirtyFilePaths) {
|
|
67
|
+
const sourceFile = this._builder.getSourceFile(filePath);
|
|
68
|
+
if (!sourceFile) continue;*/
|
|
67
69
|
|
|
68
70
|
if (this._ngCompiler.ignoreForDiagnostics.has(sourceFile)) continue;
|
|
69
71
|
if (sourceFile.isDeclarationFile) continue;
|
|
@@ -76,7 +78,7 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
if (!this.
|
|
81
|
+
if (!this.skipProcesses.includes("emit")) {
|
|
80
82
|
const transformers = this._ngCompiler.prepareEmit().transformers;
|
|
81
83
|
|
|
82
84
|
for (const filePath of dirtyFilePaths) {
|
|
@@ -86,7 +88,21 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
86
88
|
if (sourceFile.isDeclarationFile) continue;
|
|
87
89
|
|
|
88
90
|
this._builder.emit(sourceFile, undefined, undefined, undefined, transformers);
|
|
91
|
+
|
|
92
|
+
// TODO: sd-metadata를 ModuleMetadata로 만들게 아니고, 아예 IAotModuleDefMetadata형식으로 만들어지게 해야함
|
|
93
|
+
if (this._program!.getCompilerOptions().declaration) {
|
|
94
|
+
if (sourceFile.fileName.endsWith(".ts") && !sourceFile.fileName.endsWith(".d.ts")) {
|
|
95
|
+
const metadata = this._getMetadata(sourceFile);
|
|
96
|
+
if (metadata) {
|
|
97
|
+
this._writeMetadataFile(sourceFile, metadata);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
89
101
|
}
|
|
102
|
+
|
|
103
|
+
/*if (this._parsedTsconfig.options.declaration) {
|
|
104
|
+
this._writeMetadataBundles();
|
|
105
|
+
}*/
|
|
90
106
|
}
|
|
91
107
|
|
|
92
108
|
const result = diagnostics.map((item) => SdTsDiagnosticUtil.convertDiagnosticsToResult(item)).filterExists();
|
|
@@ -96,15 +112,54 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
96
112
|
return result;
|
|
97
113
|
}
|
|
98
114
|
|
|
115
|
+
private _writeMetadataFile(sourceFile: ts.SourceFile, metadata: ModuleMetadata): void {
|
|
116
|
+
const metadataText = JSON.stringify({
|
|
117
|
+
...metadata,
|
|
118
|
+
importAs: this.npmConfig.name
|
|
119
|
+
});
|
|
120
|
+
const outFileName = path.resolve(
|
|
121
|
+
this._program!.getCompilerOptions().declarationDir!,
|
|
122
|
+
path.relative(path.resolve(this.rootPath, "src"), sourceFile.fileName)
|
|
123
|
+
).replace(/\.ts$/, ".sd-metadata.json");
|
|
124
|
+
this._cacheCompilerHost!.writeFile(outFileName, metadataText, false, undefined, [sourceFile]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private _getMetadata(sourceFile: ts.SourceFile): ModuleMetadata | undefined {
|
|
128
|
+
return new MetadataCollector().getMetadata(sourceFile, true);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/*private _writeMetadataBundles(): void {
|
|
132
|
+
for (const rootFilePath of this._parsedTsconfig.fileNames) {
|
|
133
|
+
const metadata = new MetadataBundler(
|
|
134
|
+
rootFilePath.replace(/\.ts$/, ""),
|
|
135
|
+
rootFilePath.endsWith("/index.ts") ? this.npmConfig.name
|
|
136
|
+
: (this.npmConfig.name + "/" + PathUtil.posix(path.relative(path.resolve(this.rootPath, "src"), rootFilePath)).replace(/\.ts/, "")),
|
|
137
|
+
new CompilerHostAdapter(this._cacheCompilerHost!, null, this._parsedTsconfig.options),
|
|
138
|
+
undefined
|
|
139
|
+
).getMetadataBundle().metadata;
|
|
140
|
+
|
|
141
|
+
const outFileName = path.resolve(
|
|
142
|
+
this._parsedTsconfig.options.declarationDir!,
|
|
143
|
+
path.relative(path.resolve(this.rootPath, "src"), rootFilePath)
|
|
144
|
+
).replace(/\.ts$/, ".sd-metadata.json");
|
|
145
|
+
|
|
146
|
+
const fileCache = this._fileCache.get(PathUtil.posix(rootFilePath));
|
|
147
|
+
if (!fileCache?.sourceFile) throw new NeverEntryError();
|
|
148
|
+
this._cacheCompilerHost!.writeFile(outFileName, JSON.stringify(metadata), false, undefined, [fileCache.sourceFile]);
|
|
149
|
+
}
|
|
150
|
+
}*/
|
|
151
|
+
|
|
99
152
|
public override async reloadProgramAsync(watch: boolean): Promise<string[]> {
|
|
100
153
|
this._logger.debug("프로그램 리로드");
|
|
101
154
|
|
|
102
|
-
|
|
103
|
-
|
|
155
|
+
const parsedTsconfig = ts.parseJsonConfigFileContent(this._tsconfig, ts.sys, this.rootPath);
|
|
156
|
+
|
|
157
|
+
this._moduleResolutionCache = ts.createModuleResolutionCache(this.rootPath, (s) => s, parsedTsconfig.options);
|
|
158
|
+
this._cacheCompilerHost = await this._createCacheCompilerHostAsync(parsedTsconfig, this._moduleResolutionCache);
|
|
104
159
|
|
|
105
160
|
this._ngProgram = new NgtscProgram(
|
|
106
|
-
|
|
107
|
-
|
|
161
|
+
parsedTsconfig.fileNames,
|
|
162
|
+
parsedTsconfig.options,
|
|
108
163
|
this._cacheCompilerHost,
|
|
109
164
|
this._ngProgram
|
|
110
165
|
);
|
|
@@ -126,15 +181,27 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
126
181
|
};
|
|
127
182
|
|
|
128
183
|
if (watch) {
|
|
129
|
-
|
|
130
|
-
this.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
184
|
+
if (this.skipProcesses.includes("emit")) {
|
|
185
|
+
this._builder = ts.createSemanticDiagnosticsBuilderProgram(
|
|
186
|
+
this._program,
|
|
187
|
+
this._cacheCompilerHost,
|
|
188
|
+
this._builder as ts.SemanticDiagnosticsBuilderProgram
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
this._builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(
|
|
193
|
+
this._program,
|
|
194
|
+
this._cacheCompilerHost,
|
|
195
|
+
this._builder as ts.EmitAndSemanticDiagnosticsBuilderProgram
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
const builder = this._builder as ts.SemanticDiagnosticsBuilderProgram;
|
|
135
199
|
|
|
136
|
-
|
|
200
|
+
let seq = 0;
|
|
201
|
+
const affectedFilePathSet = new Set<string>();
|
|
137
202
|
while (true) {
|
|
203
|
+
const affectedFilePaths: string[] = [];
|
|
204
|
+
this._logger.debug(`프로그램 리로드 > 변경파일 목록구성: [SEQ: ${++seq}]`);
|
|
138
205
|
const result = builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, (sourceFile) => {
|
|
139
206
|
if (this._ngCompiler!.ignoreForDiagnostics.has(sourceFile) && sourceFile.fileName.endsWith(".ngtypecheck.ts")) {
|
|
140
207
|
const originalFilename = sourceFile.fileName.slice(0, -15) + ".ts";
|
|
@@ -147,14 +214,20 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
147
214
|
return false;
|
|
148
215
|
});
|
|
149
216
|
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
if ("fileName" in result.affected) {
|
|
217
|
+
if (result && "fileName" in result.affected) {
|
|
153
218
|
affectedFilePaths.push(result.affected.fileName);
|
|
154
219
|
}
|
|
220
|
+
|
|
221
|
+
affectedFilePaths.distinctThis();
|
|
222
|
+
|
|
223
|
+
this._logger.debug(`프로그램 리로드 > 변경파일 목록구성: [SEQ: ${seq}, SIZE:${affectedFilePathSet.size}]\n` + affectedFilePaths.map((item) => "- " + item).join("\n"));
|
|
224
|
+
|
|
225
|
+
affectedFilePathSet.adds(...affectedFilePaths.distinct());
|
|
226
|
+
|
|
227
|
+
if (!result) break;
|
|
155
228
|
}
|
|
156
229
|
|
|
157
|
-
const result =
|
|
230
|
+
const result = Array.from(affectedFilePathSet.values());
|
|
158
231
|
|
|
159
232
|
this._logger.debug("프로그램 리로드", result);
|
|
160
233
|
|
|
@@ -208,7 +281,7 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
208
281
|
this._logger.debug("Angular Module, RoutingModule 생성", dirtyFilePaths);
|
|
209
282
|
|
|
210
283
|
const result: ITsGenResult = { dirtyFilePaths: [], result: [] };
|
|
211
|
-
if (this.
|
|
284
|
+
if (this.skipProcesses.includes("genNgModule")) return result;
|
|
212
285
|
|
|
213
286
|
const reloadResult = await this._moduleFilesGenerator.reloadSourceFilesAsync(
|
|
214
287
|
dirtyFilePaths,
|
|
@@ -231,20 +304,6 @@ export class SdCliNgLibraryBuilder extends SdCliTypescriptBuilder {
|
|
|
231
304
|
return result;
|
|
232
305
|
}
|
|
233
306
|
|
|
234
|
-
/*protected override _getAllDependencies(filePath: string): string[] {
|
|
235
|
-
this._logger.debug("파일 의존성 확인", filePath);
|
|
236
|
-
|
|
237
|
-
const sourceFile = this._builder!.getSourceFile(filePath);
|
|
238
|
-
if (!sourceFile) {
|
|
239
|
-
this._logger.debug("파일 의존성 확인 결과", []);
|
|
240
|
-
return [];
|
|
241
|
-
}
|
|
242
|
-
const result = [...this._builder!.getAllDependencies(sourceFile), ...(this._fileCache.get(PathUtil.posix(filePath))?.scssDependencies ?? [])];
|
|
243
|
-
|
|
244
|
-
this._logger.debug("파일 의존성 확인 결과", result);
|
|
245
|
-
return result;
|
|
246
|
-
}*/
|
|
247
|
-
|
|
248
307
|
protected override async _createCacheCompilerHostAsync(parsedTsconfig: ts.ParsedCommandLine, moduleResolutionCache: ts.ModuleResolutionCache): Promise<ts.CompilerHost> {
|
|
249
308
|
const tsCacheCompilerHost = await super._createCacheCompilerHostAsync(parsedTsconfig, moduleResolutionCache);
|
|
250
309
|
|