@simplysm/sd-cli 11.0.8 → 11.0.11
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/build-cluster.js +25 -36
- package/dist/build-cluster.js.map +1 -1
- package/dist/build-tools/SdCliCordova.d.ts +21 -0
- package/dist/build-tools/SdCliCordova.js +182 -0
- package/dist/build-tools/SdCliCordova.js.map +1 -0
- package/dist/build-tools/SdCliNgRoutesFileGenerator.d.ts +4 -0
- package/dist/build-tools/SdCliNgRoutesFileGenerator.js +64 -0
- package/dist/build-tools/SdCliNgRoutesFileGenerator.js.map +1 -0
- package/dist/build-tools/SdLinter.js +8 -1
- package/dist/build-tools/SdLinter.js.map +1 -1
- package/dist/build-tools/SdNgBundler.d.ts +16 -5
- package/dist/build-tools/SdNgBundler.js +280 -179
- package/dist/build-tools/SdNgBundler.js.map +1 -1
- package/dist/build-tools/SdTsBundler.d.ts +6 -5
- package/dist/build-tools/SdTsBundler.js +78 -80
- package/dist/build-tools/SdTsBundler.js.map +1 -1
- package/dist/build-tools/SdTsCompiler.d.ts +1 -0
- package/dist/build-tools/SdTsCompiler.js +5 -1
- package/dist/build-tools/SdTsCompiler.js.map +1 -1
- package/dist/builders/SdCliClientBuilder.d.ts +1 -0
- package/dist/builders/SdCliClientBuilder.js +62 -27
- package/dist/builders/SdCliClientBuilder.js.map +1 -1
- package/dist/builders/SdCliServerBuilder.d.ts +6 -2
- package/dist/builders/SdCliServerBuilder.js +107 -141
- package/dist/builders/SdCliServerBuilder.js.map +1 -1
- package/dist/builders/SdCliTsLibBuilder.d.ts +6 -3
- package/dist/builders/SdCliTsLibBuilder.js +42 -45
- package/dist/builders/SdCliTsLibBuilder.js.map +1 -1
- package/dist/commons.d.ts +22 -2
- package/dist/entry/SdCliElectron.js +3 -3
- package/dist/entry/SdCliElectron.js.map +1 -1
- package/dist/entry/SdCliProject.d.ts +0 -3
- package/dist/entry/SdCliProject.js +10 -33
- package/dist/entry/SdCliProject.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/sd-cli.js +27 -21
- package/dist/sd-cli.js.map +1 -1
- package/dist/utils/SdMemoryLoadResultCache.d.ts +9 -0
- package/dist/utils/SdMemoryLoadResultCache.js +39 -0
- package/dist/utils/SdMemoryLoadResultCache.js.map +1 -0
- package/dist/utils/SdSourceFileCache.d.ts +5 -0
- package/dist/utils/SdSourceFileCache.js +9 -0
- package/dist/utils/SdSourceFileCache.js.map +1 -0
- package/lib/cordova-entry.js +22 -0
- package/package.json +19 -16
- package/src/build-cluster.ts +26 -36
- package/src/build-tools/SdCliCordova.ts +240 -0
- package/src/build-tools/SdCliNgRoutesFileGenerator.ts +80 -0
- package/src/build-tools/SdLinter.ts +12 -1
- package/src/build-tools/SdNgBundler.ts +428 -288
- package/src/build-tools/SdTsBundler.ts +86 -86
- package/src/build-tools/SdTsCompiler.ts +6 -1
- package/src/builders/SdCliClientBuilder.ts +76 -34
- package/src/builders/SdCliServerBuilder.ts +64 -63
- package/src/builders/SdCliTsLibBuilder.ts +58 -50
- package/src/commons.ts +24 -2
- package/src/entry/SdCliElectron.ts +3 -3
- package/src/entry/SdCliProject.ts +12 -41
- package/src/index.ts +4 -0
- package/src/sd-cli.ts +31 -21
- package/src/utils/SdMemoryLoadResultCache.ts +44 -0
- package/src/utils/SdSourceFileCache.ts +6 -0
|
@@ -4,104 +4,104 @@ import path from "path";
|
|
|
4
4
|
import esbuildPluginTsc from "esbuild-plugin-tsc";
|
|
5
5
|
|
|
6
6
|
export class SdTsBundler {
|
|
7
|
-
|
|
7
|
+
#context?: esbuild.BuildContext;
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
constructor(private readonly _opt: {
|
|
10
10
|
dev: boolean;
|
|
11
11
|
pkgPath: string;
|
|
12
12
|
entryPoints: string[];
|
|
13
|
-
|
|
13
|
+
external?: string[];
|
|
14
14
|
}) {
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
packages: "external",
|
|
68
|
-
// external: this._opt.external,
|
|
69
|
-
banner: {
|
|
70
|
-
js: `
|
|
17
|
+
async bundleAsync(): Promise<{
|
|
18
|
+
filePaths: string[];
|
|
19
|
+
results: ISdCliPackageBuildResult[];
|
|
20
|
+
}> {
|
|
21
|
+
if (!this.#context) {
|
|
22
|
+
this.#context = await esbuild.context({
|
|
23
|
+
entryPoints: this._opt.entryPoints,
|
|
24
|
+
keepNames: true,
|
|
25
|
+
bundle: true,
|
|
26
|
+
sourcemap: this._opt.dev,
|
|
27
|
+
target: "node16",
|
|
28
|
+
mainFields: ['es2020', 'es2015', 'module', 'main'],
|
|
29
|
+
conditions: ["es2020", "es2015", "module"],
|
|
30
|
+
tsconfig: path.resolve(this._opt.pkgPath, "tsconfig.json"),
|
|
31
|
+
write: true,
|
|
32
|
+
metafile: true,
|
|
33
|
+
outdir: path.resolve(this._opt.pkgPath, "dist"),
|
|
34
|
+
format: "esm",
|
|
35
|
+
resolveExtensions: [".js", ".mjs", ".cjs", ".ts"],
|
|
36
|
+
preserveSymlinks: false,
|
|
37
|
+
loader: {
|
|
38
|
+
".png": "file",
|
|
39
|
+
".jpeg": "file",
|
|
40
|
+
".jpg": "file",
|
|
41
|
+
".jfif": "file",
|
|
42
|
+
".gif": "file",
|
|
43
|
+
".svg": "file",
|
|
44
|
+
".woff": "file",
|
|
45
|
+
".woff2": "file",
|
|
46
|
+
".ttf": "file",
|
|
47
|
+
".eot": "file",
|
|
48
|
+
".ico": "file",
|
|
49
|
+
".otf": "file",
|
|
50
|
+
".csv": "file",
|
|
51
|
+
".xlsx": "file",
|
|
52
|
+
".xls": "file",
|
|
53
|
+
".pptx": "file",
|
|
54
|
+
".ppt": "file",
|
|
55
|
+
".docx": "file",
|
|
56
|
+
".doc": "file",
|
|
57
|
+
".zip": "file",
|
|
58
|
+
".pfx": "file",
|
|
59
|
+
".pkl": "file"
|
|
60
|
+
},
|
|
61
|
+
platform: "node",
|
|
62
|
+
logLevel: "silent",
|
|
63
|
+
// packages: "external",
|
|
64
|
+
external: this._opt.external,
|
|
65
|
+
banner: {
|
|
66
|
+
js: `
|
|
71
67
|
import __path__ from 'path';
|
|
72
68
|
import { fileURLToPath as __fileURLToPath__ } from 'url';
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
import { createRequire as __createRequire__ } from 'module';
|
|
70
|
+
|
|
71
|
+
const require = __createRequire__(import.meta.url);
|
|
76
72
|
const __filename = __fileURLToPath__(import.meta.url);
|
|
77
73
|
const __dirname = __path__.dirname(__filename);`.trim()
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
},
|
|
75
|
+
plugins: [
|
|
76
|
+
esbuildPluginTsc()
|
|
77
|
+
]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const result = await this.#context.rebuild();
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
filePaths: Object.keys(result.metafile!.inputs).map(item => path.resolve(process.cwd(), item)),
|
|
85
|
+
results: [
|
|
86
|
+
...result.warnings.map((warn) => ({
|
|
87
|
+
type: "build" as const,
|
|
88
|
+
filePath: warn.location?.file !== undefined ? path.resolve(warn.location.file) : undefined,
|
|
89
|
+
line: warn.location?.line,
|
|
90
|
+
char: warn.location?.column,
|
|
91
|
+
code: undefined,
|
|
92
|
+
severity: "warning" as const,
|
|
93
|
+
message: warn.text
|
|
94
|
+
})),
|
|
95
|
+
...result.errors.map((err) => ({
|
|
96
|
+
type: "build" as const,
|
|
97
|
+
filePath: err.location?.file !== undefined ? path.resolve(err.location.file) : undefined,
|
|
98
|
+
line: err.location?.line,
|
|
99
|
+
char: err.location?.column !== undefined ? err.location.column + 1 : undefined,
|
|
100
|
+
code: undefined,
|
|
101
|
+
severity: "error" as const,
|
|
102
|
+
message: err.text
|
|
103
|
+
}))
|
|
81
104
|
]
|
|
82
105
|
};
|
|
83
106
|
}
|
|
84
|
-
|
|
85
|
-
private _convertResults(result: esbuild.BuildResult): ISdCliPackageBuildResult[] {
|
|
86
|
-
return [
|
|
87
|
-
...result.warnings.map((warn) => ({
|
|
88
|
-
type: "build" as const,
|
|
89
|
-
filePath: warn.location?.file !== undefined ? path.resolve(warn.location.file) : undefined,
|
|
90
|
-
line: warn.location?.line,
|
|
91
|
-
char: warn.location?.column,
|
|
92
|
-
code: undefined,
|
|
93
|
-
severity: "warning" as const,
|
|
94
|
-
message: warn.text
|
|
95
|
-
})),
|
|
96
|
-
...result.errors.map((err) => ({
|
|
97
|
-
type: "build" as const,
|
|
98
|
-
filePath: err.location?.file !== undefined ? path.resolve(err.location.file) : undefined,
|
|
99
|
-
line: err.location?.line,
|
|
100
|
-
char: err.location?.column !== undefined ? err.location.column + 1 : undefined,
|
|
101
|
-
code: undefined,
|
|
102
|
-
severity: "error" as const,
|
|
103
|
-
message: err.text
|
|
104
|
-
}))
|
|
105
|
-
];
|
|
106
|
-
}
|
|
107
107
|
}
|
|
@@ -99,6 +99,7 @@ export class SdTsCompiler {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
public async buildAsync(): Promise<{
|
|
102
|
+
filePaths: string[];
|
|
102
103
|
affectedFilePaths: string[];
|
|
103
104
|
results: ISdCliPackageBuildResult[];
|
|
104
105
|
}> {
|
|
@@ -290,7 +291,11 @@ export class SdTsCompiler {
|
|
|
290
291
|
const buildResults = diagnostics.map((item) => SdCliBuildResultUtil.convertFromTsDiag(item, this._opt.emit ? "build" : "check"));
|
|
291
292
|
|
|
292
293
|
return {
|
|
293
|
-
|
|
294
|
+
filePaths: [
|
|
295
|
+
...Array.from(this._styleDepsCache.keys()),
|
|
296
|
+
...this._builder.getSourceFiles().map(item => path.resolve(item.fileName))
|
|
297
|
+
],
|
|
298
|
+
affectedFilePaths: affectedFilePaths,
|
|
294
299
|
results: buildResults
|
|
295
300
|
};
|
|
296
301
|
}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import {EventEmitter} from "events";
|
|
2
2
|
import {FsUtil, Logger, PathUtil, SdFsWatcher} from "@simplysm/sd-core-node";
|
|
3
3
|
import {ISdCliBuilderResult, ISdCliClientPackageConfig, ISdCliConfig, ISdCliPackageBuildResult} from "../commons";
|
|
4
|
-
import {FunctionQueue
|
|
4
|
+
import {FunctionQueue} from "@simplysm/sd-core-common";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import {SdNgBundler} from "../build-tools/SdNgBundler";
|
|
7
7
|
import {SdLinter} from "../build-tools/SdLinter";
|
|
8
|
+
import {SdCliCordova} from "../build-tools/SdCliCordova";
|
|
9
|
+
import {SdCliNgRoutesFileGenerator} from "../build-tools/SdCliNgRoutesFileGenerator";
|
|
8
10
|
|
|
9
11
|
export class SdCliClientBuilder extends EventEmitter {
|
|
10
12
|
private readonly _logger = Logger.get(["simplysm", "sd-cli", "SdCliClientBuilder"]);
|
|
11
13
|
private readonly _pkgConf: ISdCliClientPackageConfig;
|
|
12
14
|
private _builders?: SdNgBundler[];
|
|
15
|
+
private _cordova?: SdCliCordova;
|
|
13
16
|
|
|
14
17
|
public constructor(private readonly _projConf: ISdCliConfig,
|
|
15
18
|
private readonly _pkgPath: string) {
|
|
@@ -28,7 +31,14 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
28
31
|
this._debug("dist 초기화...");
|
|
29
32
|
await FsUtil.removeAsync(path.resolve(this._pkgPath, "dist"));
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
this._debug(`GEN index.ts...`);
|
|
35
|
+
await SdCliNgRoutesFileGenerator.runAsync(this._pkgPath);
|
|
36
|
+
|
|
37
|
+
this._debug("GEN .config...");
|
|
38
|
+
const confDistPath = path.resolve(this._pkgPath, "dist/.config.json");
|
|
39
|
+
await FsUtil.writeFileAsync(confDistPath, JSON.stringify(this._pkgConf.configs ?? {}, undefined, 2));
|
|
40
|
+
|
|
41
|
+
return await this._runAsync({dev: false});
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
public async watchAsync(): Promise<void> {
|
|
@@ -37,16 +47,20 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
37
47
|
this._debug("dist 초기화...");
|
|
38
48
|
await FsUtil.removeAsync(path.resolve(this._pkgPath, "dist"));
|
|
39
49
|
|
|
40
|
-
|
|
50
|
+
this._debug(`WATCH GEN index.ts...`);
|
|
51
|
+
await SdCliNgRoutesFileGenerator.watchAsync(this._pkgPath);
|
|
52
|
+
|
|
53
|
+
this._debug("GEN .config...");
|
|
54
|
+
const confDistPath = path.resolve(this._pkgPath, "dist/.config.json");
|
|
55
|
+
await FsUtil.writeFileAsync(confDistPath, JSON.stringify(this._pkgConf.configs ?? {}, undefined, 2));
|
|
56
|
+
|
|
57
|
+
const result = await this._runAsync({dev: true});
|
|
41
58
|
this.emit("complete", result);
|
|
42
59
|
|
|
43
60
|
this._debug("WATCH...");
|
|
44
61
|
const fnQ = new FunctionQueue();
|
|
45
62
|
const watcher = SdFsWatcher
|
|
46
|
-
.watch(
|
|
47
|
-
...result.watchFilePaths,
|
|
48
|
-
path.resolve(this._pkgPath, "src/**/*.*")
|
|
49
|
-
])
|
|
63
|
+
.watch(result.watchFilePaths)
|
|
50
64
|
.onChange({delay: 100}, (changeInfos) => {
|
|
51
65
|
for (const builder of this._builders!) {
|
|
52
66
|
builder.removeCache(changeInfos.map((item) => item.path));
|
|
@@ -55,7 +69,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
55
69
|
fnQ.runLast(async () => {
|
|
56
70
|
this.emit("change");
|
|
57
71
|
|
|
58
|
-
const watchResult = await this._runAsync({dev: true
|
|
72
|
+
const watchResult = await this._runAsync({dev: true});
|
|
59
73
|
this.emit("complete", watchResult);
|
|
60
74
|
|
|
61
75
|
watcher.add(watchResult.watchFilePaths);
|
|
@@ -65,19 +79,39 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
65
79
|
|
|
66
80
|
private async _runAsync(opt: {
|
|
67
81
|
dev: boolean;
|
|
68
|
-
genConf: boolean;
|
|
69
82
|
}): Promise<{
|
|
70
83
|
watchFilePaths: string[];
|
|
71
84
|
affectedFilePaths: string[];
|
|
72
85
|
buildResults: ISdCliPackageBuildResult[];
|
|
73
86
|
}> {
|
|
74
|
-
this.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
const builderTypes = (Object.keys(this._pkgConf.builder ?? {web: {}}) as ("web" | "electron" | "cordova")[]);
|
|
88
|
+
if (this._pkgConf.builder?.cordova && !this._cordova) {
|
|
89
|
+
this._debug("CORDOVA 준비...");
|
|
90
|
+
this._cordova = new SdCliCordova({
|
|
91
|
+
pkgPath: this._pkgPath,
|
|
92
|
+
config: this._pkgConf.builder.cordova,
|
|
93
|
+
cordovaPath: path.resolve(this._pkgPath, ".cordova")
|
|
94
|
+
});
|
|
95
|
+
await this._cordova.initializeAsync();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!this._builders) {
|
|
99
|
+
this._debug(`BUILD 준비...`);
|
|
100
|
+
this._builders = builderTypes.map((builderType) => new SdNgBundler({
|
|
101
|
+
dev: opt.dev,
|
|
102
|
+
builderType: builderType,
|
|
103
|
+
pkgPath: this._pkgPath,
|
|
104
|
+
cordovaPlatforms: builderType === "cordova" ? Object.keys(this._pkgConf.builder!.cordova!.platform ?? {browser: {}}) : undefined,
|
|
105
|
+
outputPath: builderType === "web" ? path.resolve(this._pkgPath, "dist")
|
|
106
|
+
: builderType === "electron" ? path.resolve(this._pkgPath, ".electron/src")
|
|
107
|
+
: builderType === "cordova" && !opt.dev ? path.resolve(this._pkgPath, ".cordova/www")
|
|
108
|
+
: path.resolve(this._pkgPath, "dist", builderType),
|
|
109
|
+
env: {
|
|
110
|
+
...this._pkgConf.env,
|
|
111
|
+
...this._pkgConf.builder?.[builderType]?.env
|
|
112
|
+
}
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
81
115
|
|
|
82
116
|
this._debug(`BUILD & CHECK...`);
|
|
83
117
|
const buildResults = await Promise.all(this._builders.map((builder) => builder.bundleAsync()));
|
|
@@ -86,29 +120,37 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
86
120
|
const results = buildResults.mapMany((item) => item.results).distinct();
|
|
87
121
|
|
|
88
122
|
this._debug(`LINT...`);
|
|
89
|
-
const lintResults = await SdLinter.lintAsync(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
await FsUtil.writeJsonAsync(path.resolve(this._pkgPath, "dist/.config.json"), this._pkgConf.configs ?? {}, {space: 2});
|
|
100
|
-
}
|
|
123
|
+
const lintResults = await SdLinter.lintAsync(
|
|
124
|
+
affectedFilePaths,
|
|
125
|
+
this._pkgPath
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
if (!opt.dev && this._cordova) {
|
|
129
|
+
this._debug("CORDOVA BUILD...");
|
|
130
|
+
await this._cordova.buildAsync(path.resolve(this._pkgPath, "dist"));
|
|
101
131
|
}
|
|
102
132
|
|
|
133
|
+
this._debug(`빌드 완료`);
|
|
103
134
|
const localUpdatePaths = Object.keys(this._projConf.localUpdates ?? {})
|
|
104
135
|
.mapMany((key) => FsUtil.glob(path.resolve(this._pkgPath, "../../node_modules", key)));
|
|
105
|
-
const watchFilePaths = filePaths
|
|
106
|
-
.
|
|
107
|
-
PathUtil.isChildPath(item, path.resolve(this._pkgPath, "../"))
|
|
108
|
-
|
|
109
|
-
|
|
136
|
+
/*const watchFilePaths = filePaths
|
|
137
|
+
.map((item) => {
|
|
138
|
+
if (PathUtil.isChildPath(item, path.resolve(this._pkgPath, "../"))) {
|
|
139
|
+
return path.resolve(this._pkgPath, "..", path.relative(path.resolve(this._pkgPath, "../"), item).split("\\").slice(0, 2).join("/"), "**!/!*.*");
|
|
140
|
+
}
|
|
110
141
|
|
|
111
|
-
|
|
142
|
+
const localUpdatePath = localUpdatePaths.single((lu) => PathUtil.isChildPath(item, lu));
|
|
143
|
+
if (localUpdatePath != null) {
|
|
144
|
+
return path.resolve(localUpdatePath, path.relative(localUpdatePath, item).split("\\").slice(0, 1).join("/"), "**!/!*.*");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return undefined;
|
|
148
|
+
}).filterExists().distinct();
|
|
149
|
+
console.log(watchFilePaths);*/
|
|
150
|
+
const watchFilePaths = filePaths.filter(item =>
|
|
151
|
+
PathUtil.isChildPath(item, path.resolve(this._pkgPath, "../")) ||
|
|
152
|
+
localUpdatePaths.some((lu) => PathUtil.isChildPath(item, lu))
|
|
153
|
+
);
|
|
112
154
|
return {
|
|
113
155
|
watchFilePaths: watchFilePaths,
|
|
114
156
|
affectedFilePaths: affectedFilePaths,
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import {EventEmitter} from "events";
|
|
2
|
-
import {FsUtil, Logger, SdFsWatcher} from "@simplysm/sd-core-node";
|
|
3
|
-
import {
|
|
2
|
+
import {FsUtil, Logger, PathUtil, SdFsWatcher} from "@simplysm/sd-core-node";
|
|
3
|
+
import {
|
|
4
|
+
INpmConfig,
|
|
5
|
+
ISdCliBuilderResult,
|
|
6
|
+
ISdCliConfig,
|
|
7
|
+
ISdCliPackageBuildResult,
|
|
8
|
+
ISdCliServerPackageConfig,
|
|
9
|
+
ITsConfig
|
|
10
|
+
} from "../commons";
|
|
4
11
|
import path from "path";
|
|
5
12
|
import {SdTsCompiler} from "../build-tools/SdTsCompiler";
|
|
6
13
|
import {SdLinter} from "../build-tools/SdLinter";
|
|
7
|
-
import {FunctionQueue, ObjectUtil} from "@simplysm/sd-core-common";
|
|
14
|
+
import {FunctionQueue, ObjectUtil, StringUtil} from "@simplysm/sd-core-common";
|
|
8
15
|
import {SdTsBundler} from "../build-tools/SdTsBundler";
|
|
9
16
|
|
|
10
17
|
export class SdCliServerBuilder extends EventEmitter {
|
|
11
18
|
private readonly _logger = Logger.get(["simplysm", "sd-cli", "SdCliServerBuilder"]);
|
|
12
19
|
private readonly _pkgConf: ISdCliServerPackageConfig;
|
|
20
|
+
private _builder?: SdTsBundler;
|
|
21
|
+
private _checker?: SdTsCompiler;
|
|
22
|
+
private _extModules?: { name: string; exists: boolean }[];
|
|
13
23
|
|
|
14
24
|
public constructor(private readonly _projConf: ISdCliConfig,
|
|
15
|
-
private readonly _pkgPath: string
|
|
16
|
-
private readonly _withLint: boolean) {
|
|
25
|
+
private readonly _pkgPath: string) {
|
|
17
26
|
super();
|
|
18
27
|
this._pkgConf = this._projConf.packages[path.basename(_pkgPath)] as ISdCliServerPackageConfig;
|
|
19
28
|
}
|
|
@@ -26,7 +35,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
public async watchAsync(): Promise<void> {
|
|
29
|
-
|
|
38
|
+
this.emit("change");
|
|
30
39
|
|
|
31
40
|
this._debug("dist 초기화...");
|
|
32
41
|
await FsUtil.removeAsync(path.resolve(this._pkgPath, "dist"));
|
|
@@ -35,58 +44,28 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
35
44
|
const confDistPath = path.resolve(this._pkgPath, "dist/.config.json");
|
|
36
45
|
await FsUtil.writeFileAsync(confDistPath, JSON.stringify(this._pkgConf.configs ?? {}, undefined, 2));
|
|
37
46
|
|
|
38
|
-
this.
|
|
39
|
-
|
|
40
|
-
dev: false,
|
|
41
|
-
pkgPath: this._pkgPath,
|
|
42
|
-
entryPoints: [
|
|
43
|
-
path.resolve(this._pkgPath, "src/main.ts")
|
|
44
|
-
],
|
|
45
|
-
// external: extModules.map((item) => item.name)
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const checker = new SdTsCompiler({
|
|
49
|
-
pkgPath: this._pkgPath,
|
|
50
|
-
emit: false,
|
|
51
|
-
emitDts: false,
|
|
52
|
-
globalStyle: false
|
|
53
|
-
});
|
|
47
|
+
const result = await this._runAsync({dev: true});
|
|
48
|
+
this.emit("complete", result);
|
|
54
49
|
|
|
55
50
|
this._debug("WATCH...");
|
|
56
51
|
const fnQ = new FunctionQueue();
|
|
57
|
-
SdFsWatcher
|
|
58
|
-
.watch(
|
|
59
|
-
|
|
60
|
-
], {
|
|
61
|
-
ignoreInitial: false
|
|
62
|
-
})
|
|
63
|
-
.onChange({
|
|
64
|
-
delay: 100
|
|
65
|
-
}, () => {
|
|
52
|
+
const watcher = SdFsWatcher
|
|
53
|
+
.watch(result.watchFilePaths)
|
|
54
|
+
.onChange({delay: 100}, () => {
|
|
66
55
|
fnQ.runLast(async () => {
|
|
67
56
|
this.emit("change");
|
|
68
57
|
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this._debug("CHECK...");
|
|
73
|
-
const checkResult = await checker.buildAsync();
|
|
74
|
-
|
|
75
|
-
this._debug(`LINT...`);
|
|
76
|
-
const lintResults = !this._withLint ? [] : await SdLinter.lintAsync(checkResult.affectedFilePaths, checker.program);
|
|
58
|
+
const watchResult = await this._runAsync({dev: true});
|
|
59
|
+
this.emit("complete", watchResult);
|
|
77
60
|
|
|
78
|
-
|
|
79
|
-
this.emit("complete", {
|
|
80
|
-
affectedFilePaths: checkResult.affectedFilePaths,
|
|
81
|
-
buildResults: [...buildResults, ...checkResult.results, ...lintResults]
|
|
82
|
-
});
|
|
61
|
+
watcher.add(watchResult.watchFilePaths);
|
|
83
62
|
});
|
|
84
63
|
});
|
|
85
64
|
}
|
|
86
65
|
|
|
87
66
|
public async buildAsync(): Promise<ISdCliBuilderResult> {
|
|
88
67
|
const npmConfig = (await FsUtil.readJsonAsync(path.resolve(this._pkgPath, "package.json"))) as INpmConfig;
|
|
89
|
-
|
|
68
|
+
const extModules = await this._getExternalModulesAsync();
|
|
90
69
|
|
|
91
70
|
this._debug("dist 초기화...");
|
|
92
71
|
await FsUtil.removeAsync(path.resolve(this._pkgPath, "dist"));
|
|
@@ -97,13 +76,13 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
97
76
|
|
|
98
77
|
this._debug("GEN package.json...");
|
|
99
78
|
{
|
|
100
|
-
|
|
79
|
+
const deps = extModules.filter((item) => item.exists).map((item) => item.name);
|
|
101
80
|
|
|
102
81
|
const distNpmConfig = ObjectUtil.clone(npmConfig);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
82
|
+
distNpmConfig.dependencies = {};
|
|
83
|
+
for (const dep of deps) {
|
|
84
|
+
distNpmConfig.dependencies[dep] = "*";
|
|
85
|
+
}
|
|
107
86
|
delete distNpmConfig.optionalDependencies;
|
|
108
87
|
delete distNpmConfig.devDependencies;
|
|
109
88
|
delete distNpmConfig.peerDependencies;
|
|
@@ -177,17 +156,29 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
177
156
|
`.trim());
|
|
178
157
|
}
|
|
179
158
|
|
|
159
|
+
return await this._runAsync({dev: false});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private async _runAsync(opt: { dev: boolean }): Promise<{
|
|
163
|
+
watchFilePaths: string[];
|
|
164
|
+
affectedFilePaths: string[];
|
|
165
|
+
buildResults: ISdCliPackageBuildResult[];
|
|
166
|
+
}> {
|
|
180
167
|
this._debug(`BUILD 준비...`);
|
|
181
|
-
|
|
182
|
-
|
|
168
|
+
|
|
169
|
+
this._extModules = this._extModules ?? await this._getExternalModulesAsync();
|
|
170
|
+
|
|
171
|
+
const tsConfig = FsUtil.readJson(path.resolve(this._pkgPath, "tsconfig.json")) as ITsConfig;
|
|
172
|
+
this._builder = this._builder ?? new SdTsBundler({
|
|
173
|
+
dev: opt.dev,
|
|
183
174
|
pkgPath: this._pkgPath,
|
|
184
|
-
entryPoints: [
|
|
175
|
+
entryPoints: tsConfig.files ? tsConfig.files.map((item) => path.resolve(this._pkgPath, item)) : [
|
|
185
176
|
path.resolve(this._pkgPath, "src/main.ts")
|
|
186
177
|
],
|
|
187
|
-
|
|
178
|
+
external: this._extModules.map((item) => item.name)
|
|
188
179
|
});
|
|
189
180
|
|
|
190
|
-
|
|
181
|
+
this._checker = this._checker ?? new SdTsCompiler({
|
|
191
182
|
pkgPath: this._pkgPath,
|
|
192
183
|
emit: false,
|
|
193
184
|
emitDts: false,
|
|
@@ -195,22 +186,32 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
195
186
|
});
|
|
196
187
|
|
|
197
188
|
this._debug(`BUILD...`);
|
|
198
|
-
const
|
|
189
|
+
const buildResult = await this._builder.bundleAsync();
|
|
199
190
|
|
|
200
191
|
this._debug("CHECK...");
|
|
201
|
-
const checkResult = await
|
|
192
|
+
const checkResult = await this._checker.buildAsync();
|
|
202
193
|
|
|
203
194
|
this._debug(`LINT...`);
|
|
204
|
-
const lintResults =
|
|
195
|
+
const lintResults = await SdLinter.lintAsync(checkResult.affectedFilePaths, this._checker.program);
|
|
205
196
|
|
|
206
197
|
this._debug(`빌드 완료`);
|
|
198
|
+
const localUpdatePaths = Object.keys(this._projConf.localUpdates ?? {})
|
|
199
|
+
.mapMany((key) => FsUtil.glob(path.resolve(this._pkgPath, "../../node_modules", key)));
|
|
200
|
+
const watchFilePaths = [
|
|
201
|
+
...buildResult.filePaths,
|
|
202
|
+
...checkResult.filePaths,
|
|
203
|
+
].filter(item =>
|
|
204
|
+
PathUtil.isChildPath(item, path.resolve(this._pkgPath, "../")) ||
|
|
205
|
+
localUpdatePaths.some((lu) => PathUtil.isChildPath(item, lu))
|
|
206
|
+
);
|
|
207
207
|
return {
|
|
208
|
+
watchFilePaths,
|
|
208
209
|
affectedFilePaths: checkResult.affectedFilePaths,
|
|
209
|
-
buildResults: [...
|
|
210
|
+
buildResults: [...buildResult.results, ...checkResult.results, ...lintResults]
|
|
210
211
|
};
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
|
|
214
|
+
private async _getExternalModulesAsync(): Promise<{
|
|
214
215
|
name: string;
|
|
215
216
|
exists: boolean
|
|
216
217
|
}[]> {
|
|
@@ -245,7 +246,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
245
246
|
continue;
|
|
246
247
|
}
|
|
247
248
|
|
|
248
|
-
if (FsUtil.glob(path.resolve(modulePath, "
|
|
249
|
+
if (FsUtil.glob(path.resolve(modulePath, "binding.gyp")).length > 0) {
|
|
249
250
|
results.push({
|
|
250
251
|
name: moduleName,
|
|
251
252
|
exists: true
|
|
@@ -275,7 +276,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
275
276
|
continue;
|
|
276
277
|
}
|
|
277
278
|
|
|
278
|
-
if (FsUtil.glob(path.resolve(optModulePath, "
|
|
279
|
+
if (FsUtil.glob(path.resolve(optModulePath, "binding.gyp")).length > 0) {
|
|
279
280
|
results.push({
|
|
280
281
|
name: optModuleName,
|
|
281
282
|
exists: true
|
|
@@ -296,7 +297,7 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
296
297
|
await fn(this._pkgPath);
|
|
297
298
|
|
|
298
299
|
return results;
|
|
299
|
-
}
|
|
300
|
+
}
|
|
300
301
|
|
|
301
302
|
private _debug(msg: string): void {
|
|
302
303
|
this._logger.debug(`[${path.basename(this._pkgPath)}] ${msg}`);
|