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