@4399ywkf/core 5.0.18 → 5.0.20
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/cli/index.js +550 -640
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +3 -3
- package/dist/config/index.js +8 -13
- package/dist/config/index.js.map +1 -1
- package/dist/index.d.ts +249 -184
- package/dist/index.js +2229 -2174
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.d.ts +3 -3
- package/dist/plugin/index.js +10 -28
- package/dist/plugin/index.js.map +1 -1
- package/dist/router/index.js +34 -61
- package/dist/router/index.js.map +1 -1
- package/dist/rspack/index.d.ts +2 -2
- package/dist/rspack/index.js +99 -155
- package/dist/rspack/index.js.map +1 -1
- package/dist/runtime/index.d.ts +57 -57
- package/dist/runtime/index.js +11 -15
- package/dist/runtime/index.js.map +1 -1
- package/dist/{schema-VPH72NAR.d.ts → schema-CGQSqjRr.d.ts} +12 -12
- package/dist/{types-BztKUufh.d.ts → types-DbUq-VY8.d.ts} +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import { Command } from "commander";
|
|
5
|
-
import chalk4 from "chalk";
|
|
6
4
|
import { createRequire as createRequire4 } from "module";
|
|
7
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
8
5
|
import { dirname as dirname3, join as join7 } from "path";
|
|
6
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7
|
+
import chalk4 from "chalk";
|
|
8
|
+
import { Command } from "commander";
|
|
9
9
|
|
|
10
|
-
// src/cli/
|
|
10
|
+
// src/cli/build.ts
|
|
11
11
|
import { rspack as rspack3 } from "@rspack/core";
|
|
12
|
-
import { RspackDevServer } from "@rspack/dev-server";
|
|
13
12
|
import chalk2 from "chalk";
|
|
14
13
|
|
|
15
14
|
// src/config/loader.ts
|
|
16
15
|
import { existsSync } from "fs";
|
|
17
|
-
import {
|
|
16
|
+
import { extname, resolve } from "path";
|
|
18
17
|
import { pathToFileURL } from "url";
|
|
19
18
|
import deepmerge from "deepmerge";
|
|
20
19
|
|
|
@@ -78,12 +77,7 @@ var defaultConfig = {
|
|
|
78
77
|
};
|
|
79
78
|
|
|
80
79
|
// src/config/loader.ts
|
|
81
|
-
var CONFIG_FILES = [
|
|
82
|
-
"ywkf.config.ts",
|
|
83
|
-
"ywkf.config.mts",
|
|
84
|
-
"ywkf.config.js",
|
|
85
|
-
"ywkf.config.mjs"
|
|
86
|
-
];
|
|
80
|
+
var CONFIG_FILES = ["ywkf.config.ts", "ywkf.config.mts", "ywkf.config.js", "ywkf.config.mjs"];
|
|
87
81
|
function findConfigFile(cwd) {
|
|
88
82
|
for (const file of CONFIG_FILES) {
|
|
89
83
|
const configPath = resolve(cwd, file);
|
|
@@ -121,9 +115,7 @@ function mergeConfig(userConfig, baseConfig = defaultConfig) {
|
|
|
121
115
|
async function resolveConfig(cwd) {
|
|
122
116
|
const configPath = findConfigFile(cwd);
|
|
123
117
|
if (!configPath) {
|
|
124
|
-
console.warn(
|
|
125
|
-
"\u26A0\uFE0F \u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (ywkf.config.ts)\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E"
|
|
126
|
-
);
|
|
118
|
+
console.warn("\u26A0\uFE0F \u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (ywkf.config.ts)\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E");
|
|
127
119
|
return {
|
|
128
120
|
config: defaultConfig,
|
|
129
121
|
configPath: null
|
|
@@ -145,36 +137,257 @@ function createPathResolver(cwd) {
|
|
|
145
137
|
};
|
|
146
138
|
}
|
|
147
139
|
|
|
140
|
+
// src/plugin/manager.ts
|
|
141
|
+
function createLogger(pluginName) {
|
|
142
|
+
const prefix = `[${pluginName}]`;
|
|
143
|
+
const verbose = !!process.env.DEBUG;
|
|
144
|
+
return {
|
|
145
|
+
info: (msg) => {
|
|
146
|
+
if (verbose) console.log(`${prefix} ${msg}`);
|
|
147
|
+
},
|
|
148
|
+
warn: (msg) => console.warn(`${prefix} ${msg}`),
|
|
149
|
+
error: (msg) => console.error(`${prefix} ${msg}`),
|
|
150
|
+
debug: (msg) => {
|
|
151
|
+
if (verbose) console.debug(`${prefix} ${msg}`);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
async function resolvePlugin(pluginConfig, _cwd) {
|
|
156
|
+
let plugin;
|
|
157
|
+
let options = {};
|
|
158
|
+
if (typeof pluginConfig === "string") {
|
|
159
|
+
const module = await import(pluginConfig);
|
|
160
|
+
plugin = module.default || module;
|
|
161
|
+
} else if (Array.isArray(pluginConfig)) {
|
|
162
|
+
const [pluginOrName, pluginOptions] = pluginConfig;
|
|
163
|
+
options = pluginOptions;
|
|
164
|
+
if (typeof pluginOrName === "string") {
|
|
165
|
+
const module = await import(pluginOrName);
|
|
166
|
+
plugin = module.default || module;
|
|
167
|
+
} else {
|
|
168
|
+
plugin = pluginOrName;
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
plugin = pluginConfig;
|
|
172
|
+
}
|
|
173
|
+
if (typeof plugin === "function") {
|
|
174
|
+
plugin = plugin(options);
|
|
175
|
+
}
|
|
176
|
+
return { plugin, options };
|
|
177
|
+
}
|
|
178
|
+
var PluginManager = class {
|
|
179
|
+
plugins = /* @__PURE__ */ new Map();
|
|
180
|
+
context;
|
|
181
|
+
constructor(config, cwd, isDev) {
|
|
182
|
+
this.context = {
|
|
183
|
+
cwd,
|
|
184
|
+
isDev,
|
|
185
|
+
isProd: !isDev,
|
|
186
|
+
config,
|
|
187
|
+
logger: createLogger("PluginManager")
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 加载并初始化所有插件
|
|
192
|
+
*/
|
|
193
|
+
async loadPlugins(pluginConfigs) {
|
|
194
|
+
for (const pluginConfig of pluginConfigs) {
|
|
195
|
+
try {
|
|
196
|
+
const { plugin } = await resolvePlugin(pluginConfig, this.context.cwd);
|
|
197
|
+
if (this.plugins.has(plugin.name)) {
|
|
198
|
+
this.context.logger.warn(`\u63D2\u4EF6 ${plugin.name} \u5DF2\u52A0\u8F7D\uFF0C\u8DF3\u8FC7\u91CD\u590D\u52A0\u8F7D`);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const pluginContext = {
|
|
202
|
+
...this.context,
|
|
203
|
+
logger: createLogger(plugin.name)
|
|
204
|
+
};
|
|
205
|
+
const hooks = await plugin.setup(pluginContext);
|
|
206
|
+
this.plugins.set(plugin.name, { plugin, hooks });
|
|
207
|
+
this.context.logger.info(`\u5DF2\u52A0\u8F7D\u63D2\u4EF6: ${plugin.name}`);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
this.context.logger.error(`\u52A0\u8F7D\u63D2\u4EF6\u5931\u8D25: ${String(pluginConfig)} - ${error}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* 执行 modifyRspackConfig 钩子
|
|
215
|
+
*/
|
|
216
|
+
async applyRspackConfigHooks(config) {
|
|
217
|
+
let result = config;
|
|
218
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
219
|
+
if (hooks.modifyRspackConfig) {
|
|
220
|
+
try {
|
|
221
|
+
const modified = await hooks.modifyRspackConfig(result, this.context);
|
|
222
|
+
if (modified) {
|
|
223
|
+
result = modified;
|
|
224
|
+
}
|
|
225
|
+
} catch (error) {
|
|
226
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} modifyRspackConfig \u6267\u884C\u5931\u8D25: ${error}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* 执行 modifyRoutes 钩子
|
|
234
|
+
*/
|
|
235
|
+
async applyRoutesHooks(routes) {
|
|
236
|
+
let result = routes;
|
|
237
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
238
|
+
if (hooks.modifyRoutes) {
|
|
239
|
+
try {
|
|
240
|
+
const modified = await hooks.modifyRoutes(result, this.context);
|
|
241
|
+
if (modified) {
|
|
242
|
+
result = modified;
|
|
243
|
+
}
|
|
244
|
+
} catch (error) {
|
|
245
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} modifyRoutes \u6267\u884C\u5931\u8D25: ${error}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 执行 modifyAppConfig 钩子
|
|
253
|
+
*/
|
|
254
|
+
applyAppConfigHooks(appConfig) {
|
|
255
|
+
let result = appConfig;
|
|
256
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
257
|
+
if (hooks.modifyAppConfig) {
|
|
258
|
+
try {
|
|
259
|
+
const modified = hooks.modifyAppConfig(result, this.context);
|
|
260
|
+
if (modified) {
|
|
261
|
+
result = modified;
|
|
262
|
+
}
|
|
263
|
+
} catch (error) {
|
|
264
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} modifyAppConfig \u6267\u884C\u5931\u8D25: ${error}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return result;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* 收集所有插件的 Provider
|
|
272
|
+
*/
|
|
273
|
+
collectProviders() {
|
|
274
|
+
const providers = [];
|
|
275
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
276
|
+
if (hooks.addProvider) {
|
|
277
|
+
try {
|
|
278
|
+
const result = hooks.addProvider(this.context);
|
|
279
|
+
if (Array.isArray(result)) {
|
|
280
|
+
providers.push(...result);
|
|
281
|
+
} else if (result) {
|
|
282
|
+
providers.push(result);
|
|
283
|
+
}
|
|
284
|
+
} catch (error) {
|
|
285
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} addProvider \u6267\u884C\u5931\u8D25: ${error}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return providers;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* 执行 beforeBuild 钩子
|
|
293
|
+
*/
|
|
294
|
+
async runBeforeBuild() {
|
|
295
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
296
|
+
if (hooks.beforeBuild) {
|
|
297
|
+
try {
|
|
298
|
+
await hooks.beforeBuild(this.context);
|
|
299
|
+
} catch (error) {
|
|
300
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} beforeBuild \u6267\u884C\u5931\u8D25: ${error}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* 执行 afterBuild 钩子
|
|
307
|
+
*/
|
|
308
|
+
async runAfterBuild(stats) {
|
|
309
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
310
|
+
if (hooks.afterBuild) {
|
|
311
|
+
try {
|
|
312
|
+
await hooks.afterBuild(this.context, stats);
|
|
313
|
+
} catch (error) {
|
|
314
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} afterBuild \u6267\u884C\u5931\u8D25: ${error}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* 执行 beforeDevServer 钩子
|
|
321
|
+
*/
|
|
322
|
+
async runBeforeDevServer() {
|
|
323
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
324
|
+
if (hooks.beforeDevServer) {
|
|
325
|
+
try {
|
|
326
|
+
await hooks.beforeDevServer(this.context);
|
|
327
|
+
} catch (error) {
|
|
328
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} beforeDevServer \u6267\u884C\u5931\u8D25: ${error}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* 执行 afterDevServer 钩子
|
|
335
|
+
*/
|
|
336
|
+
async runAfterDevServer(server) {
|
|
337
|
+
for (const [name, { hooks }] of this.plugins) {
|
|
338
|
+
if (hooks.afterDevServer) {
|
|
339
|
+
try {
|
|
340
|
+
await hooks.afterDevServer(this.context, server);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
this.context.logger.error(`\u63D2\u4EF6 ${name} afterDevServer \u6267\u884C\u5931\u8D25: ${error}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* 获取所有已加载的插件名称
|
|
349
|
+
*/
|
|
350
|
+
getPluginNames() {
|
|
351
|
+
return Array.from(this.plugins.keys());
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* 获取所有已加载的插件
|
|
355
|
+
*/
|
|
356
|
+
getPlugins() {
|
|
357
|
+
return Array.from(this.plugins.values()).map((p) => p.plugin);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* 获取所有已加载的插件钩子
|
|
361
|
+
*/
|
|
362
|
+
getPluginHooks() {
|
|
363
|
+
return Array.from(this.plugins.values()).map((p) => p.hooks);
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
148
367
|
// src/rspack/index.ts
|
|
149
368
|
import { RsdoctorRspackPlugin } from "@rsdoctor/rspack-plugin";
|
|
150
369
|
|
|
151
370
|
// src/rspack/dev.ts
|
|
371
|
+
import { createRequire as createRequire2 } from "module";
|
|
152
372
|
import ReactRefreshPlugin from "@rspack/plugin-react-refresh";
|
|
153
373
|
import { merge } from "webpack-merge";
|
|
154
|
-
import { createRequire as createRequire2 } from "module";
|
|
155
374
|
|
|
156
375
|
// src/rspack/base.ts
|
|
157
|
-
import { rspack } from "@rspack/core";
|
|
158
376
|
import { createRequire } from "module";
|
|
159
|
-
import { fileURLToPath } from "url";
|
|
160
377
|
import { dirname, join as join5 } from "path";
|
|
378
|
+
import { fileURLToPath } from "url";
|
|
379
|
+
import { rspack } from "@rspack/core";
|
|
161
380
|
|
|
162
381
|
// src/generator/plugin.ts
|
|
163
|
-
import {
|
|
382
|
+
import { existsSync as existsSync5, watch } from "fs";
|
|
164
383
|
import { join as join4 } from "path";
|
|
165
384
|
|
|
166
385
|
// src/generator/generator.ts
|
|
167
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync2,
|
|
386
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
168
387
|
import { join as join3 } from "path";
|
|
169
388
|
|
|
170
389
|
// src/router/generator.ts
|
|
171
|
-
import {
|
|
172
|
-
existsSync as existsSync2,
|
|
173
|
-
readdirSync,
|
|
174
|
-
statSync,
|
|
175
|
-
mkdirSync,
|
|
176
|
-
writeFileSync
|
|
177
|
-
} from "fs";
|
|
390
|
+
import { existsSync as existsSync2, mkdirSync, readdirSync, statSync, writeFileSync } from "fs";
|
|
178
391
|
import { join, relative } from "path";
|
|
179
392
|
function winPath(path) {
|
|
180
393
|
const isExtendedLengthPath = /^\\\\\?\\/.test(path);
|
|
@@ -234,9 +447,7 @@ var ConventionalRouteGenerator = class {
|
|
|
234
447
|
const subDirPath = join(dir, subDir);
|
|
235
448
|
if (subDir.startsWith("__")) {
|
|
236
449
|
const pathlessRoutes = this.scanDirectory(subDirPath, routePath);
|
|
237
|
-
const pathlessLayout = readdirSync(subDirPath).find(
|
|
238
|
-
(e) => CONVENTION_FILES.layout.test(e)
|
|
239
|
-
);
|
|
450
|
+
const pathlessLayout = readdirSync(subDirPath).find((e) => CONVENTION_FILES.layout.test(e));
|
|
240
451
|
if (pathlessLayout) {
|
|
241
452
|
const pathlessChildren = this.scanDirectory(subDirPath, routePath);
|
|
242
453
|
const pathlessLayoutRel = winPath(
|
|
@@ -248,9 +459,7 @@ var ConventionalRouteGenerator = class {
|
|
|
248
459
|
layoutFile: pathlessLayoutRel,
|
|
249
460
|
isLayout: true,
|
|
250
461
|
pathless: true,
|
|
251
|
-
children: pathlessChildren.filter(
|
|
252
|
-
(r) => r.layoutFile !== pathlessLayoutRel
|
|
253
|
-
)
|
|
462
|
+
children: pathlessChildren.filter((r) => r.layoutFile !== pathlessLayoutRel)
|
|
254
463
|
});
|
|
255
464
|
} else {
|
|
256
465
|
childRoutes.push(...pathlessRoutes);
|
|
@@ -268,7 +477,7 @@ var ConventionalRouteGenerator = class {
|
|
|
268
477
|
layoutChildren.push({
|
|
269
478
|
path: routePath,
|
|
270
479
|
file: relPath(pageFile),
|
|
271
|
-
name: routeName
|
|
480
|
+
name: `${routeName}Index`,
|
|
272
481
|
index: true
|
|
273
482
|
});
|
|
274
483
|
}
|
|
@@ -276,7 +485,7 @@ var ConventionalRouteGenerator = class {
|
|
|
276
485
|
layoutChildren.push({
|
|
277
486
|
path: "*",
|
|
278
487
|
file: relPath(catchAllFile),
|
|
279
|
-
name: routeName
|
|
488
|
+
name: `${routeName}CatchAll`
|
|
280
489
|
});
|
|
281
490
|
}
|
|
282
491
|
layoutChildren.push(...childRoutes);
|
|
@@ -305,7 +514,7 @@ var ConventionalRouteGenerator = class {
|
|
|
305
514
|
result.push({
|
|
306
515
|
path: "*",
|
|
307
516
|
file: relPath(catchAllFile),
|
|
308
|
-
name: routeName
|
|
517
|
+
name: `${routeName}CatchAll`
|
|
309
518
|
});
|
|
310
519
|
}
|
|
311
520
|
result.push(...childRoutes);
|
|
@@ -340,15 +549,13 @@ var ConventionalRouteGenerator = class {
|
|
|
340
549
|
* 生成有效的 JS 标识符名称
|
|
341
550
|
*/
|
|
342
551
|
generateRouteName(path) {
|
|
343
|
-
const name = path.split("/").filter(Boolean).map(
|
|
344
|
-
(s) => s.replace(/^:/, "Param").replace(/\?$/, "Optional").replace(/^\*$/, "CatchAll")
|
|
345
|
-
).map((s) => {
|
|
552
|
+
const name = path.split("/").filter(Boolean).map((s) => s.replace(/^:/, "Param").replace(/\?$/, "Optional").replace(/^\*$/, "CatchAll")).map((s) => {
|
|
346
553
|
const cleaned = s.replace(/[^a-zA-Z0-9]/g, "");
|
|
347
554
|
if (!cleaned) return "";
|
|
348
555
|
return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);
|
|
349
556
|
}).join("");
|
|
350
557
|
if (!name || /^\d/.test(name)) {
|
|
351
|
-
return
|
|
558
|
+
return `Page${name || "Root"}`;
|
|
352
559
|
}
|
|
353
560
|
return name;
|
|
354
561
|
}
|
|
@@ -367,8 +574,12 @@ import { createBrowserRouter, type RouteObject } from "react-router";
|
|
|
367
574
|
|
|
368
575
|
// \u61D2\u52A0\u8F7D\u9875\u9762\u7EC4\u4EF6
|
|
369
576
|
${lazyImports.join("\n")}
|
|
370
|
-
${errorImports.length > 0 ?
|
|
371
|
-
|
|
577
|
+
${errorImports.length > 0 ? `
|
|
578
|
+
// \u9519\u8BEF\u8FB9\u754C\u7EC4\u4EF6
|
|
579
|
+
${errorImports.join("\n")}` : ""}
|
|
580
|
+
${loadingImports.length > 0 ? `
|
|
581
|
+
// \u52A0\u8F7D\u72B6\u6001\u7EC4\u4EF6
|
|
582
|
+
${loadingImports.join("\n")}` : ""}
|
|
372
583
|
|
|
373
584
|
// \u9ED8\u8BA4\u52A0\u8F7D\u72B6\u6001
|
|
374
585
|
const DefaultLoading = () => <div style={{ padding: 24, textAlign: "center" }}>\u52A0\u8F7D\u4E2D...</div>;
|
|
@@ -407,23 +618,17 @@ export default routes;
|
|
|
407
618
|
const toImportPath = (f) => f.replace(/\.(tsx?|jsx?)$/, "");
|
|
408
619
|
if (route.isLayout && route.layoutFile) {
|
|
409
620
|
lazyImports.push(
|
|
410
|
-
`const ${name}Layout = lazy(() => import("@/pages/${toImportPath(
|
|
411
|
-
route.layoutFile
|
|
412
|
-
)}"));`
|
|
621
|
+
`const ${name}Layout = lazy(() => import("@/pages/${toImportPath(route.layoutFile)}"));`
|
|
413
622
|
);
|
|
414
623
|
}
|
|
415
624
|
if (route.file) {
|
|
416
625
|
lazyImports.push(
|
|
417
|
-
`const ${name}Page = lazy(() => import("@/pages/${toImportPath(
|
|
418
|
-
route.file
|
|
419
|
-
)}"));`
|
|
626
|
+
`const ${name}Page = lazy(() => import("@/pages/${toImportPath(route.file)}"));`
|
|
420
627
|
);
|
|
421
628
|
}
|
|
422
629
|
if (route.errorFile) {
|
|
423
630
|
errorImports.push(
|
|
424
|
-
`const ${name}Error = lazy(() => import("@/pages/${toImportPath(
|
|
425
|
-
route.errorFile
|
|
426
|
-
)}"));`
|
|
631
|
+
`const ${name}Error = lazy(() => import("@/pages/${toImportPath(route.errorFile)}"));`
|
|
427
632
|
);
|
|
428
633
|
}
|
|
429
634
|
if (route.loadingFile) {
|
|
@@ -434,12 +639,7 @@ export default routes;
|
|
|
434
639
|
);
|
|
435
640
|
}
|
|
436
641
|
if (route.children) {
|
|
437
|
-
this.collectImports(
|
|
438
|
-
route.children,
|
|
439
|
-
lazyImports,
|
|
440
|
-
errorImports,
|
|
441
|
-
loadingImports
|
|
442
|
-
);
|
|
642
|
+
this.collectImports(route.children, lazyImports, errorImports, loadingImports);
|
|
443
643
|
}
|
|
444
644
|
}
|
|
445
645
|
}
|
|
@@ -465,9 +665,7 @@ export default routes;
|
|
|
465
665
|
}
|
|
466
666
|
if (route.isLayout && route.layoutFile) {
|
|
467
667
|
const loadingProp = route.loadingFile ? ` Loading={${name}Loading}` : "";
|
|
468
|
-
parts.push(
|
|
469
|
-
`element: <LazyRoute Component={${name}Layout}${loadingProp} />`
|
|
470
|
-
);
|
|
668
|
+
parts.push(`element: <LazyRoute Component={${name}Layout}${loadingProp} />`);
|
|
471
669
|
} else if (route.file) {
|
|
472
670
|
parts.push(`element: <LazyRoute Component={${name}Page} />`);
|
|
473
671
|
}
|
|
@@ -476,9 +674,7 @@ export default routes;
|
|
|
476
674
|
}
|
|
477
675
|
if (route.children && route.children.length > 0) {
|
|
478
676
|
const childParent = route.pathless ? parentPath : route.path;
|
|
479
|
-
parts.push(
|
|
480
|
-
`children: ${this.emitRouteArray(route.children, childParent)}`
|
|
481
|
-
);
|
|
677
|
+
parts.push(`children: ${this.emitRouteArray(route.children, childParent)}`);
|
|
482
678
|
}
|
|
483
679
|
return `{
|
|
484
680
|
${parts.join(",\n ")}
|
|
@@ -498,53 +694,13 @@ export default routes;
|
|
|
498
694
|
}
|
|
499
695
|
};
|
|
500
696
|
|
|
501
|
-
// src/generator/templates/
|
|
502
|
-
function
|
|
697
|
+
// src/generator/templates/bootstrap.ts
|
|
698
|
+
function generateBootstrap(config, injections = {}) {
|
|
699
|
+
const { appName, router } = config;
|
|
700
|
+
const routerImport = router.conventional ? `import { createRouter } from "./routes";` : `import { createRouter } from "@/routes";`;
|
|
503
701
|
const imports = [
|
|
504
|
-
`import "
|
|
505
|
-
|
|
506
|
-
...injections.imports || []
|
|
507
|
-
];
|
|
508
|
-
const topLevel = injections.topLevel || [];
|
|
509
|
-
const exports = injections.exports || [];
|
|
510
|
-
const hasPluginExports = exports.length > 0;
|
|
511
|
-
const hasAsyncTopLevel = topLevel.some((line) => line.includes("await "));
|
|
512
|
-
let startupBody;
|
|
513
|
-
if (hasPluginExports) {
|
|
514
|
-
startupBody = [
|
|
515
|
-
...topLevel,
|
|
516
|
-
...exports,
|
|
517
|
-
``,
|
|
518
|
-
`if (shouldRunIndependently !== false) {`,
|
|
519
|
-
` runApp();`,
|
|
520
|
-
`}`
|
|
521
|
-
].join("\n");
|
|
522
|
-
} else if (hasAsyncTopLevel) {
|
|
523
|
-
startupBody = [
|
|
524
|
-
`(async () => {`,
|
|
525
|
-
...topLevel.map((l) => ` ${l}`),
|
|
526
|
-
` await runApp();`,
|
|
527
|
-
`})();`
|
|
528
|
-
].join("\n");
|
|
529
|
-
} else {
|
|
530
|
-
startupBody = topLevel.length > 0 ? [...topLevel, `runApp();`].join("\n") : `runApp();`;
|
|
531
|
-
}
|
|
532
|
-
return `// \u6B64\u6587\u4EF6\u7531 @4399ywkf/core \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u4FEE\u6539
|
|
533
|
-
// Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
534
|
-
|
|
535
|
-
${imports.join("\n")}
|
|
536
|
-
|
|
537
|
-
${startupBody}
|
|
538
|
-
`;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
// src/generator/templates/bootstrap.ts
|
|
542
|
-
function generateBootstrap(config, injections = {}) {
|
|
543
|
-
const { appName, router } = config;
|
|
544
|
-
const routerImport = router.conventional ? `import { createRouter } from "./routes";` : `import { createRouter } from "@/routes";`;
|
|
545
|
-
const imports = [
|
|
546
|
-
`import { bootstrap, type AppConfig } from "@4399ywkf/core/runtime";`,
|
|
547
|
-
routerImport,
|
|
702
|
+
`import { bootstrap, type AppConfig } from "@4399ywkf/core/runtime";`,
|
|
703
|
+
routerImport,
|
|
548
704
|
...injections.imports || []
|
|
549
705
|
];
|
|
550
706
|
const topLevel = injections.topLevel || [];
|
|
@@ -626,8 +782,50 @@ export async function runApp(): Promise<void> {
|
|
|
626
782
|
const userConfig = await getUserConfig();
|
|
627
783
|
await bootstrap(createAppConfig(userConfig));
|
|
628
784
|
}
|
|
629
|
-
${topLevel.length > 0 ?
|
|
630
|
-
${
|
|
785
|
+
${topLevel.length > 0 ? `
|
|
786
|
+
${topLevel.join("\n")}` : ""}
|
|
787
|
+
${exports.length > 0 ? `
|
|
788
|
+
${exports.join("\n")}` : ""}
|
|
789
|
+
`;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// src/generator/templates/entry.ts
|
|
793
|
+
function generateEntry(_config, injections = {}) {
|
|
794
|
+
const imports = [
|
|
795
|
+
`import "@/index.css";`,
|
|
796
|
+
`import { runApp } from "./bootstrap";`,
|
|
797
|
+
...injections.imports || []
|
|
798
|
+
];
|
|
799
|
+
const topLevel = injections.topLevel || [];
|
|
800
|
+
const exports = injections.exports || [];
|
|
801
|
+
const hasPluginExports = exports.length > 0;
|
|
802
|
+
const hasAsyncTopLevel = topLevel.some((line) => line.includes("await "));
|
|
803
|
+
let startupBody;
|
|
804
|
+
if (hasPluginExports) {
|
|
805
|
+
startupBody = [
|
|
806
|
+
...topLevel,
|
|
807
|
+
...exports,
|
|
808
|
+
``,
|
|
809
|
+
`if (shouldRunIndependently !== false) {`,
|
|
810
|
+
` runApp();`,
|
|
811
|
+
`}`
|
|
812
|
+
].join("\n");
|
|
813
|
+
} else if (hasAsyncTopLevel) {
|
|
814
|
+
startupBody = [
|
|
815
|
+
`(async () => {`,
|
|
816
|
+
...topLevel.map((l) => ` ${l}`),
|
|
817
|
+
` await runApp();`,
|
|
818
|
+
`})();`
|
|
819
|
+
].join("\n");
|
|
820
|
+
} else {
|
|
821
|
+
startupBody = topLevel.length > 0 ? [...topLevel, `runApp();`].join("\n") : `runApp();`;
|
|
822
|
+
}
|
|
823
|
+
return `// \u6B64\u6587\u4EF6\u7531 @4399ywkf/core \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u4FEE\u6539
|
|
824
|
+
// Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
825
|
+
|
|
826
|
+
${imports.join("\n")}
|
|
827
|
+
|
|
828
|
+
${startupBody}
|
|
631
829
|
`;
|
|
632
830
|
}
|
|
633
831
|
|
|
@@ -791,17 +989,14 @@ var YwkfGenerator = class {
|
|
|
791
989
|
const { outputDir, config } = this.context;
|
|
792
990
|
const configPath = join3(outputDir, "config.json");
|
|
793
991
|
const serializableConfig = JSON.parse(
|
|
794
|
-
JSON.stringify(config, (
|
|
992
|
+
JSON.stringify(config, (_key, value) => {
|
|
795
993
|
if (typeof value === "function") {
|
|
796
994
|
return "[Function]";
|
|
797
995
|
}
|
|
798
996
|
return value;
|
|
799
997
|
})
|
|
800
998
|
);
|
|
801
|
-
this.writeFileIfChanged(
|
|
802
|
-
configPath,
|
|
803
|
-
JSON.stringify(serializableConfig, null, 2)
|
|
804
|
-
);
|
|
999
|
+
this.writeFileIfChanged(configPath, JSON.stringify(serializableConfig, null, 2));
|
|
805
1000
|
}
|
|
806
1001
|
/**
|
|
807
1002
|
* 生成约定式路由
|
|
@@ -905,16 +1100,10 @@ var YwkfGenerator = class {
|
|
|
905
1100
|
generateTypes() {
|
|
906
1101
|
const { outputDir, config, cwd } = this.context;
|
|
907
1102
|
const envTypesContent = generateEnvTypes(cwd, config);
|
|
908
|
-
this.writeFileIfChanged(
|
|
909
|
-
join3(outputDir, "types", "env.d.ts"),
|
|
910
|
-
envTypesContent
|
|
911
|
-
);
|
|
1103
|
+
this.writeFileIfChanged(join3(outputDir, "types", "env.d.ts"), envTypesContent);
|
|
912
1104
|
if (config.router.conventional) {
|
|
913
1105
|
const routeTypesContent = generateRouteTypes();
|
|
914
|
-
this.writeFileIfChanged(
|
|
915
|
-
join3(outputDir, "types", "routes.d.ts"),
|
|
916
|
-
routeTypesContent
|
|
917
|
-
);
|
|
1106
|
+
this.writeFileIfChanged(join3(outputDir, "types", "routes.d.ts"), routeTypesContent);
|
|
918
1107
|
}
|
|
919
1108
|
}
|
|
920
1109
|
/**
|
|
@@ -1049,7 +1238,7 @@ var YwkfGeneratorPlugin = class {
|
|
|
1049
1238
|
}
|
|
1050
1239
|
apply(compiler) {
|
|
1051
1240
|
const pluginName = "YwkfGeneratorPlugin";
|
|
1052
|
-
compiler.hooks.beforeCompile.tapAsync(pluginName, async (
|
|
1241
|
+
compiler.hooks.beforeCompile.tapAsync(pluginName, async (_params, callback) => {
|
|
1053
1242
|
try {
|
|
1054
1243
|
await this.initialize();
|
|
1055
1244
|
if (!this.hasGenerated && this.generator) {
|
|
@@ -1077,24 +1266,20 @@ var YwkfGeneratorPlugin = class {
|
|
|
1077
1266
|
}
|
|
1078
1267
|
this.isWatching = true;
|
|
1079
1268
|
let debounceTimer = null;
|
|
1080
|
-
const watcher = watch(
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
(eventType, filename) => {
|
|
1084
|
-
if (!filename?.match(/\.(tsx?|jsx?)$/)) {
|
|
1085
|
-
return;
|
|
1086
|
-
}
|
|
1087
|
-
if (debounceTimer) {
|
|
1088
|
-
clearTimeout(debounceTimer);
|
|
1089
|
-
}
|
|
1090
|
-
debounceTimer = setTimeout(async () => {
|
|
1091
|
-
if (process.env.DEBUG) console.log(`[ywkf] \u68C0\u6D4B\u5230\u9875\u9762\u53D8\u5316: ${filename}`);
|
|
1092
|
-
if (this.generator) {
|
|
1093
|
-
await this.generator.generate();
|
|
1094
|
-
}
|
|
1095
|
-
}, 500);
|
|
1269
|
+
const watcher = watch(pagesDir, { recursive: true }, (_eventType, filename) => {
|
|
1270
|
+
if (!filename?.match(/\.(tsx?|jsx?)$/)) {
|
|
1271
|
+
return;
|
|
1096
1272
|
}
|
|
1097
|
-
|
|
1273
|
+
if (debounceTimer) {
|
|
1274
|
+
clearTimeout(debounceTimer);
|
|
1275
|
+
}
|
|
1276
|
+
debounceTimer = setTimeout(async () => {
|
|
1277
|
+
if (process.env.DEBUG) console.log(`[ywkf] \u68C0\u6D4B\u5230\u9875\u9762\u53D8\u5316: ${filename}`);
|
|
1278
|
+
if (this.generator) {
|
|
1279
|
+
await this.generator.generate();
|
|
1280
|
+
}
|
|
1281
|
+
}, 500);
|
|
1282
|
+
});
|
|
1098
1283
|
process.on("exit", () => {
|
|
1099
1284
|
watcher.close();
|
|
1100
1285
|
});
|
|
@@ -1125,8 +1310,10 @@ var YwkfGeneratorPlugin = class {
|
|
|
1125
1310
|
this.resetState();
|
|
1126
1311
|
await this.initialize();
|
|
1127
1312
|
await this.regenerate();
|
|
1128
|
-
console.log(
|
|
1129
|
-
`
|
|
1313
|
+
console.log(
|
|
1314
|
+
` [ywkf] .ywkf \u76EE\u5F55\u5DF2\u91CD\u65B0\u751F\u6210\u3002\u90E8\u5206\u914D\u7F6E\u53D8\u66F4\uFF08\u5982\u7AEF\u53E3\u3001\u4EE3\u7406\uFF09\u9700\u91CD\u542F dev server \u751F\u6548\u3002
|
|
1315
|
+
`
|
|
1316
|
+
);
|
|
1130
1317
|
} catch (error) {
|
|
1131
1318
|
console.error(` [ywkf] \u914D\u7F6E\u91CD\u8F7D\u5931\u8D25:`, error);
|
|
1132
1319
|
}
|
|
@@ -1145,15 +1332,7 @@ var coreNodeModules = join5(__dirname, "../../node_modules");
|
|
|
1145
1332
|
function createBaseConfig(config, cwd, options = {}) {
|
|
1146
1333
|
const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
|
|
1147
1334
|
const { resolveApp } = createPathResolver(cwd);
|
|
1148
|
-
const {
|
|
1149
|
-
appName,
|
|
1150
|
-
appCName,
|
|
1151
|
-
output,
|
|
1152
|
-
html,
|
|
1153
|
-
alias: userAlias,
|
|
1154
|
-
microFrontend,
|
|
1155
|
-
router
|
|
1156
|
-
} = config;
|
|
1335
|
+
const { appName, appCName, output, html, alias: userAlias, microFrontend, router } = config;
|
|
1157
1336
|
const ywkfOutputDir = resolveApp(".ywkf");
|
|
1158
1337
|
const defaultAlias = {
|
|
1159
1338
|
"@": resolveApp("src"),
|
|
@@ -1329,7 +1508,7 @@ function createBaseConfig(config, cwd, options = {}) {
|
|
|
1329
1508
|
}
|
|
1330
1509
|
|
|
1331
1510
|
// src/rspack/dev.ts
|
|
1332
|
-
var
|
|
1511
|
+
var _require = createRequire2(import.meta.url);
|
|
1333
1512
|
function convertProxyToArray(proxy) {
|
|
1334
1513
|
if (!proxy || Object.keys(proxy).length === 0) {
|
|
1335
1514
|
return void 0;
|
|
@@ -1360,10 +1539,7 @@ function createDevConfig(config, cwd) {
|
|
|
1360
1539
|
// Less - antd
|
|
1361
1540
|
{
|
|
1362
1541
|
test: /\.less$/,
|
|
1363
|
-
include: [
|
|
1364
|
-
/[\\/]node_modules[\\/].*antd/,
|
|
1365
|
-
/[\\/]node_modules[\\/]@4399ywkf[\\/]design/
|
|
1366
|
-
],
|
|
1542
|
+
include: [/[\\/]node_modules[\\/].*antd/, /[\\/]node_modules[\\/]@4399ywkf[\\/]design/],
|
|
1367
1543
|
use: [
|
|
1368
1544
|
{ loader: "style-loader" },
|
|
1369
1545
|
{
|
|
@@ -1536,9 +1712,7 @@ function createDevConfig(config, cwd) {
|
|
|
1536
1712
|
clean: false
|
|
1537
1713
|
},
|
|
1538
1714
|
stats: "errors-only",
|
|
1539
|
-
plugins: [
|
|
1540
|
-
new ReactRefreshPlugin()
|
|
1541
|
-
],
|
|
1715
|
+
plugins: [new ReactRefreshPlugin()],
|
|
1542
1716
|
devServer: {
|
|
1543
1717
|
host: dev2.host,
|
|
1544
1718
|
port: dev2.port,
|
|
@@ -1569,10 +1743,7 @@ function createProdConfig(config, cwd) {
|
|
|
1569
1743
|
// Less - antd
|
|
1570
1744
|
{
|
|
1571
1745
|
test: /\.less$/,
|
|
1572
|
-
include: [
|
|
1573
|
-
/[\\/]node_modules[\\/].*antd/,
|
|
1574
|
-
/[\\/]node_modules[\\/]@4399ywkf[\\/]design/
|
|
1575
|
-
],
|
|
1746
|
+
include: [/[\\/]node_modules[\\/].*antd/, /[\\/]node_modules[\\/]@4399ywkf[\\/]design/],
|
|
1576
1747
|
use: [
|
|
1577
1748
|
{ loader: rspack2.CssExtractRspackPlugin.loader },
|
|
1578
1749
|
{
|
|
@@ -1788,10 +1959,7 @@ function createRspackConfig(config, cwd, options = {}) {
|
|
|
1788
1959
|
const isDev = options.isDev ?? process.env.NODE_ENV !== "production";
|
|
1789
1960
|
let rspackConfig = isDev ? createDevConfig(config, cwd) : createProdConfig(config, cwd);
|
|
1790
1961
|
if (config.performance.rsdoctor) {
|
|
1791
|
-
rspackConfig.plugins = [
|
|
1792
|
-
...rspackConfig.plugins || [],
|
|
1793
|
-
new RsdoctorRspackPlugin({})
|
|
1794
|
-
];
|
|
1962
|
+
rspackConfig.plugins = [...rspackConfig.plugins || [], new RsdoctorRspackPlugin({})];
|
|
1795
1963
|
}
|
|
1796
1964
|
if (config.tools.rspack) {
|
|
1797
1965
|
const userConfig = config.tools.rspack(rspackConfig, {
|
|
@@ -1823,10 +1991,7 @@ function preloadEnv(cwd, mode, nodeEnv) {
|
|
|
1823
1991
|
break;
|
|
1824
1992
|
}
|
|
1825
1993
|
}
|
|
1826
|
-
const modeEnvPaths = [
|
|
1827
|
-
resolve2(cwd, `config/env/.env.${mode}`),
|
|
1828
|
-
resolve2(cwd, `.env.${mode}`)
|
|
1829
|
-
];
|
|
1994
|
+
const modeEnvPaths = [resolve2(cwd, `config/env/.env.${mode}`), resolve2(cwd, `.env.${mode}`)];
|
|
1830
1995
|
for (const envPath of modeEnvPaths) {
|
|
1831
1996
|
if (existsSync6(envPath)) {
|
|
1832
1997
|
const envContent = readFileSync3(envPath, "utf-8");
|
|
@@ -1864,379 +2029,101 @@ function loadEnv(config, cwd, mode, nodeEnv) {
|
|
|
1864
2029
|
process.env.APP_PORT = process.env.APP_PORT || String(config.dev.port);
|
|
1865
2030
|
}
|
|
1866
2031
|
|
|
1867
|
-
// src/
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
2032
|
+
// src/cli/printer.ts
|
|
2033
|
+
import { createRequire as createRequire3 } from "module";
|
|
2034
|
+
import os from "os";
|
|
2035
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
2036
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2037
|
+
import chalk from "chalk";
|
|
2038
|
+
var __filename = fileURLToPath2(import.meta.url);
|
|
2039
|
+
var __dirname2 = dirname2(__filename);
|
|
2040
|
+
var require3 = createRequire3(import.meta.url);
|
|
2041
|
+
var _version = null;
|
|
2042
|
+
function getFrameworkVersion() {
|
|
2043
|
+
if (_version) return _version;
|
|
2044
|
+
try {
|
|
2045
|
+
const pkgPath = join6(__dirname2, "../../package.json");
|
|
2046
|
+
const pkg = require3(pkgPath);
|
|
2047
|
+
_version = pkg.version || "0.0.0";
|
|
2048
|
+
} catch {
|
|
2049
|
+
_version = "0.0.0";
|
|
2050
|
+
}
|
|
2051
|
+
return _version;
|
|
1881
2052
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
const
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
options = pluginOptions;
|
|
1891
|
-
if (typeof pluginOrName === "string") {
|
|
1892
|
-
const module = await import(pluginOrName);
|
|
1893
|
-
plugin = module.default || module;
|
|
1894
|
-
} else {
|
|
1895
|
-
plugin = pluginOrName;
|
|
2053
|
+
function getNetworkAddress(port) {
|
|
2054
|
+
const interfaces = os.networkInterfaces();
|
|
2055
|
+
for (const entries of Object.values(interfaces)) {
|
|
2056
|
+
if (!entries) continue;
|
|
2057
|
+
for (const entry of entries) {
|
|
2058
|
+
if (entry.family === "IPv4" && !entry.internal) {
|
|
2059
|
+
return `http://${entry.address}:${port}/`;
|
|
2060
|
+
}
|
|
1896
2061
|
}
|
|
1897
|
-
} else {
|
|
1898
|
-
plugin = pluginConfig;
|
|
1899
|
-
}
|
|
1900
|
-
if (typeof plugin === "function") {
|
|
1901
|
-
plugin = plugin(options);
|
|
1902
2062
|
}
|
|
1903
|
-
return
|
|
2063
|
+
return null;
|
|
1904
2064
|
}
|
|
1905
|
-
var
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
2065
|
+
var BAR_WIDTH = 30;
|
|
2066
|
+
function renderBar(percent) {
|
|
2067
|
+
const filled = Math.round(BAR_WIDTH * percent);
|
|
2068
|
+
const empty = BAR_WIDTH - filled;
|
|
2069
|
+
const bar = chalk.green("\u2501".repeat(filled)) + chalk.gray("\u2501".repeat(empty));
|
|
2070
|
+
return bar;
|
|
2071
|
+
}
|
|
2072
|
+
var DevPrinter = class {
|
|
2073
|
+
constructor(_host, port, pluginNames, isBuild = false) {
|
|
2074
|
+
this._host = _host;
|
|
2075
|
+
this.port = port;
|
|
2076
|
+
this.pluginNames = pluginNames;
|
|
2077
|
+
this.isBuild = isBuild;
|
|
1916
2078
|
}
|
|
2079
|
+
startTime = 0;
|
|
2080
|
+
lastProgressLine = "";
|
|
2081
|
+
firstCompileDone = false;
|
|
1917
2082
|
/**
|
|
1918
|
-
*
|
|
2083
|
+
* 打印框架 banner
|
|
1919
2084
|
*/
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
this.context.logger.warn(`\u63D2\u4EF6 ${plugin.name} \u5DF2\u52A0\u8F7D\uFF0C\u8DF3\u8FC7\u91CD\u590D\u52A0\u8F7D`);
|
|
1926
|
-
continue;
|
|
1927
|
-
}
|
|
1928
|
-
const pluginContext = {
|
|
1929
|
-
...this.context,
|
|
1930
|
-
logger: createLogger(plugin.name)
|
|
1931
|
-
};
|
|
1932
|
-
const hooks = await plugin.setup(pluginContext);
|
|
1933
|
-
this.plugins.set(plugin.name, { plugin, hooks });
|
|
1934
|
-
this.context.logger.info(`\u5DF2\u52A0\u8F7D\u63D2\u4EF6: ${plugin.name}`);
|
|
1935
|
-
} catch (error) {
|
|
1936
|
-
this.context.logger.error(
|
|
1937
|
-
`\u52A0\u8F7D\u63D2\u4EF6\u5931\u8D25: ${String(pluginConfig)} - ${error}`
|
|
1938
|
-
);
|
|
1939
|
-
}
|
|
1940
|
-
}
|
|
2085
|
+
printBanner() {
|
|
2086
|
+
const version2 = getFrameworkVersion();
|
|
2087
|
+
console.log();
|
|
2088
|
+
console.log(` ${chalk.bold.cyan("@4399ywkf/core")} ${chalk.green(`Framework v${version2}`)}`);
|
|
2089
|
+
console.log();
|
|
1941
2090
|
}
|
|
1942
2091
|
/**
|
|
1943
|
-
*
|
|
2092
|
+
* 打印 "start build started..."
|
|
1944
2093
|
*/
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
const modified = await hooks.modifyRspackConfig(result, this.context);
|
|
1951
|
-
if (modified) {
|
|
1952
|
-
result = modified;
|
|
1953
|
-
}
|
|
1954
|
-
} catch (error) {
|
|
1955
|
-
this.context.logger.error(
|
|
1956
|
-
`\u63D2\u4EF6 ${name} modifyRspackConfig \u6267\u884C\u5931\u8D25: ${error}`
|
|
1957
|
-
);
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
return result;
|
|
2094
|
+
printBuildStart() {
|
|
2095
|
+
this.startTime = Date.now();
|
|
2096
|
+
this.compileDone = false;
|
|
2097
|
+
const label = chalk.gray("start");
|
|
2098
|
+
console.log(` ${label} build started...`);
|
|
1962
2099
|
}
|
|
1963
2100
|
/**
|
|
1964
|
-
*
|
|
2101
|
+
* 更新编译进度条(原地覆写同一行)
|
|
1965
2102
|
*/
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
}
|
|
1975
|
-
} catch (error) {
|
|
1976
|
-
this.context.logger.error(
|
|
1977
|
-
`\u63D2\u4EF6 ${name} modifyRoutes \u6267\u884C\u5931\u8D25: ${error}`
|
|
1978
|
-
);
|
|
1979
|
-
}
|
|
2103
|
+
updateProgress(percent, message) {
|
|
2104
|
+
const pct = Math.min(Math.round(percent * 100), 100);
|
|
2105
|
+
const bar = renderBar(percent);
|
|
2106
|
+
const status = message || "compiling";
|
|
2107
|
+
const line = ` ${chalk.yellow("\u25CF")} client ${bar} ${chalk.bold(`(${pct}%)`)} ${chalk.gray(status)}`;
|
|
2108
|
+
if (process.stdout.isTTY) {
|
|
2109
|
+
if (this.lastProgressLine) {
|
|
2110
|
+
process.stdout.write("\x1B[1A\x1B[2K");
|
|
1980
2111
|
}
|
|
2112
|
+
process.stdout.write(`${line}
|
|
2113
|
+
`);
|
|
2114
|
+
} else if (!this.firstCompileDone && pct === 100) {
|
|
2115
|
+
console.log(line);
|
|
1981
2116
|
}
|
|
1982
|
-
|
|
2117
|
+
this.lastProgressLine = line;
|
|
1983
2118
|
}
|
|
1984
2119
|
/**
|
|
1985
|
-
*
|
|
1986
|
-
*/
|
|
1987
|
-
applyAppConfigHooks(appConfig) {
|
|
1988
|
-
let result = appConfig;
|
|
1989
|
-
for (const [name, { hooks }] of this.plugins) {
|
|
1990
|
-
if (hooks.modifyAppConfig) {
|
|
1991
|
-
try {
|
|
1992
|
-
const modified = hooks.modifyAppConfig(result, this.context);
|
|
1993
|
-
if (modified) {
|
|
1994
|
-
result = modified;
|
|
1995
|
-
}
|
|
1996
|
-
} catch (error) {
|
|
1997
|
-
this.context.logger.error(
|
|
1998
|
-
`\u63D2\u4EF6 ${name} modifyAppConfig \u6267\u884C\u5931\u8D25: ${error}`
|
|
1999
|
-
);
|
|
2000
|
-
}
|
|
2001
|
-
}
|
|
2002
|
-
}
|
|
2003
|
-
return result;
|
|
2004
|
-
}
|
|
2005
|
-
/**
|
|
2006
|
-
* 收集所有插件的 Provider
|
|
2007
|
-
*/
|
|
2008
|
-
collectProviders() {
|
|
2009
|
-
const providers = [];
|
|
2010
|
-
for (const [name, { hooks }] of this.plugins) {
|
|
2011
|
-
if (hooks.addProvider) {
|
|
2012
|
-
try {
|
|
2013
|
-
const result = hooks.addProvider(this.context);
|
|
2014
|
-
if (Array.isArray(result)) {
|
|
2015
|
-
providers.push(...result);
|
|
2016
|
-
} else if (result) {
|
|
2017
|
-
providers.push(result);
|
|
2018
|
-
}
|
|
2019
|
-
} catch (error) {
|
|
2020
|
-
this.context.logger.error(
|
|
2021
|
-
`\u63D2\u4EF6 ${name} addProvider \u6267\u884C\u5931\u8D25: ${error}`
|
|
2022
|
-
);
|
|
2023
|
-
}
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
return providers;
|
|
2027
|
-
}
|
|
2028
|
-
/**
|
|
2029
|
-
* 执行 beforeBuild 钩子
|
|
2030
|
-
*/
|
|
2031
|
-
async runBeforeBuild() {
|
|
2032
|
-
for (const [name, { hooks }] of this.plugins) {
|
|
2033
|
-
if (hooks.beforeBuild) {
|
|
2034
|
-
try {
|
|
2035
|
-
await hooks.beforeBuild(this.context);
|
|
2036
|
-
} catch (error) {
|
|
2037
|
-
this.context.logger.error(
|
|
2038
|
-
`\u63D2\u4EF6 ${name} beforeBuild \u6267\u884C\u5931\u8D25: ${error}`
|
|
2039
|
-
);
|
|
2040
|
-
}
|
|
2041
|
-
}
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
/**
|
|
2045
|
-
* 执行 afterBuild 钩子
|
|
2046
|
-
*/
|
|
2047
|
-
async runAfterBuild(stats) {
|
|
2048
|
-
for (const [name, { hooks }] of this.plugins) {
|
|
2049
|
-
if (hooks.afterBuild) {
|
|
2050
|
-
try {
|
|
2051
|
-
await hooks.afterBuild(this.context, stats);
|
|
2052
|
-
} catch (error) {
|
|
2053
|
-
this.context.logger.error(
|
|
2054
|
-
`\u63D2\u4EF6 ${name} afterBuild \u6267\u884C\u5931\u8D25: ${error}`
|
|
2055
|
-
);
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
/**
|
|
2061
|
-
* 执行 beforeDevServer 钩子
|
|
2062
|
-
*/
|
|
2063
|
-
async runBeforeDevServer() {
|
|
2064
|
-
for (const [name, { hooks }] of this.plugins) {
|
|
2065
|
-
if (hooks.beforeDevServer) {
|
|
2066
|
-
try {
|
|
2067
|
-
await hooks.beforeDevServer(this.context);
|
|
2068
|
-
} catch (error) {
|
|
2069
|
-
this.context.logger.error(
|
|
2070
|
-
`\u63D2\u4EF6 ${name} beforeDevServer \u6267\u884C\u5931\u8D25: ${error}`
|
|
2071
|
-
);
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
/**
|
|
2077
|
-
* 执行 afterDevServer 钩子
|
|
2078
|
-
*/
|
|
2079
|
-
async runAfterDevServer(server) {
|
|
2080
|
-
for (const [name, { hooks }] of this.plugins) {
|
|
2081
|
-
if (hooks.afterDevServer) {
|
|
2082
|
-
try {
|
|
2083
|
-
await hooks.afterDevServer(this.context, server);
|
|
2084
|
-
} catch (error) {
|
|
2085
|
-
this.context.logger.error(
|
|
2086
|
-
`\u63D2\u4EF6 ${name} afterDevServer \u6267\u884C\u5931\u8D25: ${error}`
|
|
2087
|
-
);
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2091
|
-
}
|
|
2092
|
-
/**
|
|
2093
|
-
* 获取所有已加载的插件名称
|
|
2094
|
-
*/
|
|
2095
|
-
getPluginNames() {
|
|
2096
|
-
return Array.from(this.plugins.keys());
|
|
2097
|
-
}
|
|
2098
|
-
/**
|
|
2099
|
-
* 获取所有已加载的插件
|
|
2100
|
-
*/
|
|
2101
|
-
getPlugins() {
|
|
2102
|
-
return Array.from(this.plugins.values()).map((p) => p.plugin);
|
|
2103
|
-
}
|
|
2104
|
-
/**
|
|
2105
|
-
* 获取所有已加载的插件钩子
|
|
2106
|
-
*/
|
|
2107
|
-
getPluginHooks() {
|
|
2108
|
-
return Array.from(this.plugins.values()).map((p) => p.hooks);
|
|
2109
|
-
}
|
|
2110
|
-
};
|
|
2111
|
-
|
|
2112
|
-
// src/cli/port.ts
|
|
2113
|
-
import net from "net";
|
|
2114
|
-
function isPortAvailable(port, host) {
|
|
2115
|
-
return new Promise((resolve3) => {
|
|
2116
|
-
const server = net.createServer();
|
|
2117
|
-
server.once("error", (err) => {
|
|
2118
|
-
if (err.code === "EADDRINUSE") {
|
|
2119
|
-
resolve3(false);
|
|
2120
|
-
} else {
|
|
2121
|
-
resolve3(false);
|
|
2122
|
-
}
|
|
2123
|
-
});
|
|
2124
|
-
server.once("listening", () => {
|
|
2125
|
-
server.close(() => resolve3(true));
|
|
2126
|
-
});
|
|
2127
|
-
server.listen(port, host);
|
|
2128
|
-
});
|
|
2129
|
-
}
|
|
2130
|
-
async function getAvailablePort(preferredPort, host) {
|
|
2131
|
-
const MAX_ATTEMPTS = 20;
|
|
2132
|
-
for (let i = 0; i < MAX_ATTEMPTS; i++) {
|
|
2133
|
-
const port = preferredPort + i;
|
|
2134
|
-
const available = await isPortAvailable(port, host);
|
|
2135
|
-
if (available) return port;
|
|
2136
|
-
}
|
|
2137
|
-
throw new Error(
|
|
2138
|
-
`No available port found in range ${preferredPort}-${preferredPort + MAX_ATTEMPTS - 1}`
|
|
2139
|
-
);
|
|
2140
|
-
}
|
|
2141
|
-
|
|
2142
|
-
// src/cli/printer.ts
|
|
2143
|
-
import chalk from "chalk";
|
|
2144
|
-
import os from "os";
|
|
2145
|
-
import { createRequire as createRequire3 } from "module";
|
|
2146
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2147
|
-
import { dirname as dirname2, join as join6 } from "path";
|
|
2148
|
-
var __filename = fileURLToPath2(import.meta.url);
|
|
2149
|
-
var __dirname2 = dirname2(__filename);
|
|
2150
|
-
var require4 = createRequire3(import.meta.url);
|
|
2151
|
-
var _version = null;
|
|
2152
|
-
function getFrameworkVersion() {
|
|
2153
|
-
if (_version) return _version;
|
|
2154
|
-
try {
|
|
2155
|
-
const pkgPath = join6(__dirname2, "../../package.json");
|
|
2156
|
-
const pkg = require4(pkgPath);
|
|
2157
|
-
_version = pkg.version || "0.0.0";
|
|
2158
|
-
} catch {
|
|
2159
|
-
_version = "0.0.0";
|
|
2160
|
-
}
|
|
2161
|
-
return _version;
|
|
2162
|
-
}
|
|
2163
|
-
function getNetworkAddress(port) {
|
|
2164
|
-
const interfaces = os.networkInterfaces();
|
|
2165
|
-
for (const entries of Object.values(interfaces)) {
|
|
2166
|
-
if (!entries) continue;
|
|
2167
|
-
for (const entry of entries) {
|
|
2168
|
-
if (entry.family === "IPv4" && !entry.internal) {
|
|
2169
|
-
return `http://${entry.address}:${port}/`;
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
}
|
|
2173
|
-
return null;
|
|
2174
|
-
}
|
|
2175
|
-
var BAR_WIDTH = 30;
|
|
2176
|
-
function renderBar(percent) {
|
|
2177
|
-
const filled = Math.round(BAR_WIDTH * percent);
|
|
2178
|
-
const empty = BAR_WIDTH - filled;
|
|
2179
|
-
const bar = chalk.green("\u2501".repeat(filled)) + chalk.gray("\u2501".repeat(empty));
|
|
2180
|
-
return bar;
|
|
2181
|
-
}
|
|
2182
|
-
var DevPrinter = class {
|
|
2183
|
-
constructor(host, port, pluginNames, isBuild = false) {
|
|
2184
|
-
this.host = host;
|
|
2185
|
-
this.port = port;
|
|
2186
|
-
this.pluginNames = pluginNames;
|
|
2187
|
-
this.isBuild = isBuild;
|
|
2188
|
-
}
|
|
2189
|
-
startTime = 0;
|
|
2190
|
-
lastProgressLine = "";
|
|
2191
|
-
firstCompileDone = false;
|
|
2192
|
-
/**
|
|
2193
|
-
* 打印框架 banner
|
|
2194
|
-
*/
|
|
2195
|
-
printBanner() {
|
|
2196
|
-
const version2 = getFrameworkVersion();
|
|
2197
|
-
console.log();
|
|
2198
|
-
console.log(
|
|
2199
|
-
` ${chalk.bold.cyan("@4399ywkf/core")} ${chalk.green(`Framework v${version2}`)}`
|
|
2200
|
-
);
|
|
2201
|
-
console.log();
|
|
2202
|
-
}
|
|
2203
|
-
/**
|
|
2204
|
-
* 打印 "start build started..."
|
|
2205
|
-
*/
|
|
2206
|
-
printBuildStart() {
|
|
2207
|
-
this.startTime = Date.now();
|
|
2208
|
-
this.compileDone = false;
|
|
2209
|
-
const label = chalk.gray("start");
|
|
2210
|
-
console.log(` ${label} build started...`);
|
|
2211
|
-
}
|
|
2212
|
-
/**
|
|
2213
|
-
* 更新编译进度条(原地覆写同一行)
|
|
2214
|
-
*/
|
|
2215
|
-
updateProgress(percent, message) {
|
|
2216
|
-
const pct = Math.min(Math.round(percent * 100), 100);
|
|
2217
|
-
const bar = renderBar(percent);
|
|
2218
|
-
const status = message || "compiling";
|
|
2219
|
-
const line = ` ${chalk.yellow("\u25CF")} client ${bar} ${chalk.bold(`(${pct}%)`)} ${chalk.gray(status)}`;
|
|
2220
|
-
if (process.stdout.isTTY) {
|
|
2221
|
-
if (this.lastProgressLine) {
|
|
2222
|
-
process.stdout.write("\x1B[1A\x1B[2K");
|
|
2223
|
-
}
|
|
2224
|
-
process.stdout.write(line + "\n");
|
|
2225
|
-
} else if (!this.firstCompileDone && pct === 100) {
|
|
2226
|
-
console.log(line);
|
|
2227
|
-
}
|
|
2228
|
-
this.lastProgressLine = line;
|
|
2229
|
-
}
|
|
2230
|
-
/**
|
|
2231
|
-
* 编译完成
|
|
2120
|
+
* 编译完成
|
|
2232
2121
|
*/
|
|
2233
2122
|
printBuildDone(hasErrors = false) {
|
|
2234
2123
|
if (this.firstCompileDone) {
|
|
2235
2124
|
if (!hasErrors) {
|
|
2236
2125
|
const elapsed2 = ((Date.now() - this.startTime) / 1e3).toFixed(2);
|
|
2237
|
-
console.log(
|
|
2238
|
-
` ${chalk.green("hmr")} update in ${chalk.bold(`${elapsed2} s`)}`
|
|
2239
|
-
);
|
|
2126
|
+
console.log(` ${chalk.green("hmr")} update in ${chalk.bold(`${elapsed2} s`)}`);
|
|
2240
2127
|
}
|
|
2241
2128
|
return;
|
|
2242
2129
|
}
|
|
@@ -2285,9 +2172,7 @@ var DevPrinter = class {
|
|
|
2285
2172
|
}
|
|
2286
2173
|
console.log();
|
|
2287
2174
|
this.printPluginList();
|
|
2288
|
-
console.log(
|
|
2289
|
-
` ${chalk.bold(">")} press ${chalk.bold("h + enter")} to show shortcuts`
|
|
2290
|
-
);
|
|
2175
|
+
console.log(` ${chalk.bold(">")} press ${chalk.bold("h + enter")} to show shortcuts`);
|
|
2291
2176
|
console.log();
|
|
2292
2177
|
}
|
|
2293
2178
|
/**
|
|
@@ -2342,103 +2227,7 @@ function registerShortcuts(printer, opts) {
|
|
|
2342
2227
|
process.stdin.resume();
|
|
2343
2228
|
}
|
|
2344
2229
|
|
|
2345
|
-
// src/cli/dev.ts
|
|
2346
|
-
async function dev(options = {}) {
|
|
2347
|
-
const cwd = options.cwd || process.cwd();
|
|
2348
|
-
const mode = options.mode || "development";
|
|
2349
|
-
try {
|
|
2350
|
-
preloadEnv(cwd, mode, "development");
|
|
2351
|
-
const { config } = await resolveConfig(cwd);
|
|
2352
|
-
loadEnv(config, cwd, mode, "development");
|
|
2353
|
-
const pluginManager = new PluginManager(config, cwd, true);
|
|
2354
|
-
if (config.plugins && config.plugins.length > 0) {
|
|
2355
|
-
await pluginManager.loadPlugins(config.plugins);
|
|
2356
|
-
}
|
|
2357
|
-
await pluginManager.runBeforeDevServer();
|
|
2358
|
-
let rspackConfig = createRspackConfig(config, cwd, { isDev: true });
|
|
2359
|
-
rspackConfig = await pluginManager.applyRspackConfigHooks(rspackConfig);
|
|
2360
|
-
const host = config.dev.host || "localhost";
|
|
2361
|
-
const preferredPort = config.dev.port || 3e3;
|
|
2362
|
-
const port = await getAvailablePort(preferredPort, host);
|
|
2363
|
-
const pluginNames = pluginManager.getPluginNames();
|
|
2364
|
-
if (port !== preferredPort) {
|
|
2365
|
-
console.log(
|
|
2366
|
-
chalk2.yellow(` Port ${preferredPort} is in use, using ${port} instead.
|
|
2367
|
-
`)
|
|
2368
|
-
);
|
|
2369
|
-
}
|
|
2370
|
-
const printer = new DevPrinter(host, port, pluginNames);
|
|
2371
|
-
printer.printBanner();
|
|
2372
|
-
printer.printBuildStart();
|
|
2373
|
-
printer.updateProgress(0, "preparing");
|
|
2374
|
-
rspackConfig.plugins = rspackConfig.plugins || [];
|
|
2375
|
-
rspackConfig.plugins.push(
|
|
2376
|
-
new rspack3.ProgressPlugin(createProgressHandler(printer))
|
|
2377
|
-
);
|
|
2378
|
-
rspackConfig.stats = "none";
|
|
2379
|
-
rspackConfig.infrastructureLogging = { level: "none" };
|
|
2380
|
-
if (rspackConfig.devServer) {
|
|
2381
|
-
const ds = rspackConfig.devServer;
|
|
2382
|
-
const existingClient = ds.client ?? {};
|
|
2383
|
-
ds.client = {
|
|
2384
|
-
...existingClient,
|
|
2385
|
-
logging: "warn",
|
|
2386
|
-
overlay: false,
|
|
2387
|
-
progress: false
|
|
2388
|
-
};
|
|
2389
|
-
}
|
|
2390
|
-
const compiler = rspack3(rspackConfig);
|
|
2391
|
-
compiler.hooks.done.tap("ywkf-dev-printer", (stats) => {
|
|
2392
|
-
const hasErrors = stats.hasErrors();
|
|
2393
|
-
if (hasErrors) {
|
|
2394
|
-
const info = stats.toJson({ errors: true });
|
|
2395
|
-
console.log();
|
|
2396
|
-
console.log(chalk2.red(" Compile error:"));
|
|
2397
|
-
for (const err of info.errors || []) {
|
|
2398
|
-
console.log(chalk2.red(` ${err.message}`));
|
|
2399
|
-
}
|
|
2400
|
-
console.log();
|
|
2401
|
-
}
|
|
2402
|
-
printer.printBuildDone(hasErrors);
|
|
2403
|
-
});
|
|
2404
|
-
compiler.hooks.invalid.tap("ywkf-dev-printer", () => {
|
|
2405
|
-
printer.markRebuildStart();
|
|
2406
|
-
printer.updateProgress(0, "rebuilding");
|
|
2407
|
-
});
|
|
2408
|
-
const devServerOptions = {
|
|
2409
|
-
...rspackConfig.devServer || {},
|
|
2410
|
-
host,
|
|
2411
|
-
port
|
|
2412
|
-
};
|
|
2413
|
-
const server = new RspackDevServer(devServerOptions, compiler);
|
|
2414
|
-
await server.start();
|
|
2415
|
-
await pluginManager.runAfterDevServer({ host, port });
|
|
2416
|
-
registerShortcuts(printer, {
|
|
2417
|
-
port,
|
|
2418
|
-
onQuit: async () => {
|
|
2419
|
-
console.log(chalk2.gray("\n Shutting down...\n"));
|
|
2420
|
-
await server.stop();
|
|
2421
|
-
process.exit(0);
|
|
2422
|
-
}
|
|
2423
|
-
});
|
|
2424
|
-
const signals = ["SIGINT", "SIGTERM"];
|
|
2425
|
-
for (const signal of signals) {
|
|
2426
|
-
process.on(signal, async () => {
|
|
2427
|
-
await server.stop();
|
|
2428
|
-
process.exit(0);
|
|
2429
|
-
});
|
|
2430
|
-
}
|
|
2431
|
-
} catch (error) {
|
|
2432
|
-
console.error();
|
|
2433
|
-
console.error(chalk2.red(" \u2716 Dev server failed to start"));
|
|
2434
|
-
console.error(error);
|
|
2435
|
-
process.exit(1);
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
|
-
|
|
2439
2230
|
// src/cli/build.ts
|
|
2440
|
-
import { rspack as rspack4 } from "@rspack/core";
|
|
2441
|
-
import chalk3 from "chalk";
|
|
2442
2231
|
function formatSize(bytes) {
|
|
2443
2232
|
if (bytes < 1024) return `${bytes} B`;
|
|
2444
2233
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;
|
|
@@ -2451,30 +2240,28 @@ function printBuildResult(stats) {
|
|
|
2451
2240
|
warnings: true
|
|
2452
2241
|
});
|
|
2453
2242
|
if (info.errors && info.errors.length > 0) {
|
|
2454
|
-
console.log(
|
|
2243
|
+
console.log(chalk2.red("\n Compile errors:"));
|
|
2455
2244
|
for (const error of info.errors) {
|
|
2456
|
-
console.log(
|
|
2245
|
+
console.log(chalk2.red(` ${error.message}`));
|
|
2457
2246
|
}
|
|
2458
2247
|
return;
|
|
2459
2248
|
}
|
|
2460
2249
|
if (info.warnings && info.warnings.length > 0) {
|
|
2461
|
-
console.log(
|
|
2250
|
+
console.log(chalk2.yellow("\n Warnings:"));
|
|
2462
2251
|
for (const warning of info.warnings) {
|
|
2463
|
-
console.log(
|
|
2252
|
+
console.log(chalk2.yellow(` ${warning.message}`));
|
|
2464
2253
|
}
|
|
2465
2254
|
}
|
|
2466
|
-
console.log(
|
|
2255
|
+
console.log(chalk2.bold("\n Build output:"));
|
|
2467
2256
|
console.log();
|
|
2468
2257
|
const assets = info.assets || [];
|
|
2469
2258
|
const sortedAssets = assets.filter((asset) => !asset.name.endsWith(".map")).sort((a, b) => b.size - a.size);
|
|
2470
2259
|
for (const asset of sortedAssets.slice(0, 15)) {
|
|
2471
|
-
const sizeColor = asset.size > 500 * 1024 ?
|
|
2472
|
-
console.log(
|
|
2473
|
-
` ${chalk3.dim(asset.name.padEnd(50))} ${sizeColor(formatSize(asset.size))}`
|
|
2474
|
-
);
|
|
2260
|
+
const sizeColor = asset.size > 500 * 1024 ? chalk2.yellow : chalk2.green;
|
|
2261
|
+
console.log(` ${chalk2.dim(asset.name.padEnd(50))} ${sizeColor(formatSize(asset.size))}`);
|
|
2475
2262
|
}
|
|
2476
2263
|
if (sortedAssets.length > 15) {
|
|
2477
|
-
console.log(
|
|
2264
|
+
console.log(chalk2.dim(` ... and ${sortedAssets.length - 15} more files`));
|
|
2478
2265
|
}
|
|
2479
2266
|
console.log();
|
|
2480
2267
|
}
|
|
@@ -2498,12 +2285,10 @@ async function build(options = {}) {
|
|
|
2498
2285
|
printer.printBuildStart();
|
|
2499
2286
|
printer.updateProgress(0, "preparing");
|
|
2500
2287
|
rspackConfig.plugins = rspackConfig.plugins || [];
|
|
2501
|
-
rspackConfig.plugins.push(
|
|
2502
|
-
new rspack4.ProgressPlugin(createProgressHandler(printer))
|
|
2503
|
-
);
|
|
2288
|
+
rspackConfig.plugins.push(new rspack3.ProgressPlugin(createProgressHandler(printer)));
|
|
2504
2289
|
rspackConfig.stats = "none";
|
|
2505
2290
|
rspackConfig.infrastructureLogging = { level: "none" };
|
|
2506
|
-
const compiler =
|
|
2291
|
+
const compiler = rspack3(rspackConfig);
|
|
2507
2292
|
const stats = await new Promise((resolve3, reject) => {
|
|
2508
2293
|
compiler.run((err, stats2) => {
|
|
2509
2294
|
if (err) {
|
|
@@ -2537,7 +2322,132 @@ async function build(options = {}) {
|
|
|
2537
2322
|
printBuildResult(stats);
|
|
2538
2323
|
} catch (error) {
|
|
2539
2324
|
console.error();
|
|
2540
|
-
console.error(
|
|
2325
|
+
console.error(chalk2.red(" \u2716 Build failed"));
|
|
2326
|
+
console.error(error);
|
|
2327
|
+
process.exit(1);
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
// src/cli/dev.ts
|
|
2332
|
+
import { rspack as rspack4 } from "@rspack/core";
|
|
2333
|
+
import { RspackDevServer } from "@rspack/dev-server";
|
|
2334
|
+
import chalk3 from "chalk";
|
|
2335
|
+
|
|
2336
|
+
// src/cli/port.ts
|
|
2337
|
+
import net from "net";
|
|
2338
|
+
function isPortAvailable(port, host) {
|
|
2339
|
+
return new Promise((resolve3) => {
|
|
2340
|
+
const server = net.createServer();
|
|
2341
|
+
server.once("error", (err) => {
|
|
2342
|
+
if (err.code === "EADDRINUSE") {
|
|
2343
|
+
resolve3(false);
|
|
2344
|
+
} else {
|
|
2345
|
+
resolve3(false);
|
|
2346
|
+
}
|
|
2347
|
+
});
|
|
2348
|
+
server.once("listening", () => {
|
|
2349
|
+
server.close(() => resolve3(true));
|
|
2350
|
+
});
|
|
2351
|
+
server.listen(port, host);
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2354
|
+
async function getAvailablePort(preferredPort, host) {
|
|
2355
|
+
const MAX_ATTEMPTS = 20;
|
|
2356
|
+
for (let i = 0; i < MAX_ATTEMPTS; i++) {
|
|
2357
|
+
const port = preferredPort + i;
|
|
2358
|
+
const available = await isPortAvailable(port, host);
|
|
2359
|
+
if (available) return port;
|
|
2360
|
+
}
|
|
2361
|
+
throw new Error(
|
|
2362
|
+
`No available port found in range ${preferredPort}-${preferredPort + MAX_ATTEMPTS - 1}`
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
// src/cli/dev.ts
|
|
2367
|
+
async function dev(options = {}) {
|
|
2368
|
+
const cwd = options.cwd || process.cwd();
|
|
2369
|
+
const mode = options.mode || "development";
|
|
2370
|
+
try {
|
|
2371
|
+
preloadEnv(cwd, mode, "development");
|
|
2372
|
+
const { config } = await resolveConfig(cwd);
|
|
2373
|
+
loadEnv(config, cwd, mode, "development");
|
|
2374
|
+
const pluginManager = new PluginManager(config, cwd, true);
|
|
2375
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
2376
|
+
await pluginManager.loadPlugins(config.plugins);
|
|
2377
|
+
}
|
|
2378
|
+
await pluginManager.runBeforeDevServer();
|
|
2379
|
+
let rspackConfig = createRspackConfig(config, cwd, { isDev: true });
|
|
2380
|
+
rspackConfig = await pluginManager.applyRspackConfigHooks(rspackConfig);
|
|
2381
|
+
const host = config.dev.host || "localhost";
|
|
2382
|
+
const preferredPort = config.dev.port || 3e3;
|
|
2383
|
+
const port = await getAvailablePort(preferredPort, host);
|
|
2384
|
+
const pluginNames = pluginManager.getPluginNames();
|
|
2385
|
+
if (port !== preferredPort) {
|
|
2386
|
+
console.log(chalk3.yellow(` Port ${preferredPort} is in use, using ${port} instead.
|
|
2387
|
+
`));
|
|
2388
|
+
}
|
|
2389
|
+
const printer = new DevPrinter(host, port, pluginNames);
|
|
2390
|
+
printer.printBanner();
|
|
2391
|
+
printer.printBuildStart();
|
|
2392
|
+
printer.updateProgress(0, "preparing");
|
|
2393
|
+
rspackConfig.plugins = rspackConfig.plugins || [];
|
|
2394
|
+
rspackConfig.plugins.push(new rspack4.ProgressPlugin(createProgressHandler(printer)));
|
|
2395
|
+
rspackConfig.stats = "none";
|
|
2396
|
+
rspackConfig.infrastructureLogging = { level: "none" };
|
|
2397
|
+
if (rspackConfig.devServer) {
|
|
2398
|
+
const ds = rspackConfig.devServer;
|
|
2399
|
+
const existingClient = ds.client ?? {};
|
|
2400
|
+
ds.client = {
|
|
2401
|
+
...existingClient,
|
|
2402
|
+
logging: "warn",
|
|
2403
|
+
overlay: false,
|
|
2404
|
+
progress: false
|
|
2405
|
+
};
|
|
2406
|
+
}
|
|
2407
|
+
const compiler = rspack4(rspackConfig);
|
|
2408
|
+
compiler.hooks.done.tap("ywkf-dev-printer", (stats) => {
|
|
2409
|
+
const hasErrors = stats.hasErrors();
|
|
2410
|
+
if (hasErrors) {
|
|
2411
|
+
const info = stats.toJson({ errors: true });
|
|
2412
|
+
console.log();
|
|
2413
|
+
console.log(chalk3.red(" Compile error:"));
|
|
2414
|
+
for (const err of info.errors || []) {
|
|
2415
|
+
console.log(chalk3.red(` ${err.message}`));
|
|
2416
|
+
}
|
|
2417
|
+
console.log();
|
|
2418
|
+
}
|
|
2419
|
+
printer.printBuildDone(hasErrors);
|
|
2420
|
+
});
|
|
2421
|
+
compiler.hooks.invalid.tap("ywkf-dev-printer", () => {
|
|
2422
|
+
printer.markRebuildStart();
|
|
2423
|
+
printer.updateProgress(0, "rebuilding");
|
|
2424
|
+
});
|
|
2425
|
+
const devServerOptions = {
|
|
2426
|
+
...rspackConfig.devServer || {},
|
|
2427
|
+
host,
|
|
2428
|
+
port
|
|
2429
|
+
};
|
|
2430
|
+
const server = new RspackDevServer(devServerOptions, compiler);
|
|
2431
|
+
await server.start();
|
|
2432
|
+
await pluginManager.runAfterDevServer({ host, port });
|
|
2433
|
+
registerShortcuts(printer, {
|
|
2434
|
+
port,
|
|
2435
|
+
onQuit: async () => {
|
|
2436
|
+
console.log(chalk3.gray("\n Shutting down...\n"));
|
|
2437
|
+
await server.stop();
|
|
2438
|
+
process.exit(0);
|
|
2439
|
+
}
|
|
2440
|
+
});
|
|
2441
|
+
const signals = ["SIGINT", "SIGTERM"];
|
|
2442
|
+
for (const signal of signals) {
|
|
2443
|
+
process.on(signal, async () => {
|
|
2444
|
+
await server.stop();
|
|
2445
|
+
process.exit(0);
|
|
2446
|
+
});
|
|
2447
|
+
}
|
|
2448
|
+
} catch (error) {
|
|
2449
|
+
console.error();
|
|
2450
|
+
console.error(chalk3.red(" \u2716 Dev server failed to start"));
|
|
2541
2451
|
console.error(error);
|
|
2542
2452
|
process.exit(1);
|
|
2543
2453
|
}
|
|
@@ -2546,10 +2456,10 @@ async function build(options = {}) {
|
|
|
2546
2456
|
// src/cli/index.ts
|
|
2547
2457
|
var __filename2 = fileURLToPath3(import.meta.url);
|
|
2548
2458
|
var __dirname3 = dirname3(__filename2);
|
|
2549
|
-
var
|
|
2459
|
+
var require4 = createRequire4(import.meta.url);
|
|
2550
2460
|
var version = "0.0.0";
|
|
2551
2461
|
try {
|
|
2552
|
-
const pkg =
|
|
2462
|
+
const pkg = require4(join7(__dirname3, "../../package.json"));
|
|
2553
2463
|
version = pkg.version;
|
|
2554
2464
|
} catch {
|
|
2555
2465
|
}
|