@simplysm/sd-cli 12.5.22 → 12.5.24
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/entry/SdCliCordova.js +2 -2
- package/dist/entry/SdCliCordova.js.map +1 -1
- package/dist/entry/SdCliElectron.js +2 -2
- package/dist/entry/SdCliElectron.js.map +1 -1
- package/dist/entry/SdCliLocalUpdate.js +6 -8
- package/dist/entry/SdCliLocalUpdate.js.map +1 -1
- package/dist/entry/SdCliProject.js +4 -4
- package/dist/entry/SdCliProject.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pkg-builders/SdMultiBuildRunner.d.ts +3 -10
- package/dist/pkg-builders/SdMultiBuildRunner.js +133 -117
- package/dist/pkg-builders/SdMultiBuildRunner.js.map +1 -1
- package/dist/pkg-builders/client/SdCliNgRoutesFileGenerator.js +1 -1
- package/dist/pkg-builders/client/SdCliNgRoutesFileGenerator.js.map +1 -1
- package/dist/pkg-builders/client/SdClientBuildRunner.d.ts +6 -5
- package/dist/pkg-builders/client/SdClientBuildRunner.js +16 -8
- package/dist/pkg-builders/client/SdClientBuildRunner.js.map +1 -1
- package/dist/pkg-builders/client/SdNgBundler.js +13 -61
- package/dist/pkg-builders/client/SdNgBundler.js.map +1 -1
- package/dist/pkg-builders/client/createSdNgPlugin.js +3 -3
- package/dist/pkg-builders/client/createSdNgPlugin.js.map +1 -1
- package/dist/pkg-builders/lib/SdCliIndexFileGenerator.js +1 -1
- package/dist/pkg-builders/lib/SdCliIndexFileGenerator.js.map +1 -1
- package/dist/pkg-builders/lib/SdJsLibBuildRunner.js +1 -1
- package/dist/pkg-builders/lib/SdTsLibBuildRunner.d.ts +6 -1
- package/dist/pkg-builders/lib/SdTsLibBuildRunner.js +27 -28
- package/dist/pkg-builders/lib/SdTsLibBuildRunner.js.map +1 -1
- package/dist/pkg-builders/lib/SdTsLibBuilder.d.ts +3 -4
- package/dist/pkg-builders/lib/SdTsLibBuilder.js +7 -11
- package/dist/pkg-builders/lib/SdTsLibBuilder.js.map +1 -1
- package/dist/pkg-builders/server/SdServerBuildRunner.d.ts +5 -1
- package/dist/pkg-builders/server/SdServerBuildRunner.js +32 -29
- package/dist/pkg-builders/server/SdServerBuildRunner.js.map +1 -1
- package/dist/pkg-builders/server/createSdServerPlugin.js +3 -3
- package/dist/pkg-builders/server/createSdServerPlugin.js.map +1 -1
- package/dist/ts-builder/SdTsCompiler.d.ts +1 -1
- package/dist/ts-builder/SdTsCompiler.js +222 -201
- package/dist/ts-builder/SdTsCompiler.js.map +1 -1
- package/dist/types/build-runner.type.d.ts +7 -0
- package/dist/types/build-runner.type.js +2 -0
- package/dist/types/build-runner.type.js.map +1 -0
- package/dist/types/workers.type.d.ts +15 -1
- package/dist/workers/build-runner-worker.js +45 -0
- package/dist/workers/build-runner-worker.js.map +1 -0
- package/package.json +6 -6
- package/src/entry/SdCliCordova.ts +2 -2
- package/src/entry/SdCliElectron.ts +2 -2
- package/src/entry/SdCliLocalUpdate.ts +8 -8
- package/src/entry/SdCliProject.ts +4 -4
- package/src/index.ts +1 -1
- package/src/pkg-builders/SdMultiBuildRunner.ts +123 -121
- package/src/pkg-builders/client/SdCliNgRoutesFileGenerator.ts +1 -1
- package/src/pkg-builders/client/SdClientBuildRunner.ts +26 -22
- package/src/pkg-builders/client/SdNgBundler.ts +16 -74
- package/src/pkg-builders/client/createSdNgPlugin.ts +3 -3
- package/src/pkg-builders/lib/SdCliIndexFileGenerator.ts +1 -1
- package/src/pkg-builders/lib/SdJsLibBuildRunner.ts +1 -1
- package/src/pkg-builders/lib/SdTsLibBuildRunner.ts +42 -29
- package/src/pkg-builders/lib/SdTsLibBuilder.ts +13 -14
- package/src/pkg-builders/server/SdServerBuildRunner.ts +44 -29
- package/src/pkg-builders/server/createSdServerPlugin.ts +3 -3
- package/src/ts-builder/SdTsCompiler.ts +282 -261
- package/src/types/build-runner.type.ts +8 -0
- package/src/types/workers.type.ts +14 -1
- package/src/workers/build-runner-worker.ts +52 -0
- package/tsconfig.json +1 -1
- package/dist/ts-builder/SdTsCompileWorker.d.ts +0 -9
- package/dist/ts-builder/SdTsCompileWorker.js +0 -16
- package/dist/ts-builder/SdTsCompileWorker.js.map +0 -1
- package/dist/workers/compile-worker.js +0 -27
- package/dist/workers/compile-worker.js.map +0 -1
- package/lib/dev-worker.cjs +0 -5
- package/src/ts-builder/SdTsCompileWorker.ts +0 -21
- package/src/workers/compile-worker.ts +0 -31
- /package/dist/workers/{compile-worker.d.ts → build-runner-worker.d.ts} +0 -0
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { FsUtil, Logger, PathUtil, SdWorker, TNormPath } from "@simplysm/sd-core-node";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { EventEmitter } from "events";
|
|
4
|
-
import {
|
|
5
|
-
import { SdClientBuildRunner } from "./client/SdClientBuildRunner";
|
|
6
|
-
import { SdTsLibBuildRunner } from "./lib/SdTsLibBuildRunner";
|
|
7
|
-
import { SdJsLibBuildRunner } from "./lib/SdJsLibBuildRunner";
|
|
8
|
-
import { ISdProjectConfig, ISdServerPackageConfig } from "../types/sd-configs.type";
|
|
4
|
+
import { ISdServerPackageConfig } from "../types/sd-configs.type";
|
|
9
5
|
import { ISdBuildMessage, ISdBuildRunnerResult } from "../types/build.type";
|
|
10
|
-
import { TServerWorkerType } from "../types/workers.type";
|
|
6
|
+
import { TSdBuildRunnerWorkerType, TServerWorkerType } from "../types/workers.type";
|
|
11
7
|
import { INpmConfig } from "../types/common-configs.type";
|
|
8
|
+
import { ISdBuildRunnerWorkerRequest } from "../types/build-runner.type";
|
|
12
9
|
|
|
13
10
|
export class SdMultiBuildRunner extends EventEmitter {
|
|
14
11
|
#logger = Logger.get(["simplysm", "sd-cli", "SdMultiBuildRunner"]);
|
|
@@ -43,10 +40,20 @@ export class SdMultiBuildRunner extends EventEmitter {
|
|
|
43
40
|
return this;
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
async runAsync(req:
|
|
47
|
-
async runAsync(req:
|
|
48
|
-
async runAsync(req:
|
|
49
|
-
const
|
|
43
|
+
async runAsync(req: ISdBuildRunnerWorkerRequest & { cmd: "watch" }): Promise<void>;
|
|
44
|
+
async runAsync(req: ISdBuildRunnerWorkerRequest & { cmd: "build" }): Promise<ISdBuildMessage[]>;
|
|
45
|
+
async runAsync(req: ISdBuildRunnerWorkerRequest): Promise<ISdBuildMessage[] | void> {
|
|
46
|
+
const worker = new SdWorker<TSdBuildRunnerWorkerType>(import.meta.resolve("../workers/build-runner-worker"))
|
|
47
|
+
.on("change", () => {
|
|
48
|
+
if (this.#busyCount === 0) {
|
|
49
|
+
this.emit("change");
|
|
50
|
+
}
|
|
51
|
+
this.#busyCount++;
|
|
52
|
+
})
|
|
53
|
+
.on("complete", (result) => this.#onComplete(req, result));
|
|
54
|
+
|
|
55
|
+
return await worker.run("run", [req]);
|
|
56
|
+
/*const pkgConf = req.projConf.packages[path.basename(req.pkgPath)]!;
|
|
50
57
|
|
|
51
58
|
const buildRunnerType =
|
|
52
59
|
pkgConf.type === "server"
|
|
@@ -67,140 +74,133 @@ export class SdMultiBuildRunner extends EventEmitter {
|
|
|
67
74
|
} else {
|
|
68
75
|
await builder.watchAsync();
|
|
69
76
|
return;
|
|
70
|
-
}
|
|
77
|
+
}*/
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.#busyCount++;
|
|
79
|
-
} else {
|
|
80
|
-
this.#resultCache.delete(req.pkgPath);
|
|
81
|
-
for (const affectedFilePath of res.result.affectedFilePathSet) {
|
|
82
|
-
if (PathUtil.isChildPath(affectedFilePath, req.pkgPath)) {
|
|
83
|
-
this.#resultCache.delete(affectedFilePath);
|
|
84
|
-
}
|
|
80
|
+
#onComplete(req: ISdBuildRunnerWorkerRequest, result: ISdBuildRunnerResult) {
|
|
81
|
+
this.#resultCache.delete(req.pkgPath);
|
|
82
|
+
for (const affectedFilePath of result.affectedFilePathSet) {
|
|
83
|
+
if (PathUtil.isChildPath(affectedFilePath, req.pkgPath)) {
|
|
84
|
+
this.#resultCache.delete(affectedFilePath);
|
|
85
85
|
}
|
|
86
|
+
}
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
for (const buildMessage of result.buildMessages) {
|
|
89
|
+
const cacheItem = this.#resultCache.getOrCreate(buildMessage.filePath ?? req.pkgPath, []);
|
|
90
|
+
cacheItem.push(buildMessage);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const pkgConf = req.projConf.packages[path.basename(req.pkgPath)]!;
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
if (pkgConf.type === "server") {
|
|
96
|
+
const pkgName = path.basename(req.pkgPath);
|
|
97
|
+
const serverInfo = this.#serverInfoMap.getOrCreate(pkgName, {
|
|
98
|
+
hasChanges: true,
|
|
99
|
+
clientChangedFileSet: new Set(),
|
|
100
|
+
clients: {},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const serverPkgConf = req.projConf.packages[pkgName] as ISdServerPackageConfig;
|
|
104
|
+
serverInfo.pkgInfo = {
|
|
105
|
+
path: req.pkgPath,
|
|
106
|
+
conf: serverPkgConf,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
serverInfo.hasChanges = true;
|
|
110
|
+
} else if (pkgConf.type === "client") {
|
|
111
|
+
const pkgName = path.basename(req.pkgPath);
|
|
112
|
+
|
|
113
|
+
if (pkgConf.server !== undefined) {
|
|
114
|
+
const serverInfo = this.#serverInfoMap.getOrCreate(
|
|
115
|
+
typeof pkgConf.server === "string" ? pkgConf.server : pkgConf.server.port.toString(),
|
|
116
|
+
{
|
|
117
|
+
hasChanges: true,
|
|
118
|
+
clientChangedFileSet: new Set(),
|
|
119
|
+
clients: {},
|
|
120
|
+
},
|
|
121
|
+
);
|
|
93
122
|
|
|
94
|
-
|
|
95
|
-
|
|
123
|
+
if (typeof pkgConf.server !== "string") {
|
|
124
|
+
serverInfo.pkgInfo = pkgConf.server;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
serverInfo.clients[pkgName] = {
|
|
128
|
+
path: path.resolve(req.pkgPath, "dist"),
|
|
129
|
+
buildTypes: (pkgConf.builder ? Object.keys(pkgConf.builder) : ["web"]) as any,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
serverInfo.clientChangedFileSet.adds(...result.emitFileSet);
|
|
133
|
+
} else {
|
|
96
134
|
const serverInfo = this.#serverInfoMap.getOrCreate(pkgName, {
|
|
97
135
|
hasChanges: true,
|
|
98
136
|
clientChangedFileSet: new Set(),
|
|
99
137
|
clients: {},
|
|
100
138
|
});
|
|
101
139
|
|
|
102
|
-
|
|
103
|
-
serverInfo.pkgInfo = {
|
|
104
|
-
path: req.pkgPath,
|
|
105
|
-
conf: serverPkgConf,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
serverInfo.hasChanges = true;
|
|
109
|
-
} else if (pkgConf.type === "client") {
|
|
110
|
-
const pkgName = path.basename(req.pkgPath);
|
|
111
|
-
|
|
112
|
-
if (pkgConf.server !== undefined) {
|
|
113
|
-
const serverInfo = this.#serverInfoMap.getOrCreate(
|
|
114
|
-
typeof pkgConf.server === "string" ? pkgConf.server : pkgConf.server.port.toString(),
|
|
115
|
-
{
|
|
116
|
-
hasChanges: true,
|
|
117
|
-
clientChangedFileSet: new Set(),
|
|
118
|
-
clients: {},
|
|
119
|
-
},
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
if (typeof pkgConf.server !== "string") {
|
|
123
|
-
serverInfo.pkgInfo = pkgConf.server;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
serverInfo.clients[pkgName] = {
|
|
127
|
-
path: path.resolve(req.pkgPath, "dist"),
|
|
128
|
-
buildTypes: (pkgConf.builder ? Object.keys(pkgConf.builder) : ["web"]) as any,
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
serverInfo.clientChangedFileSet.adds(...res.result.emitFileSet);
|
|
132
|
-
} else {
|
|
133
|
-
const serverInfo = this.#serverInfoMap.getOrCreate(pkgName, {
|
|
134
|
-
hasChanges: true,
|
|
135
|
-
clientChangedFileSet: new Set(),
|
|
136
|
-
clients: {},
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
serverInfo.clientChangedFileSet.adds(...res.result.emitFileSet);
|
|
140
|
-
}
|
|
140
|
+
serverInfo.clientChangedFileSet.adds(...result.emitFileSet);
|
|
141
141
|
}
|
|
142
|
+
}
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
144
|
+
setTimeout(async () => {
|
|
145
|
+
this.#busyCount--;
|
|
146
|
+
if (this.#busyCount === 0) {
|
|
147
|
+
for (const serverPkgNameOrPort of this.#serverInfoMap.keys()) {
|
|
148
|
+
const serverInfo = this.#serverInfoMap.get(serverPkgNameOrPort)!;
|
|
149
|
+
if (serverInfo.pkgInfo && serverInfo.hasChanges) {
|
|
150
|
+
this.#logger.debug("서버 재시작...");
|
|
151
|
+
try {
|
|
152
|
+
const restartServerResult = await this.#restartServerAsync(serverInfo.pkgInfo, serverInfo.worker);
|
|
153
|
+
serverInfo.worker = restartServerResult.worker;
|
|
154
|
+
serverInfo.port = restartServerResult.port;
|
|
155
|
+
serverInfo.hasChanges = false;
|
|
156
|
+
} catch (err) {
|
|
157
|
+
this.#logger.error(err);
|
|
158
158
|
}
|
|
159
|
+
}
|
|
159
160
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
161
|
+
if (serverInfo.worker) {
|
|
162
|
+
this.#logger.debug("클라이언트 설정...");
|
|
163
|
+
await serverInfo.worker.run("setPathProxy", [
|
|
164
|
+
{
|
|
165
|
+
...Object.keys(serverInfo.clients).toObject(
|
|
166
|
+
(key) => key,
|
|
167
|
+
(key) => serverInfo.clients[key].path,
|
|
168
|
+
),
|
|
169
|
+
node_modules: path.resolve(process.cwd(), "node_modules"),
|
|
170
|
+
},
|
|
171
|
+
]);
|
|
172
|
+
|
|
173
|
+
if (serverInfo.clientChangedFileSet.size > 0) {
|
|
174
|
+
this.#logger.debug("클라이언트 새로고침...");
|
|
175
|
+
await serverInfo.worker.run("broadcastReload", [serverInfo.clientChangedFileSet]);
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
+
}
|
|
178
179
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
180
|
+
const clientPaths: string[] = [];
|
|
181
|
+
for (const serverInfo of this.#serverInfoMap.values()) {
|
|
182
|
+
if (Object.keys(serverInfo.clients).length > 0) {
|
|
183
|
+
for (const clientPkgName of Object.keys(serverInfo.clients)) {
|
|
184
|
+
for (const buildType of serverInfo.clients[clientPkgName].buildTypes) {
|
|
185
|
+
if (buildType === "web") {
|
|
186
|
+
clientPaths.push(`http://localhost:${serverInfo.port}/${clientPkgName}/`);
|
|
187
|
+
} else {
|
|
188
|
+
clientPaths.push(`http://localhost:${serverInfo.port}/${clientPkgName}/${buildType}/`);
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
-
} else {
|
|
192
|
-
clientPaths.push(`http://localhost:${serverInfo.port}/`);
|
|
193
191
|
}
|
|
192
|
+
} else {
|
|
193
|
+
clientPaths.push(`http://localhost:${serverInfo.port}/`);
|
|
194
194
|
}
|
|
195
|
-
if (clientPaths.length > 0) {
|
|
196
|
-
this.#logger.info("클라이언트 개발 서버 접속 주소\n" + clientPaths.join("\n"));
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const messages = Array.from(this.#resultCache.values()).mapMany();
|
|
200
|
-
this.emit("complete", messages);
|
|
201
195
|
}
|
|
202
|
-
|
|
203
|
-
|
|
196
|
+
if (clientPaths.length > 0) {
|
|
197
|
+
this.#logger.info("클라이언트 개발 서버 접속 주소\n" + clientPaths.join("\n"));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const messages = Array.from(this.#resultCache.values()).mapMany();
|
|
201
|
+
this.emit("complete", messages);
|
|
202
|
+
}
|
|
203
|
+
}, 300);
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
async #restartServerAsync(
|
|
@@ -213,7 +213,7 @@ export class SdMultiBuildRunner extends EventEmitter {
|
|
|
213
213
|
const logger = Logger.get(["simplysm", "sd-cli", "SdMultiBuildRunner", "#restartServerAsync"]);
|
|
214
214
|
|
|
215
215
|
if (prevWorker) {
|
|
216
|
-
prevWorker.
|
|
216
|
+
await prevWorker.killAsync();
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
const npmConf =
|
|
@@ -234,6 +234,7 @@ export class SdMultiBuildRunner extends EventEmitter {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
/*
|
|
237
238
|
interface IRequest {
|
|
238
239
|
cmd: "watch" | "build";
|
|
239
240
|
pkgPath: TNormPath;
|
|
@@ -248,3 +249,4 @@ type TResponse =
|
|
|
248
249
|
type: "complete";
|
|
249
250
|
result: ISdBuildRunnerResult;
|
|
250
251
|
};
|
|
252
|
+
*/
|
|
@@ -7,7 +7,7 @@ export class SdCliNgRoutesFileGenerator {
|
|
|
7
7
|
const routesFilePath = path.resolve(pkgPath, "src/routes.ts");
|
|
8
8
|
let cache = FsUtil.exists(routesFilePath) ? FsUtil.readFile(routesFilePath) : undefined;
|
|
9
9
|
|
|
10
|
-
SdFsWatcher.watch([path.resolve(pkgPath, "src")]).onChange({ delay:
|
|
10
|
+
SdFsWatcher.watch([path.resolve(pkgPath, "src")]).onChange({ delay: 50 }, () => {
|
|
11
11
|
cache = this.run(pkgPath, cache, noLazyRoute);
|
|
12
12
|
});
|
|
13
13
|
|
|
@@ -10,19 +10,27 @@ import { INpmConfig } from "../../types/common-configs.type";
|
|
|
10
10
|
import { ISdBuildMessage, ISdBuildRunnerResult } from "../../types/build.type";
|
|
11
11
|
|
|
12
12
|
export class SdClientBuildRunner extends EventEmitter {
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private
|
|
13
|
+
private _logger = Logger.get(["simplysm", "sd-cli", "SdClientBuildRunner"]);
|
|
14
|
+
private _pkgConf: ISdClientPackageConfig;
|
|
15
|
+
private _npmConf: INpmConfig;
|
|
16
16
|
private _ngBundlers?: SdNgBundler[];
|
|
17
17
|
private _cordova?: SdCliCordova;
|
|
18
|
+
private _watchScopePathSet: Set<TNormPath>;
|
|
18
19
|
|
|
19
20
|
public constructor(
|
|
20
|
-
private
|
|
21
|
-
private
|
|
21
|
+
private _projConf: ISdProjectConfig,
|
|
22
|
+
private _pkgPath: TNormPath,
|
|
22
23
|
) {
|
|
23
24
|
super();
|
|
24
25
|
this._pkgConf = this._projConf.packages[path.basename(_pkgPath)] as ISdClientPackageConfig;
|
|
25
26
|
this._npmConf = FsUtil.readJson(path.resolve(_pkgPath, "package.json")) as INpmConfig;
|
|
27
|
+
|
|
28
|
+
const localUpdatePaths = Object.keys(this._projConf.localUpdates ?? {}).mapMany((key) =>
|
|
29
|
+
FsUtil.glob(path.resolve(this._pkgPath, "../../node_modules", key)),
|
|
30
|
+
);
|
|
31
|
+
this._watchScopePathSet = new Set(
|
|
32
|
+
[path.resolve(this._pkgPath, "../"), ...localUpdatePaths].map((item) => PathUtil.norm(item)),
|
|
33
|
+
);
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
public override on(event: "change", listener: () => void): this;
|
|
@@ -77,11 +85,15 @@ export class SdClientBuildRunner extends EventEmitter {
|
|
|
77
85
|
this.emit("complete", res);
|
|
78
86
|
|
|
79
87
|
this._debug("WATCH...");
|
|
80
|
-
|
|
88
|
+
let lastWatchFileSet = result.watchFileSet;
|
|
89
|
+
SdFsWatcher.watch(Array.from(this._watchScopePathSet)).onChange({ delay: 100 }, async (changeInfos) => {
|
|
90
|
+
const currentChangeInfos = changeInfos.filter((item) => lastWatchFileSet.has(item.path));
|
|
91
|
+
if (currentChangeInfos.length < 1) return;
|
|
92
|
+
|
|
81
93
|
this.emit("change");
|
|
82
94
|
|
|
83
95
|
for (const ngBundler of this._ngBundlers!) {
|
|
84
|
-
ngBundler.markForChanges(
|
|
96
|
+
ngBundler.markForChanges(currentChangeInfos.map((item) => item.path));
|
|
85
97
|
}
|
|
86
98
|
|
|
87
99
|
const watchResult = await this._runAsync({ dev: !this._pkgConf.forceProductionMode });
|
|
@@ -92,7 +104,7 @@ export class SdClientBuildRunner extends EventEmitter {
|
|
|
92
104
|
};
|
|
93
105
|
this.emit("complete", watchRes);
|
|
94
106
|
|
|
95
|
-
|
|
107
|
+
lastWatchFileSet = watchResult.watchFileSet;
|
|
96
108
|
});
|
|
97
109
|
}
|
|
98
110
|
|
|
@@ -102,10 +114,6 @@ export class SdClientBuildRunner extends EventEmitter {
|
|
|
102
114
|
buildMessages: ISdBuildMessage[];
|
|
103
115
|
emitFileSet: Set<TNormPath>;
|
|
104
116
|
}> {
|
|
105
|
-
const localUpdatePaths = Object.keys(this._projConf.localUpdates ?? {}).mapMany((key) =>
|
|
106
|
-
FsUtil.glob(path.resolve(this._pkgPath, "../../node_modules", key)),
|
|
107
|
-
);
|
|
108
|
-
|
|
109
117
|
const ngBundlerBuilderTypes = Object.keys(this._pkgConf.builder ?? { web: {} }) as (
|
|
110
118
|
| "web"
|
|
111
119
|
| "electron"
|
|
@@ -142,9 +150,7 @@ export class SdClientBuildRunner extends EventEmitter {
|
|
|
142
150
|
...this._pkgConf.builder?.[ngBundlerBuilderType]?.env,
|
|
143
151
|
},
|
|
144
152
|
cordovaConfig: ngBundlerBuilderType === "cordova" ? this._pkgConf.builder!.cordova : undefined,
|
|
145
|
-
watchScopePaths:
|
|
146
|
-
PathUtil.norm(item),
|
|
147
|
-
),
|
|
153
|
+
watchScopePaths: Array.from(this._watchScopePathSet),
|
|
148
154
|
}),
|
|
149
155
|
);
|
|
150
156
|
}
|
|
@@ -170,15 +176,13 @@ export class SdClientBuildRunner extends EventEmitter {
|
|
|
170
176
|
}
|
|
171
177
|
|
|
172
178
|
this._debug(`빌드 완료`);
|
|
173
|
-
const currWatchFileSet = new Set(
|
|
174
|
-
Array.from(watchFileSet).filter(
|
|
175
|
-
(
|
|
176
|
-
PathUtil.isChildPath(item, path.resolve(this._pkgPath, "../")) ||
|
|
177
|
-
localUpdatePaths.some((lu) => PathUtil.isChildPath(item, lu)),
|
|
179
|
+
/*const currWatchFileSet = new Set(
|
|
180
|
+
Array.from(watchFileSet).filter((item) =>
|
|
181
|
+
Array.from(this._watchScopePathSet).some((scope) => PathUtil.isChildPath(item, scope)),
|
|
178
182
|
),
|
|
179
|
-
)
|
|
183
|
+
);*/
|
|
180
184
|
return {
|
|
181
|
-
watchFileSet
|
|
185
|
+
watchFileSet,
|
|
182
186
|
affectedFileSet,
|
|
183
187
|
buildMessages: results, //.filter((item) => item.filePath !== path.resolve(this._pkgPath, "src/routes.ts")),
|
|
184
188
|
emitFileSet,
|
|
@@ -18,14 +18,9 @@ import {
|
|
|
18
18
|
InitialFileRecord,
|
|
19
19
|
} from "@angular/build/src/tools/esbuild/bundler-context";
|
|
20
20
|
import { extractLicenses } from "@angular/build/src/tools/esbuild/license-extractor";
|
|
21
|
-
import {
|
|
22
|
-
HintMode,
|
|
23
|
-
IndexHtmlGenerator,
|
|
24
|
-
IndexHtmlProcessResult,
|
|
25
|
-
} from "@angular/build/src/utils/index-file/index-html-generator";
|
|
21
|
+
import { IndexHtmlGenerator, IndexHtmlProcessResult } from "@angular/build/src/utils/index-file/index-html-generator";
|
|
26
22
|
import { Entrypoint } from "@angular/build/src/utils/index-file/augment-index-html";
|
|
27
23
|
import { CrossOrigin } from "@angular/build/src/builders/application/schema";
|
|
28
|
-
import { InlineCriticalCssProcessor } from "@angular/build/src/utils/index-file/inline-critical-css";
|
|
29
24
|
import { augmentAppWithServiceWorkerEsbuild } from "@angular/build/src/utils/service-worker";
|
|
30
25
|
import { createSourcemapIgnorelistPlugin } from "@angular/build/src/tools/esbuild/sourcemap-ignorelist-plugin";
|
|
31
26
|
import { StylesheetPluginFactory } from "@angular/build/src/tools/esbuild/stylesheets/stylesheet-plugin-factory";
|
|
@@ -43,10 +38,6 @@ import { ISdBuildMessage } from "../../types/build.type";
|
|
|
43
38
|
export class SdNgBundler {
|
|
44
39
|
readonly #logger = Logger.get(["simplysm", "sd-cli", "SdNgBundler"]);
|
|
45
40
|
|
|
46
|
-
// private readonly _sourceFileCache = new SourceFileCache(
|
|
47
|
-
// path.resolve(this._opt.pkgPath, ".cache")
|
|
48
|
-
// );
|
|
49
|
-
|
|
50
41
|
readonly #modifiedFileSet = new Set<TNormPath>();
|
|
51
42
|
readonly #ngResultCache: ISdCliNgPluginResultCache = {
|
|
52
43
|
affectedFileSet: new Set<TNormPath>(),
|
|
@@ -155,7 +146,7 @@ export class SdNgBundler {
|
|
|
155
146
|
|
|
156
147
|
this.#debug(`create index.html...`);
|
|
157
148
|
await perf.run("create index.html", async () => {
|
|
158
|
-
const genIndexHtmlResult = await this._genIndexHtmlAsync(
|
|
149
|
+
const genIndexHtmlResult = await this._genIndexHtmlAsync(initialFiles);
|
|
159
150
|
for (const warning of genIndexHtmlResult.warnings) {
|
|
160
151
|
results.push({
|
|
161
152
|
filePath: undefined,
|
|
@@ -251,6 +242,7 @@ export class SdNgBundler {
|
|
|
251
242
|
watchFileSet: new Set([
|
|
252
243
|
...this.#ngResultCache.watchFileSet!,
|
|
253
244
|
...this.#styleLoadResultCache.watchFiles.map((item) => PathUtil.norm(item)),
|
|
245
|
+
...assetFiles.map((item) => PathUtil.norm(item.source)),
|
|
254
246
|
PathUtil.norm(this.#indexHtmlFilePath),
|
|
255
247
|
]),
|
|
256
248
|
affectedFileSet: this.#ngResultCache.affectedFileSet!,
|
|
@@ -259,60 +251,30 @@ export class SdNgBundler {
|
|
|
259
251
|
};
|
|
260
252
|
}
|
|
261
253
|
|
|
262
|
-
private async _genIndexHtmlAsync(
|
|
263
|
-
outputFiles: esbuild.OutputFile[],
|
|
264
|
-
initialFiles: Map<string, InitialFileRecord>,
|
|
265
|
-
): Promise<IndexHtmlProcessResult> {
|
|
266
|
-
const readAsset = (filePath: string): Promise<string> => {
|
|
267
|
-
const relFilePath = path.relative("/", filePath);
|
|
268
|
-
const currFile = outputFiles.find((outputFile) => outputFile.path === relFilePath);
|
|
269
|
-
if (currFile) {
|
|
270
|
-
return Promise.resolve(currFile.text);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
throw new Error(`Output file does not exist: ${relFilePath}`);
|
|
274
|
-
};
|
|
275
|
-
|
|
254
|
+
private async _genIndexHtmlAsync(initialFiles: Map<string, InitialFileRecord>): Promise<IndexHtmlProcessResult> {
|
|
276
255
|
const indexHtmlGenerator = new IndexHtmlGenerator({
|
|
277
256
|
indexPath: this.#indexHtmlFilePath,
|
|
278
257
|
entrypoints: [
|
|
279
|
-
["runtime", true],
|
|
280
258
|
["polyfills", true],
|
|
281
259
|
["styles", false],
|
|
282
|
-
["vendor", true],
|
|
283
260
|
["main", true],
|
|
284
261
|
...(this._opt.builderType === "cordova" ? [["cordova-entry", true] as Entrypoint] : []),
|
|
285
262
|
],
|
|
263
|
+
sri: false,
|
|
286
264
|
optimization: {
|
|
287
265
|
scripts: !this._opt.dev,
|
|
288
|
-
fonts: { inline: !this._opt.dev },
|
|
289
266
|
styles: {
|
|
290
267
|
minify: !this._opt.dev,
|
|
291
|
-
inlineCritical:
|
|
268
|
+
inlineCritical: !this._opt.dev,
|
|
269
|
+
removeSpecialComments: !this._opt.dev,
|
|
292
270
|
},
|
|
271
|
+
fonts: { inline: !this._opt.dev },
|
|
293
272
|
},
|
|
294
273
|
crossOrigin: CrossOrigin.None,
|
|
274
|
+
generateDedicatedSSRContent: false,
|
|
295
275
|
});
|
|
296
|
-
indexHtmlGenerator.readAsset = readAsset;
|
|
297
|
-
|
|
298
|
-
const hints: { url: string; mode: HintMode; as?: string }[] = [];
|
|
299
|
-
if (!this._opt.dev) {
|
|
300
|
-
for (const [key, value] of initialFiles) {
|
|
301
|
-
if (value.entrypoint) {
|
|
302
|
-
continue;
|
|
303
|
-
}
|
|
304
276
|
|
|
305
|
-
|
|
306
|
-
hints.push({ url: key, mode: "modulepreload" as const });
|
|
307
|
-
}
|
|
308
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
309
|
-
else if (value.type === "style") {
|
|
310
|
-
hints.push({ url: key, mode: "preload" as const, as: "style" });
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const transformResult = await indexHtmlGenerator.process({
|
|
277
|
+
return await indexHtmlGenerator.process({
|
|
316
278
|
baseHref: this.#baseHref,
|
|
317
279
|
lang: undefined,
|
|
318
280
|
outputPath: "/",
|
|
@@ -321,29 +283,9 @@ export class SdNgBundler {
|
|
|
321
283
|
file,
|
|
322
284
|
extension: path.extname(file),
|
|
323
285
|
})),
|
|
324
|
-
hints,
|
|
325
286
|
});
|
|
326
|
-
|
|
327
|
-
if (this._opt.dev) {
|
|
328
|
-
return transformResult;
|
|
329
|
-
} else {
|
|
330
|
-
const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({
|
|
331
|
-
minify: false,
|
|
332
|
-
readAsset,
|
|
333
|
-
});
|
|
334
|
-
const { content, errors, warnings } = await inlineCriticalCssProcessor.process(transformResult.csrContent, {
|
|
335
|
-
outputPath: "/",
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
return {
|
|
339
|
-
warnings: [...transformResult.warnings, ...warnings],
|
|
340
|
-
errors: [...transformResult.errors, ...errors],
|
|
341
|
-
csrContent: content,
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
287
|
}
|
|
345
288
|
|
|
346
|
-
//TODO: index.html 파일에 manifest.json 정보 추가? manifest.webmanifest ? PWA?
|
|
347
289
|
private async _copyAssetsAsync(): Promise<
|
|
348
290
|
{
|
|
349
291
|
source: string;
|
|
@@ -352,11 +294,8 @@ export class SdNgBundler {
|
|
|
352
294
|
> {
|
|
353
295
|
return await resolveAssets(
|
|
354
296
|
[
|
|
355
|
-
{ input: "
|
|
356
|
-
{ input: "
|
|
357
|
-
{ input: "src", glob: "manifest.json", output: "" },
|
|
358
|
-
{ input: "src/assets", glob: "**/*", output: "assets" },
|
|
359
|
-
...(this._opt.dev ? [{ input: "src/assets-dev", glob: "**/*", output: "assets-dev" }] : []),
|
|
297
|
+
{ input: "public", glob: "**/*", output: "." },
|
|
298
|
+
...(this._opt.dev ? [{ input: "public-dev", glob: "**/*", output: "." }] : []),
|
|
360
299
|
...(this._opt.dev && this._opt.builderType === "cordova"
|
|
361
300
|
? Object.keys(this._opt.cordovaConfig?.platform ?? { browser: {} }).mapMany((platform) => [
|
|
362
301
|
{
|
|
@@ -461,7 +400,10 @@ export class SdNgBundler {
|
|
|
461
400
|
polyfills: path.resolve(this._opt.pkgPath, "src/polyfills.ts"),
|
|
462
401
|
...(this._opt.builderType === "cordova"
|
|
463
402
|
? {
|
|
464
|
-
"cordova-entry": path.resolve(
|
|
403
|
+
"cordova-entry": path.resolve(
|
|
404
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
405
|
+
`../../../lib/cordova-entry.js`,
|
|
406
|
+
),
|
|
465
407
|
}
|
|
466
408
|
: {}),
|
|
467
409
|
...workerEntries,
|
|
@@ -7,7 +7,7 @@ import { SdCliPerformanceTimer } from "../../utils/SdCliPerformanceTime";
|
|
|
7
7
|
import { SdCliConvertMessageUtil } from "../../utils/SdCliConvertMessageUtil";
|
|
8
8
|
import { ISdCliNgPluginResultCache } from "../../types/build-plugin.type";
|
|
9
9
|
import { ISdTsCompilerResult } from "../../types/ts-compiler.type";
|
|
10
|
-
import {
|
|
10
|
+
import { SdTsCompiler } from "../../ts-builder/SdTsCompiler";
|
|
11
11
|
|
|
12
12
|
export function createSdNgPlugin(conf: {
|
|
13
13
|
pkgPath: TNormPath;
|
|
@@ -25,8 +25,8 @@ export function createSdNgPlugin(conf: {
|
|
|
25
25
|
|
|
26
26
|
return {
|
|
27
27
|
name: "sd-ng-compile",
|
|
28
|
-
setup:
|
|
29
|
-
const tsCompiler =
|
|
28
|
+
setup: (build: esbuild.PluginBuild) => {
|
|
29
|
+
const tsCompiler = new SdTsCompiler({
|
|
30
30
|
pkgPath: conf.pkgPath,
|
|
31
31
|
additionalOptions: { declaration: false },
|
|
32
32
|
isDevMode: conf.dev,
|
|
@@ -6,7 +6,7 @@ export class SdCliIndexFileGenerator {
|
|
|
6
6
|
const indexFilePath = path.resolve(pkgPath, "src/index.ts");
|
|
7
7
|
let cache = FsUtil.exists(indexFilePath) ? FsUtil.readFile(indexFilePath) : undefined;
|
|
8
8
|
|
|
9
|
-
SdFsWatcher.watch([path.resolve(pkgPath, "src")]).onChange({ delay:
|
|
9
|
+
SdFsWatcher.watch([path.resolve(pkgPath, "src")]).onChange({ delay: 50 }, () => {
|
|
10
10
|
cache = this.run(pkgPath, polyfills, cache);
|
|
11
11
|
});
|
|
12
12
|
|
|
@@ -71,7 +71,7 @@ export class SdJsLibBuildRunner extends EventEmitter {
|
|
|
71
71
|
};
|
|
72
72
|
this.emit("complete", res);
|
|
73
73
|
|
|
74
|
-
SdFsWatcher.watch([srcGlobPath]).onChange({ delay:
|
|
74
|
+
SdFsWatcher.watch([srcGlobPath]).onChange({ delay: 100 }, async (changeInfos) => {
|
|
75
75
|
const watchFilePaths = changeInfos.filter((item) => FsUtil.exists(item.path)).map((item) => item.path);
|
|
76
76
|
if (watchFilePaths.length < 1) return;
|
|
77
77
|
|