@simplysm/sd-cli 7.0.79 → 7.0.100
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/bin/sd-cli.mjs +13 -3
- package/dist/build-tool/SdCliCordova.d.ts +4 -4
- package/dist/build-tool/SdCliCordova.mjs +105 -110
- package/dist/build-tool/SdCliElectron.d.ts +3 -0
- package/dist/build-tool/SdCliElectron.mjs +21 -0
- package/dist/builder/SdCliClientBuilder.mjs +123 -53
- package/dist/builder/SdCliJsLibBuilder.mjs +4 -4
- package/dist/builder/SdCliTsLibBuilder.mjs +4 -4
- package/dist/commons.d.ts +25 -10
- package/dist/entry-points/SdCliLocalUpdate.mjs +3 -3
- package/dist/entry-points/SdCliWorkspace.mjs +21 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +2 -1
- package/dist/ng-tools/babel/SdCliBbFileMetadata.mjs +2 -2
- package/dist/ng-tools/babel/SdCliBbRootMetadata.d.ts +1 -0
- package/dist/ng-tools/babel/SdCliBbRootMetadata.mjs +29 -3
- package/package.json +11 -8
- package/src/bin/sd-cli.ts +18 -4
- package/src/build-tool/SdCliCordova.ts +130 -146
- package/src/build-tool/SdCliElectron.ts +25 -0
- package/src/builder/SdCliClientBuilder.ts +136 -54
- package/src/builder/SdCliJsLibBuilder.ts +3 -3
- package/src/builder/SdCliTsLibBuilder.ts +3 -3
- package/src/commons.ts +28 -10
- package/src/entry-points/SdCliLocalUpdate.ts +2 -2
- package/src/entry-points/SdCliWorkspace.ts +19 -3
- package/src/index.ts +1 -0
- package/src/ng-tools/babel/SdCliBbFileMetadata.ts +1 -1
- package/src/ng-tools/babel/SdCliBbRootMetadata.ts +30 -2
- package/tsconfig.json +3 -0
|
@@ -31,10 +31,11 @@ import { TransferSizePlugin } from "@angular-devkit/build-angular/src/webpack/pl
|
|
|
31
31
|
import { CssOptimizerPlugin } from "@angular-devkit/build-angular/src/webpack/plugins/css-optimizer-plugin";
|
|
32
32
|
import browserslist from "browserslist";
|
|
33
33
|
import { augmentAppWithServiceWorker } from "@angular-devkit/build-angular/src/utils/service-worker";
|
|
34
|
-
import { StringUtil } from "@simplysm/sd-core-common";
|
|
35
34
|
import { SdCliNgModuleGenerator } from "../ng-tools/SdCliNgModuleGenerator";
|
|
36
35
|
import { SdCliCordova } from "../build-tool/SdCliCordova";
|
|
37
36
|
import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
|
|
37
|
+
import electronBuilder from "electron-builder";
|
|
38
|
+
import { NeverEntryError } from "@simplysm/sd-core-common";
|
|
38
39
|
import LintResult = ESLint.LintResult;
|
|
39
40
|
|
|
40
41
|
export class SdCliClientBuilder extends EventEmitter {
|
|
@@ -84,8 +85,8 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
84
85
|
} : undefined);
|
|
85
86
|
|
|
86
87
|
// CORDOVA
|
|
87
|
-
if (this._config.cordova) {
|
|
88
|
-
this._cordova = new SdCliCordova(this._rootPath, this._config.cordova);
|
|
88
|
+
if (this._config.builders?.cordova) {
|
|
89
|
+
this._cordova = new SdCliCordova(this._rootPath, this._config.builders.cordova);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
|
|
@@ -97,6 +98,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
97
98
|
|
|
98
99
|
public async watchAsync(): Promise<NextHandleFunction[]> {
|
|
99
100
|
// DIST 비우기
|
|
101
|
+
await FsUtil.removeAsync(path.resolve(this._rootPath, ".electron"));
|
|
100
102
|
await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
|
|
101
103
|
|
|
102
104
|
// NgModule 생성
|
|
@@ -109,10 +111,11 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
// 빌드 준비
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
+
const webpackConfigs = (Object.keys(this._config.builders ?? { web: {} }) as ("web" | "cordova" | "electron")[])
|
|
115
|
+
.map((builderType) => this._getWebpackConfig(true, builderType));
|
|
116
|
+
const multiCompiler = webpack(webpackConfigs);
|
|
114
117
|
return await new Promise<NextHandleFunction[]>((resolve, reject) => {
|
|
115
|
-
|
|
118
|
+
multiCompiler.hooks.invalid.tap(this.constructor.name, (fileName) => {
|
|
116
119
|
if (fileName != null) {
|
|
117
120
|
this._logger.debug("파일변경 감지", fileName);
|
|
118
121
|
// NgModule 캐시 삭제
|
|
@@ -120,7 +123,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
120
123
|
}
|
|
121
124
|
});
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
multiCompiler.hooks.watchRun.tapAsync(this.constructor.name, async (args, callback) => {
|
|
124
127
|
this.emit("change");
|
|
125
128
|
|
|
126
129
|
// NgModule 생성
|
|
@@ -131,54 +134,58 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
131
134
|
this._logger.debug("Webpack 빌드 수행...");
|
|
132
135
|
});
|
|
133
136
|
|
|
134
|
-
compiler.
|
|
135
|
-
this.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
for (const compiler of multiCompiler.compilers) {
|
|
138
|
+
compiler.hooks.failed.tap(this.constructor.name, (err) => {
|
|
139
|
+
this.emit("complete", [{
|
|
140
|
+
filePath: undefined,
|
|
141
|
+
line: undefined,
|
|
142
|
+
char: undefined,
|
|
143
|
+
code: undefined,
|
|
144
|
+
severity: "error",
|
|
145
|
+
message: err.stack
|
|
146
|
+
}]);
|
|
147
|
+
reject(err);
|
|
148
|
+
return;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
146
151
|
|
|
147
|
-
|
|
152
|
+
multiCompiler.hooks.done.tap(this.constructor.name, async (multiStats) => {
|
|
148
153
|
// 결과 반환
|
|
149
|
-
const results = SdCliBuildResultUtil.convertFromWebpackStats(stats);
|
|
154
|
+
const results = multiStats.stats.mapMany((stats) => SdCliBuildResultUtil.convertFromWebpackStats(stats));
|
|
150
155
|
|
|
151
156
|
// .config.json 파일 쓰기
|
|
152
157
|
const npmConfig = this._getNpmConfig(this._rootPath)!;
|
|
153
158
|
const packageKey = npmConfig.name.split("/").last()!;
|
|
154
159
|
|
|
155
|
-
const configDistPath =
|
|
160
|
+
const configDistPath = typeof this._config.server === "string"
|
|
156
161
|
? path.resolve(this._workspaceRootPath, "packages", this._config.server, "dist/www", packageKey, ".config.json")
|
|
157
162
|
: path.resolve(this._parsedTsconfig.options.outDir!, ".config.json");
|
|
158
163
|
await FsUtil.writeFileAsync(configDistPath, JSON.stringify(this._config.configs ?? {}, undefined, 2));
|
|
159
164
|
|
|
160
165
|
// 마무리
|
|
161
166
|
this._logger.debug("Webpack 빌드 완료");
|
|
162
|
-
resolve(
|
|
167
|
+
resolve(middlewares);
|
|
163
168
|
|
|
164
169
|
this.emit("complete", results);
|
|
165
170
|
});
|
|
166
171
|
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
const middlewares = multiCompiler.compilers.mapMany((compiler) => [
|
|
173
|
+
wdm(compiler, {
|
|
174
|
+
publicPath: compiler.options.output.publicPath,
|
|
175
|
+
index: "index.html",
|
|
176
|
+
stats: false
|
|
177
|
+
}),
|
|
178
|
+
whm(compiler, {
|
|
179
|
+
path: `${compiler.options.output.publicPath}__webpack_hmr`,
|
|
180
|
+
log: false
|
|
181
|
+
})
|
|
182
|
+
]);
|
|
177
183
|
});
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
|
|
181
187
|
// DIST 비우기
|
|
188
|
+
await FsUtil.removeAsync(path.resolve(this._rootPath, ".electron"));
|
|
182
189
|
await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
|
|
183
190
|
|
|
184
191
|
// NgModule 생성
|
|
@@ -186,17 +193,18 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
186
193
|
|
|
187
194
|
// 빌드
|
|
188
195
|
this._logger.debug("Webpack 빌드 수행...");
|
|
189
|
-
const
|
|
190
|
-
const
|
|
196
|
+
const builderTypes = (Object.keys(this._config.builders ?? { web: {} }) as ("web" | "cordova" | "electron")[]);
|
|
197
|
+
const webpackConfigs = builderTypes.map((builderType) => this._getWebpackConfig(false, builderType));
|
|
198
|
+
const multipleCompiler = webpack(webpackConfigs);
|
|
191
199
|
const buildResults = await new Promise<ISdCliPackageBuildResult[]>((resolve, reject) => {
|
|
192
|
-
|
|
193
|
-
if (err != null ||
|
|
200
|
+
multipleCompiler.run((err, multiStats) => {
|
|
201
|
+
if (err != null || multiStats == null) {
|
|
194
202
|
reject(err);
|
|
195
203
|
return;
|
|
196
204
|
}
|
|
197
205
|
|
|
198
206
|
// 결과 반환
|
|
199
|
-
const results = SdCliBuildResultUtil.convertFromWebpackStats(stats);
|
|
207
|
+
const results = multiStats.stats.mapMany((stats) => SdCliBuildResultUtil.convertFromWebpackStats(stats));
|
|
200
208
|
resolve(results);
|
|
201
209
|
});
|
|
202
210
|
});
|
|
@@ -206,12 +214,12 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
206
214
|
await FsUtil.writeFileAsync(targetPath, JSON.stringify(this._config.configs ?? {}, undefined, 2));
|
|
207
215
|
|
|
208
216
|
// service-worker 처리
|
|
209
|
-
if (FsUtil.exists(path.resolve(this._rootPath, "ngsw-config.json"))) {
|
|
217
|
+
if (builderTypes.includes("web") && FsUtil.exists(path.resolve(this._rootPath, "ngsw-config.json"))) {
|
|
210
218
|
const packageKey = this._getNpmConfig(this._rootPath)!.name.split("/").last()!;
|
|
211
219
|
await augmentAppWithServiceWorker(
|
|
212
220
|
PathUtil.posix(path.relative(this._workspaceRootPath, this._rootPath)) as any,
|
|
213
|
-
PathUtil.posix(path.relative(this._workspaceRootPath, this._parsedTsconfig.options.outDir
|
|
214
|
-
`/${packageKey}/`,
|
|
221
|
+
PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._parsedTsconfig.options.outDir!, "web"))) as any,
|
|
222
|
+
`/${packageKey}/web/`,
|
|
215
223
|
PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._rootPath, "ngsw-config.json")))
|
|
216
224
|
);
|
|
217
225
|
}
|
|
@@ -222,7 +230,55 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
222
230
|
await this._cordova.initializeAsync();
|
|
223
231
|
|
|
224
232
|
this._logger.debug("CORDOVA 빌드...");
|
|
225
|
-
await this._cordova.buildAsync(this._parsedTsconfig.options.outDir
|
|
233
|
+
await this._cordova.buildAsync(path.resolve(this._parsedTsconfig.options.outDir!, "cordova"));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ELECTRON
|
|
237
|
+
if (this._config.builders?.electron) {
|
|
238
|
+
const npmConfig = this._getNpmConfig(this._rootPath)!;
|
|
239
|
+
|
|
240
|
+
if (npmConfig.dependencies?.["electron"] == null) {
|
|
241
|
+
throw new NeverEntryError();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
await FsUtil.writeJsonAsync(path.resolve(this._rootPath, `.electron/src/package.json`), {
|
|
245
|
+
name: npmConfig.name,
|
|
246
|
+
version: npmConfig.version,
|
|
247
|
+
description: npmConfig.description,
|
|
248
|
+
main: "electron.js",
|
|
249
|
+
author: npmConfig.author,
|
|
250
|
+
license: npmConfig.license,
|
|
251
|
+
devDependencies: {
|
|
252
|
+
"electron": npmConfig.dependencies["electron"].replace("^", "")
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
await FsUtil.writeFileAsync(path.resolve(this._rootPath, `.electron/src/.env`), `NODE_ENV=production`);
|
|
257
|
+
|
|
258
|
+
await FsUtil.copyAsync(path.resolve(this._rootPath, `src/electron.prod.js`), path.resolve(this._rootPath, ".electron/src/electron.js"));
|
|
259
|
+
|
|
260
|
+
await electronBuilder.build({
|
|
261
|
+
targets: electronBuilder.Platform.WINDOWS.createTarget(),
|
|
262
|
+
config: {
|
|
263
|
+
appId: this._config.builders.electron.appId,
|
|
264
|
+
productName: npmConfig.description,
|
|
265
|
+
asar: true,
|
|
266
|
+
nsis: {},
|
|
267
|
+
directories: {
|
|
268
|
+
app: path.resolve(this._rootPath, ".electron/src"),
|
|
269
|
+
output: path.resolve(this._rootPath, ".electron/dist")
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
await FsUtil.copyAsync(
|
|
275
|
+
path.resolve(this._rootPath, `.electron/dist/${npmConfig.description} Setup ${npmConfig.version}.exe`),
|
|
276
|
+
path.resolve(this._parsedTsconfig.options.outDir!, `electron/${npmConfig.description}-v${npmConfig.version}.exe`)
|
|
277
|
+
);
|
|
278
|
+
await FsUtil.copyAsync(
|
|
279
|
+
path.resolve(this._rootPath, `.electron/dist/${npmConfig.description} Setup ${npmConfig.version}.exe`),
|
|
280
|
+
path.resolve(this._parsedTsconfig.options.outDir!, `electron/${npmConfig.description}-latest.exe`)
|
|
281
|
+
);
|
|
226
282
|
}
|
|
227
283
|
|
|
228
284
|
// 마무리
|
|
@@ -237,7 +293,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
237
293
|
].map((p) => path.dirname(p));
|
|
238
294
|
}
|
|
239
295
|
|
|
240
|
-
private _getWebpackConfig(watch: boolean): webpack.Configuration {
|
|
296
|
+
private _getWebpackConfig(watch: boolean, builderType: "web" | "cordova" | "electron"): webpack.Configuration {
|
|
241
297
|
const workspaceNpmConfig = this._getNpmConfig(this._workspaceRootPath)!;
|
|
242
298
|
const workspaceName = workspaceNpmConfig.name;
|
|
243
299
|
|
|
@@ -248,12 +304,16 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
248
304
|
const ngVersion = this._getNpmConfig(FsUtil.findAllParentChildDirPaths("node_modules/@angular/core", this._rootPath, this._workspaceRootPath)[0])!.version;
|
|
249
305
|
|
|
250
306
|
const pkgKey = npmConfig.name.split("/").last()!;
|
|
251
|
-
const publicPath = (
|
|
307
|
+
const publicPath = (builderType === "web" || watch) ? `/${pkgKey}/${builderType}/` : ``;
|
|
252
308
|
|
|
253
309
|
const cacheBasePath = path.resolve(this._rootPath, ".cache");
|
|
254
310
|
const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
255
311
|
|
|
256
|
-
const distPath = (
|
|
312
|
+
const distPath = (builderType === "cordova" && !watch)
|
|
313
|
+
? path.resolve(this._cordova!.cordovaPath, "www")
|
|
314
|
+
: (builderType === "electron" && !watch)
|
|
315
|
+
? path.resolve(this._rootPath, ".electron/src")
|
|
316
|
+
: `${this._parsedTsconfig.options.outDir}/${builderType}`;
|
|
257
317
|
|
|
258
318
|
const sassImplementation = new SassWorkerImplementation();
|
|
259
319
|
|
|
@@ -265,7 +325,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
265
325
|
return {
|
|
266
326
|
mode: watch ? "development" : "production",
|
|
267
327
|
devtool: false,
|
|
268
|
-
target: ["web", "es2015"],
|
|
328
|
+
target: builderType === "electron" ? ["electron-renderer", "es2015"] : ["web", "es2015"],
|
|
269
329
|
profile: false,
|
|
270
330
|
resolve: {
|
|
271
331
|
roots: [this._rootPath],
|
|
@@ -273,7 +333,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
273
333
|
symlinks: true,
|
|
274
334
|
modules: [this._workspaceRootPath, "node_modules"],
|
|
275
335
|
mainFields: ["es2015", "browser", "module", "main"],
|
|
276
|
-
conditionNames: ["es2015", "..."]
|
|
336
|
+
conditionNames: ["es2015", "..."],
|
|
277
337
|
},
|
|
278
338
|
resolveLoader: {
|
|
279
339
|
symlinks: true
|
|
@@ -518,7 +578,9 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
518
578
|
}
|
|
519
579
|
}
|
|
520
580
|
}),
|
|
521
|
-
new CommonJsUsageWarnPlugin(
|
|
581
|
+
new CommonJsUsageWarnPlugin({
|
|
582
|
+
allowedDependencies: ["@fortawesome"]
|
|
583
|
+
}),
|
|
522
584
|
...watch ? [] : [
|
|
523
585
|
new LicenseWebpackPlugin({
|
|
524
586
|
stats: { warnings: false, errors: false },
|
|
@@ -529,7 +591,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
529
591
|
],
|
|
530
592
|
new CopyWebpackPlugin({
|
|
531
593
|
patterns: [
|
|
532
|
-
...["favicon.ico", "assets/", "manifest.
|
|
594
|
+
...["favicon.ico", "assets/", "manifest.json"].map((item) => ({
|
|
533
595
|
context: this._rootPath,
|
|
534
596
|
to: item,
|
|
535
597
|
from: `src/${item}`,
|
|
@@ -546,11 +608,31 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
546
608
|
},
|
|
547
609
|
priority: 0
|
|
548
610
|
})),
|
|
549
|
-
...
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
611
|
+
...builderType === "cordova" && watch ? this._cordova!.platforms.mapMany((platform) => [
|
|
612
|
+
{
|
|
613
|
+
context: this._cordova!.cordovaPath,
|
|
614
|
+
to: `cordova-${platform}/plugins`,
|
|
615
|
+
from: `platforms/${platform}/www/plugins`,
|
|
616
|
+
noErrorOnMissing: true
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
context: this._cordova!.cordovaPath,
|
|
620
|
+
to: `cordova-${platform}/cordova.js`,
|
|
621
|
+
from: `platforms/${platform}/www/cordova.js`
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
context: this._cordova!.cordovaPath,
|
|
625
|
+
to: `cordova-${platform}/cordova_plugins.js`,
|
|
626
|
+
from: `platforms/${platform}/www/cordova_plugins.js`,
|
|
627
|
+
noErrorOnMissing: true
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
context: this._cordova!.cordovaPath,
|
|
631
|
+
to: `cordova-${platform}/config.xml`,
|
|
632
|
+
from: `platforms/${platform}/www/config.xml`,
|
|
633
|
+
noErrorOnMissing: true
|
|
634
|
+
}
|
|
635
|
+
]) : []
|
|
554
636
|
]
|
|
555
637
|
}),
|
|
556
638
|
...watch ? [
|
|
@@ -25,15 +25,15 @@ export class SdCliJsLibBuilder extends EventEmitter {
|
|
|
25
25
|
|
|
26
26
|
const relatedPaths = await this.getRelatedPathsAsync();
|
|
27
27
|
const watcher = SdFsWatcher.watch(relatedPaths);
|
|
28
|
-
watcher.onChange({}, async (
|
|
29
|
-
const changeFilePaths =
|
|
28
|
+
watcher.onChange({}, async (changedInfos) => {
|
|
29
|
+
const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
30
30
|
if (changeFilePaths.length === 0) return;
|
|
31
31
|
|
|
32
32
|
this._logger.debug("파일 변경 감지");
|
|
33
33
|
this.emit("change");
|
|
34
34
|
const watchBuildResults: ISdCliPackageBuildResult[] = [];
|
|
35
35
|
|
|
36
|
-
const lintFilePaths =
|
|
36
|
+
const lintFilePaths = changedInfos.filter((item) => ["add", "change"].includes(item.event)).map((item) => item.path);
|
|
37
37
|
if (lintFilePaths.length > 0) {
|
|
38
38
|
watchBuildResults.push(...await this._linter.lintAsync(lintFilePaths));
|
|
39
39
|
}
|
|
@@ -115,8 +115,8 @@ export class SdCliTsLibBuilder extends EventEmitter {
|
|
|
115
115
|
this._logger.debug("변경감지 구성...");
|
|
116
116
|
const relatedPaths = await this.getAllRelatedPathsAsync();
|
|
117
117
|
const watcher = SdFsWatcher.watch(relatedPaths);
|
|
118
|
-
watcher.onChange({}, async (
|
|
119
|
-
const changeFilePaths =
|
|
118
|
+
watcher.onChange({}, async (changedInfos) => {
|
|
119
|
+
const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
120
120
|
if (changeFilePaths.length === 0) return;
|
|
121
121
|
|
|
122
122
|
this._logger.debug("파일 변경 감지", changeFilePaths);
|
|
@@ -153,7 +153,7 @@ export class SdCliTsLibBuilder extends EventEmitter {
|
|
|
153
153
|
this._logger.debug("린트...");
|
|
154
154
|
const lintFilePaths = [
|
|
155
155
|
...watchBuildPack.affectedSourceFiles.map((item) => item.fileName),
|
|
156
|
-
...
|
|
156
|
+
...changedInfos.filter((item) => ["add", "change"].includes(item.event)).map((item) => item.path)
|
|
157
157
|
];
|
|
158
158
|
if (lintFilePaths.length > 0) {
|
|
159
159
|
watchBuildResults.push(...await this._linter.lintAsync(lintFilePaths, watchBuildPack.program));
|
package/src/commons.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export interface INpmConfig {
|
|
2
2
|
name: string;
|
|
3
3
|
version: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
author?: string;
|
|
6
|
+
license?: string;
|
|
4
7
|
type?: "module";
|
|
5
8
|
workspaces?: string[];
|
|
6
9
|
main?: string;
|
|
@@ -63,8 +66,12 @@ export interface ISdCliServerPackageConfig {
|
|
|
63
66
|
|
|
64
67
|
export interface ISdCliClientPackageConfig {
|
|
65
68
|
type: "client";
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
builders?: {
|
|
70
|
+
web?: ISdCliClientBuilderWebConfig;
|
|
71
|
+
cordova?: ISdCliClientBuilderCordovaConfig;
|
|
72
|
+
electron?: ISdCliClientBuilderElectronConfig;
|
|
73
|
+
};
|
|
74
|
+
server: string | { port: number };
|
|
68
75
|
env?: Record<string, string>;
|
|
69
76
|
configs?: Record<string, any>;
|
|
70
77
|
publish?: TSdCliPublishConfig;
|
|
@@ -86,17 +93,21 @@ export interface ISdCliLocalDirectoryPublishConfig {
|
|
|
86
93
|
path: string;
|
|
87
94
|
}
|
|
88
95
|
|
|
89
|
-
export interface
|
|
90
|
-
|
|
96
|
+
export interface ISdCliClientBuilderWebConfig {
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface ISdCliClientBuilderCordovaConfig {
|
|
100
|
+
type: "cordova";
|
|
91
101
|
appId: string;
|
|
92
102
|
appName: string;
|
|
93
103
|
plugins?: string[];
|
|
94
104
|
icon?: string;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
debug?: boolean;
|
|
106
|
+
targets?: {
|
|
107
|
+
browser?: {};
|
|
108
|
+
android?: {
|
|
109
|
+
bundle?: boolean;
|
|
110
|
+
sign?: {
|
|
100
111
|
keystore: string;
|
|
101
112
|
storePassword: string;
|
|
102
113
|
alias: string;
|
|
@@ -107,4 +118,11 @@ export interface ISdCliClientPackageCordovaConfig {
|
|
|
107
118
|
};
|
|
108
119
|
}
|
|
109
120
|
|
|
110
|
-
export
|
|
121
|
+
export interface ISdCliClientBuilderElectronConfig {
|
|
122
|
+
appId: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type TSdCliClientBuilderConfig =
|
|
126
|
+
ISdCliClientBuilderWebConfig
|
|
127
|
+
| ISdCliClientBuilderCordovaConfig
|
|
128
|
+
| ISdCliClientBuilderElectronConfig;
|
|
@@ -42,8 +42,8 @@ export class SdCliLocalUpdate {
|
|
|
42
42
|
const watchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
43
43
|
|
|
44
44
|
const watcher = SdFsWatcher.watch(watchPaths);
|
|
45
|
-
watcher.onChange({ delay: 1000 }, async (
|
|
46
|
-
const changeFilePaths =
|
|
45
|
+
watcher.onChange({ delay: 1000 }, async (changedInfos) => {
|
|
46
|
+
const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
47
47
|
if (changeFilePaths.length === 0) return;
|
|
48
48
|
|
|
49
49
|
this._logger.log("로컬 라이브러리 변경감지...");
|
|
@@ -80,9 +80,25 @@ export class SdCliWorkspace {
|
|
|
80
80
|
if (pkg.config.type === "client") {
|
|
81
81
|
const middlewares = (await pkg.watchAsync()) as NextHandleFunction[];
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
if (typeof pkg.config.server === "string") {
|
|
84
|
+
const serverInfo = this._serverInfoMap.getOrCreate(pkg.config.server, { middlewares: [], clientInfos: [] });
|
|
85
|
+
serverInfo.middlewares.push(...middlewares);
|
|
86
|
+
serverInfo.clientInfos.push({ pkgKey: pkg.name.split("/").last()! });
|
|
87
|
+
}
|
|
88
|
+
else { // DEV SERVER
|
|
89
|
+
const serverInfo = this._serverInfoMap.getOrCreate("_", { middlewares: [], clientInfos: [] });
|
|
90
|
+
if (serverInfo.server === undefined) {
|
|
91
|
+
const server = new SdServiceServer({
|
|
92
|
+
rootPath: process.cwd(),
|
|
93
|
+
services: [],
|
|
94
|
+
port: pkg.config.server.port
|
|
95
|
+
});
|
|
96
|
+
await server.listenAsync();
|
|
97
|
+
serverInfo.server = server;
|
|
98
|
+
serverInfo.server.devMiddlewares = middlewares;
|
|
99
|
+
serverInfo.clientInfos.push({ pkgKey: pkg.name.split("/").last()! });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
86
102
|
}
|
|
87
103
|
else {
|
|
88
104
|
await pkg.watchAsync();
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./build-tool/SdCliCacheCompilerHost";
|
|
2
2
|
export * from "./build-tool/SdCliCordova";
|
|
3
|
+
export * from "./build-tool/SdCliElectron";
|
|
3
4
|
export * from "./build-tool/SdCliIndexFileGenerator";
|
|
4
5
|
export * from "./build-tool/SdCliNgCacheCompilerHost";
|
|
5
6
|
export * from "./build-tool/SdCliPackageLinter";
|
|
@@ -46,7 +46,7 @@ export class SdCliBbFileMetadata {
|
|
|
46
46
|
|
|
47
47
|
public constructor(public readonly filePath: string) {
|
|
48
48
|
let realFilePath: string | undefined;
|
|
49
|
-
for (const ext of ["", ".mjs", ".cjs", ".js"]) {
|
|
49
|
+
for (const ext of ["", ".mjs", ".cjs", ".js"/*, "/index.mjs", "/index.cjs", "/index.js"*/]) {
|
|
50
50
|
if (FsUtil.exists(filePath + ext) && !FsUtil.stat(filePath + ext).isDirectory()) {
|
|
51
51
|
realFilePath = filePath + ext;
|
|
52
52
|
break;
|
|
@@ -144,7 +144,10 @@ export class SdCliBbRootMetadata {
|
|
|
144
144
|
|
|
145
145
|
const entryFilePath = npmConfig["es2015"] ?? npmConfig["browser"] ?? npmConfig["module"] ?? npmConfig["main"] ?? npmConfig["default"];
|
|
146
146
|
if (typeof entryFilePath === "string") {
|
|
147
|
-
|
|
147
|
+
const realPath = this._getRealFilePath(path.resolve(ngDepPath, entryFilePath));
|
|
148
|
+
if (realPath != null) {
|
|
149
|
+
entryMap.set(npmConfig.name, realPath);
|
|
150
|
+
}
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
if (npmConfig.exports) {
|
|
@@ -168,7 +171,10 @@ export class SdCliBbRootMetadata {
|
|
|
168
171
|
const exportPath = path.resolve(ngDepPath, expEntryFilePath);
|
|
169
172
|
const exportResult = this._getGlobExportResult(PathUtil.posix(npmConfig.name, exportKey), exportPath);
|
|
170
173
|
for (const exportResultItem of exportResult) {
|
|
171
|
-
|
|
174
|
+
const realPath = this._getRealFilePath(exportResultItem.target);
|
|
175
|
+
if (realPath != null) {
|
|
176
|
+
entryMap.set(exportResultItem.name, realPath);
|
|
177
|
+
}
|
|
172
178
|
}
|
|
173
179
|
}
|
|
174
180
|
}
|
|
@@ -178,6 +184,28 @@ export class SdCliBbRootMetadata {
|
|
|
178
184
|
return entryMap;
|
|
179
185
|
}
|
|
180
186
|
|
|
187
|
+
private _getRealFilePath(itemPath: string): string | undefined {
|
|
188
|
+
if (!FsUtil.exists(itemPath)) {
|
|
189
|
+
for (const ext of [".mjs", ".cjs", ".js"]) {
|
|
190
|
+
if (FsUtil.exists(itemPath + ext)) {
|
|
191
|
+
return itemPath + ext;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else if (FsUtil.stat(itemPath).isFile()) {
|
|
196
|
+
return itemPath;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
for (const fileName of ["index.mjs", "index.cjs", "index.js"]) {
|
|
200
|
+
if (FsUtil.exists(path.resolve(itemPath, fileName))) {
|
|
201
|
+
return path.resolve(itemPath, fileName);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
|
|
181
209
|
private _getGlobExportResult(globName: string, globTarget: string): { name: string; target: string }[] {
|
|
182
210
|
if (globName.includes("*") && globTarget.includes("*")) {
|
|
183
211
|
const result: { name: string; target: string }[] = [];
|