@4399ywkf/core 5.1.1 → 5.1.3
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 +237 -149
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +7 -2
- package/dist/config/index.js +17 -10
- package/dist/config/index.js.map +1 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.js +247 -155
- package/dist/index.js.map +1 -1
- package/dist/router/index.js +7 -3
- package/dist/router/index.js.map +1 -1
- package/dist/rspack/index.js +6 -148
- package/dist/rspack/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -25,7 +25,6 @@ declare function build(options?: {
|
|
|
25
25
|
* 启动开发服务器
|
|
26
26
|
*
|
|
27
27
|
* @param options.mode - env 文件模式,决定加载 .env.{mode},默认 "development"
|
|
28
|
-
* 例如 --mode staging 会加载 .env.staging,但 NODE_ENV 仍为 "development"
|
|
29
28
|
*/
|
|
30
29
|
declare function dev(options?: {
|
|
31
30
|
cwd?: string;
|
|
@@ -129,17 +128,11 @@ declare class YwkfGeneratorPlugin {
|
|
|
129
128
|
* 初始化插件钩子
|
|
130
129
|
*/
|
|
131
130
|
private initialize;
|
|
132
|
-
private resetState;
|
|
133
|
-
private regenerate;
|
|
134
131
|
apply(compiler: Compiler): void;
|
|
135
132
|
/**
|
|
136
133
|
* 监听页面目录变化
|
|
137
134
|
*/
|
|
138
135
|
private watchPages;
|
|
139
|
-
/**
|
|
140
|
-
* 监听配置文件变化,重新加载配置并重新生成 .ywkf 文件
|
|
141
|
-
*/
|
|
142
|
-
private watchConfig;
|
|
143
136
|
}
|
|
144
137
|
|
|
145
138
|
export { GeneratorContext, PluginConfig, PluginHooks, YwkfConfig, YwkfGenerator, YwkfGeneratorPlugin, type YwkfGeneratorPluginOptions, build, dev };
|
package/dist/index.js
CHANGED
|
@@ -876,7 +876,7 @@ function createMockMiddleware(mockPath, options) {
|
|
|
876
876
|
scanMockFiles(mockPath);
|
|
877
877
|
return async (_req, _res, next) => {
|
|
878
878
|
if (delay > 0) {
|
|
879
|
-
await new Promise((
|
|
879
|
+
await new Promise((resolve5) => setTimeout(resolve5, delay));
|
|
880
880
|
}
|
|
881
881
|
next();
|
|
882
882
|
};
|
|
@@ -1830,11 +1830,11 @@ var zustandPlugin = createPlugin((options = {}) => ({
|
|
|
1830
1830
|
const hooks = {
|
|
1831
1831
|
modifyRspackConfig(rspackConfig) {
|
|
1832
1832
|
logger.info("Zustand \u5DF2\u542F\u7528");
|
|
1833
|
-
const
|
|
1834
|
-
const alias =
|
|
1833
|
+
const resolve5 = rspackConfig.resolve || {};
|
|
1834
|
+
const alias = resolve5.alias || {};
|
|
1835
1835
|
alias["@store"] = storePath;
|
|
1836
|
-
|
|
1837
|
-
rspackConfig.resolve =
|
|
1836
|
+
resolve5.alias = alias;
|
|
1837
|
+
rspackConfig.resolve = resolve5;
|
|
1838
1838
|
return rspackConfig;
|
|
1839
1839
|
},
|
|
1840
1840
|
generateFiles(_ctx) {
|
|
@@ -2127,7 +2127,7 @@ var defaultConfig = {
|
|
|
2127
2127
|
strictMode: true,
|
|
2128
2128
|
dev: {
|
|
2129
2129
|
port: 3e3,
|
|
2130
|
-
host: "
|
|
2130
|
+
host: "127.0.0.1",
|
|
2131
2131
|
proxy: {},
|
|
2132
2132
|
https: false
|
|
2133
2133
|
},
|
|
@@ -2191,32 +2191,39 @@ function findConfigFile(cwd) {
|
|
|
2191
2191
|
}
|
|
2192
2192
|
return null;
|
|
2193
2193
|
}
|
|
2194
|
-
async function loadTsConfig(configPath) {
|
|
2194
|
+
async function loadTsConfig(configPath, fresh = false) {
|
|
2195
2195
|
const jiti = (await import("jiti")).default;
|
|
2196
2196
|
const loader = jiti(configPath, {
|
|
2197
|
-
interopDefault: true
|
|
2197
|
+
interopDefault: true,
|
|
2198
|
+
// fresh(热重启)时必须禁用缓存:jiti 的 moduleCache 默认与 Node 原生 require 缓存集成,
|
|
2199
|
+
// 即使新建 jiti 实例,loader(configPath) 仍会命中 Node 全局缓存读回旧配置;
|
|
2200
|
+
// fsCache 为转译产物缓存,一并关闭以确保读到最新源码。
|
|
2201
|
+
...fresh ? { moduleCache: false, fsCache: false } : {}
|
|
2198
2202
|
});
|
|
2199
2203
|
const config = loader(configPath);
|
|
2200
2204
|
return config.default || config;
|
|
2201
2205
|
}
|
|
2202
|
-
async function loadJsConfig(configPath) {
|
|
2203
|
-
|
|
2206
|
+
async function loadJsConfig(configPath, fresh = false) {
|
|
2207
|
+
let fileUrl = pathToFileURL(configPath).href;
|
|
2208
|
+
if (fresh) {
|
|
2209
|
+
fileUrl += `?t=${Date.now()}`;
|
|
2210
|
+
}
|
|
2204
2211
|
const module = await import(fileUrl);
|
|
2205
2212
|
return module.default || module;
|
|
2206
2213
|
}
|
|
2207
|
-
async function loadConfigFile(configPath) {
|
|
2214
|
+
async function loadConfigFile(configPath, opts = {}) {
|
|
2208
2215
|
const ext = extname(configPath);
|
|
2209
2216
|
if (ext === ".ts" || ext === ".mts") {
|
|
2210
|
-
return loadTsConfig(configPath);
|
|
2217
|
+
return loadTsConfig(configPath, opts.fresh);
|
|
2211
2218
|
}
|
|
2212
|
-
return loadJsConfig(configPath);
|
|
2219
|
+
return loadJsConfig(configPath, opts.fresh);
|
|
2213
2220
|
}
|
|
2214
2221
|
function mergeConfig(userConfig, baseConfig = defaultConfig) {
|
|
2215
2222
|
return deepmerge(baseConfig, userConfig, {
|
|
2216
2223
|
arrayMerge: (_, sourceArray) => sourceArray
|
|
2217
2224
|
});
|
|
2218
2225
|
}
|
|
2219
|
-
async function resolveConfig(cwd) {
|
|
2226
|
+
async function resolveConfig(cwd, opts = {}) {
|
|
2220
2227
|
const configPath = findConfigFile(cwd);
|
|
2221
2228
|
if (!configPath) {
|
|
2222
2229
|
console.warn("\u26A0\uFE0F \u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6 (ywkf.config.ts)\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E");
|
|
@@ -2226,7 +2233,7 @@ async function resolveConfig(cwd) {
|
|
|
2226
2233
|
};
|
|
2227
2234
|
}
|
|
2228
2235
|
try {
|
|
2229
|
-
const userConfig = await loadConfigFile(configPath);
|
|
2236
|
+
const userConfig = await loadConfigFile(configPath, opts);
|
|
2230
2237
|
const normalized = normalizeConfig(userConfig);
|
|
2231
2238
|
const config = mergeConfig(normalized);
|
|
2232
2239
|
return { config, configPath };
|
|
@@ -3377,16 +3384,6 @@ var YwkfGeneratorPlugin = class {
|
|
|
3377
3384
|
);
|
|
3378
3385
|
this.initialized = true;
|
|
3379
3386
|
}
|
|
3380
|
-
resetState() {
|
|
3381
|
-
this.initialized = false;
|
|
3382
|
-
this.pluginHooks = [];
|
|
3383
|
-
this.generator = null;
|
|
3384
|
-
}
|
|
3385
|
-
async regenerate() {
|
|
3386
|
-
if (this.generator) {
|
|
3387
|
-
await this.generator.generate();
|
|
3388
|
-
}
|
|
3389
|
-
}
|
|
3390
3387
|
apply(compiler) {
|
|
3391
3388
|
const pluginName = "YwkfGeneratorPlugin";
|
|
3392
3389
|
compiler.hooks.beforeCompile.tapAsync(pluginName, async (_params, callback) => {
|
|
@@ -3402,14 +3399,13 @@ var YwkfGeneratorPlugin = class {
|
|
|
3402
3399
|
}
|
|
3403
3400
|
});
|
|
3404
3401
|
if (this.options.isDev && !this.isWatching) {
|
|
3405
|
-
this.watchPages();
|
|
3406
|
-
this.watchConfig();
|
|
3402
|
+
this.watchPages(compiler);
|
|
3407
3403
|
}
|
|
3408
3404
|
}
|
|
3409
3405
|
/**
|
|
3410
3406
|
* 监听页面目录变化
|
|
3411
3407
|
*/
|
|
3412
|
-
watchPages() {
|
|
3408
|
+
watchPages(compiler) {
|
|
3413
3409
|
const { config, cwd } = this.options;
|
|
3414
3410
|
const pagesDir = join11(cwd, config.router.pagesDir || "src/pages");
|
|
3415
3411
|
if (!existsSync11(pagesDir)) {
|
|
@@ -3431,47 +3427,11 @@ var YwkfGeneratorPlugin = class {
|
|
|
3431
3427
|
}
|
|
3432
3428
|
}, 500);
|
|
3433
3429
|
});
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
});
|
|
3437
|
-
}
|
|
3438
|
-
/**
|
|
3439
|
-
* 监听配置文件变化,重新加载配置并重新生成 .ywkf 文件
|
|
3440
|
-
*/
|
|
3441
|
-
watchConfig() {
|
|
3442
|
-
const { cwd } = this.options;
|
|
3443
|
-
const configPath = findConfigFile(cwd);
|
|
3444
|
-
if (!configPath) {
|
|
3445
|
-
return;
|
|
3446
|
-
}
|
|
3447
|
-
let debounceTimer = null;
|
|
3448
|
-
const watcher = watch(configPath, async () => {
|
|
3449
|
-
if (debounceTimer) {
|
|
3450
|
-
clearTimeout(debounceTimer);
|
|
3451
|
-
}
|
|
3452
|
-
debounceTimer = setTimeout(async () => {
|
|
3453
|
-
try {
|
|
3454
|
-
console.log(`
|
|
3455
|
-
[ywkf] \u68C0\u6D4B\u5230\u914D\u7F6E\u6587\u4EF6\u53D8\u5316\uFF0C\u91CD\u65B0\u751F\u6210 .ywkf \u76EE\u5F55...
|
|
3456
|
-
`);
|
|
3457
|
-
const userConfig = await loadConfigFile(configPath);
|
|
3458
|
-
const newConfig = mergeConfig(userConfig);
|
|
3459
|
-
this.options.config = newConfig;
|
|
3460
|
-
this.options.pluginConfigs = newConfig.plugins;
|
|
3461
|
-
this.resetState();
|
|
3462
|
-
await this.initialize();
|
|
3463
|
-
await this.regenerate();
|
|
3464
|
-
console.log(
|
|
3465
|
-
` [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
|
|
3466
|
-
`
|
|
3467
|
-
);
|
|
3468
|
-
} catch (error) {
|
|
3469
|
-
console.error(` [ywkf] \u914D\u7F6E\u91CD\u8F7D\u5931\u8D25:`, error);
|
|
3470
|
-
}
|
|
3471
|
-
}, 500);
|
|
3472
|
-
});
|
|
3473
|
-
process.on("exit", () => {
|
|
3430
|
+
compiler.hooks.shutdown.tap("YwkfGeneratorPlugin", () => {
|
|
3431
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
3474
3432
|
watcher.close();
|
|
3433
|
+
this.isWatching = false;
|
|
3434
|
+
this.hasGenerated = false;
|
|
3475
3435
|
});
|
|
3476
3436
|
}
|
|
3477
3437
|
};
|
|
@@ -4212,6 +4172,10 @@ function getNetworkAddress(port) {
|
|
|
4212
4172
|
}
|
|
4213
4173
|
return null;
|
|
4214
4174
|
}
|
|
4175
|
+
function displayHost(host) {
|
|
4176
|
+
if (host === "0.0.0.0" || host === "::") return "localhost";
|
|
4177
|
+
return host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
|
4178
|
+
}
|
|
4215
4179
|
var BAR_WIDTH = 30;
|
|
4216
4180
|
function renderBar(percent) {
|
|
4217
4181
|
const filled = Math.round(BAR_WIDTH * percent);
|
|
@@ -4313,7 +4277,7 @@ var DevPrinter = class {
|
|
|
4313
4277
|
* 打印服务器信息面板(dev 模式使用)
|
|
4314
4278
|
*/
|
|
4315
4279
|
printServerInfo() {
|
|
4316
|
-
const localUrl = `http
|
|
4280
|
+
const localUrl = `http://${displayHost(this._host)}:${this.port}/`;
|
|
4317
4281
|
const networkUrl = getNetworkAddress(this.port);
|
|
4318
4282
|
console.log(` ${chalk.bold(">")} Local: ${chalk.cyan(localUrl)}`);
|
|
4319
4283
|
if (networkUrl) {
|
|
@@ -4341,7 +4305,7 @@ function createProgressHandler(printer) {
|
|
|
4341
4305
|
printer.updateProgress(percent, message);
|
|
4342
4306
|
};
|
|
4343
4307
|
}
|
|
4344
|
-
function registerShortcuts(
|
|
4308
|
+
function registerShortcuts(getPrinter, opts) {
|
|
4345
4309
|
if (!process.stdin.isTTY) return;
|
|
4346
4310
|
process.stdin.setEncoding("utf-8");
|
|
4347
4311
|
process.stdin.setRawMode?.(false);
|
|
@@ -4353,10 +4317,10 @@ function registerShortcuts(printer, opts) {
|
|
|
4353
4317
|
buffer = "";
|
|
4354
4318
|
switch (cmd) {
|
|
4355
4319
|
case "h":
|
|
4356
|
-
|
|
4320
|
+
getPrinter().printShortcuts();
|
|
4357
4321
|
break;
|
|
4358
4322
|
case "o": {
|
|
4359
|
-
const url = `http
|
|
4323
|
+
const url = `http://${displayHost(opts.getHost())}:${opts.getPort()}/`;
|
|
4360
4324
|
import("child_process").then((cp) => {
|
|
4361
4325
|
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
4362
4326
|
cp.exec(`${command} ${url}`);
|
|
@@ -4429,7 +4393,7 @@ async function build(options = {}) {
|
|
|
4429
4393
|
let rspackConfig = createRspackConfig(config, cwd, { isDev: false });
|
|
4430
4394
|
rspackConfig = await pluginManager.applyRspackConfigHooks(rspackConfig);
|
|
4431
4395
|
const pluginNames = pluginManager.getPluginNames();
|
|
4432
|
-
const printer = new DevPrinter("
|
|
4396
|
+
const printer = new DevPrinter("127.0.0.1", 0, pluginNames, true);
|
|
4433
4397
|
printer.printBanner();
|
|
4434
4398
|
printer.printBuildStart();
|
|
4435
4399
|
printer.updateProgress(0, "preparing");
|
|
@@ -4438,7 +4402,7 @@ async function build(options = {}) {
|
|
|
4438
4402
|
rspackConfig.stats = "none";
|
|
4439
4403
|
rspackConfig.infrastructureLogging = { level: "none" };
|
|
4440
4404
|
const compiler = rspack4(rspackConfig);
|
|
4441
|
-
const stats = await new Promise((
|
|
4405
|
+
const stats = await new Promise((resolve5, reject) => {
|
|
4442
4406
|
compiler.run((err, stats2) => {
|
|
4443
4407
|
if (err) {
|
|
4444
4408
|
reject(err);
|
|
@@ -4448,13 +4412,13 @@ async function build(options = {}) {
|
|
|
4448
4412
|
reject(new Error("Build failed: no stats available"));
|
|
4449
4413
|
return;
|
|
4450
4414
|
}
|
|
4451
|
-
|
|
4415
|
+
resolve5(stats2);
|
|
4452
4416
|
});
|
|
4453
4417
|
});
|
|
4454
|
-
await new Promise((
|
|
4418
|
+
await new Promise((resolve5, reject) => {
|
|
4455
4419
|
compiler.close((err) => {
|
|
4456
4420
|
if (err) reject(err);
|
|
4457
|
-
else
|
|
4421
|
+
else resolve5();
|
|
4458
4422
|
});
|
|
4459
4423
|
});
|
|
4460
4424
|
const hasErrors = stats.hasErrors();
|
|
@@ -4485,17 +4449,17 @@ import chalk3 from "chalk";
|
|
|
4485
4449
|
// src/cli/port.ts
|
|
4486
4450
|
import net from "net";
|
|
4487
4451
|
function isPortAvailable(port, host) {
|
|
4488
|
-
return new Promise((
|
|
4452
|
+
return new Promise((resolve5) => {
|
|
4489
4453
|
const server = net.createServer();
|
|
4490
4454
|
server.once("error", (err) => {
|
|
4491
4455
|
if (err.code === "EADDRINUSE") {
|
|
4492
|
-
|
|
4456
|
+
resolve5(false);
|
|
4493
4457
|
} else {
|
|
4494
|
-
|
|
4458
|
+
resolve5(false);
|
|
4495
4459
|
}
|
|
4496
4460
|
});
|
|
4497
4461
|
server.once("listening", () => {
|
|
4498
|
-
server.close(() =>
|
|
4462
|
+
server.close(() => resolve5(true));
|
|
4499
4463
|
});
|
|
4500
4464
|
server.listen(port, host);
|
|
4501
4465
|
});
|
|
@@ -4512,88 +4476,212 @@ async function getAvailablePort(preferredPort, host) {
|
|
|
4512
4476
|
);
|
|
4513
4477
|
}
|
|
4514
4478
|
|
|
4479
|
+
// src/cli/restart-watcher.ts
|
|
4480
|
+
import { existsSync as existsSync13, watch as watch2 } from "fs";
|
|
4481
|
+
import { resolve as resolve4 } from "path";
|
|
4482
|
+
function isTriggerFile(filename, mode) {
|
|
4483
|
+
if (!filename) return false;
|
|
4484
|
+
if (CONFIG_FILES.includes(filename)) return true;
|
|
4485
|
+
if (filename === ".env" || filename === ".env.public" || filename === `.env.${mode}`) {
|
|
4486
|
+
return true;
|
|
4487
|
+
}
|
|
4488
|
+
return false;
|
|
4489
|
+
}
|
|
4490
|
+
function normalizeFilename(filename) {
|
|
4491
|
+
if (typeof filename === "string") return filename;
|
|
4492
|
+
if (Buffer.isBuffer(filename)) return filename.toString("utf8");
|
|
4493
|
+
return null;
|
|
4494
|
+
}
|
|
4495
|
+
function watchForRestart(opts) {
|
|
4496
|
+
const { cwd, mode, onChange, debounceMs = 300 } = opts;
|
|
4497
|
+
const watchers = [];
|
|
4498
|
+
let timer = null;
|
|
4499
|
+
const trigger = (filename) => {
|
|
4500
|
+
const name = normalizeFilename(filename);
|
|
4501
|
+
if (!isTriggerFile(name, mode)) return;
|
|
4502
|
+
if (timer) clearTimeout(timer);
|
|
4503
|
+
timer = setTimeout(() => {
|
|
4504
|
+
timer = null;
|
|
4505
|
+
Promise.resolve(onChange()).catch((err) => {
|
|
4506
|
+
console.error("[ywkf] \u81EA\u52A8\u91CD\u542F\u56DE\u8C03\u51FA\u9519:", err);
|
|
4507
|
+
});
|
|
4508
|
+
}, debounceMs);
|
|
4509
|
+
};
|
|
4510
|
+
watchers.push(watch2(cwd, { recursive: false }, (_event, filename) => trigger(filename)));
|
|
4511
|
+
const envDir = resolve4(cwd, "config/env");
|
|
4512
|
+
if (existsSync13(envDir)) {
|
|
4513
|
+
watchers.push(watch2(envDir, { recursive: false }, (_event, filename) => trigger(filename)));
|
|
4514
|
+
}
|
|
4515
|
+
return {
|
|
4516
|
+
close: () => {
|
|
4517
|
+
if (timer) clearTimeout(timer);
|
|
4518
|
+
for (const w of watchers) w.close();
|
|
4519
|
+
}
|
|
4520
|
+
};
|
|
4521
|
+
}
|
|
4522
|
+
|
|
4515
4523
|
// src/cli/dev.ts
|
|
4516
|
-
|
|
4517
|
-
const
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
preloadEnv(cwd, mode, "development");
|
|
4521
|
-
const { config } = await resolveConfig(cwd);
|
|
4522
|
-
loadEnv(config, cwd, mode, "development");
|
|
4523
|
-
const pluginManager = new PluginManager(config, cwd, true);
|
|
4524
|
-
if (config.plugins && config.plugins.length > 0) {
|
|
4525
|
-
await pluginManager.loadPlugins(config.plugins);
|
|
4524
|
+
function restoreEnv(snapshot) {
|
|
4525
|
+
for (const key of Object.keys(process.env)) {
|
|
4526
|
+
if (!(key in snapshot)) {
|
|
4527
|
+
delete process.env[key];
|
|
4526
4528
|
}
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4529
|
+
}
|
|
4530
|
+
for (const key of Object.keys(snapshot)) {
|
|
4531
|
+
process.env[key] = snapshot[key];
|
|
4532
|
+
}
|
|
4533
|
+
}
|
|
4534
|
+
async function loadFullConfig(cwd, mode, envSnapshot, opts = {}) {
|
|
4535
|
+
restoreEnv(envSnapshot);
|
|
4536
|
+
preloadEnv(cwd, mode, "development");
|
|
4537
|
+
const { config } = await resolveConfig(cwd, { fresh: opts.fresh });
|
|
4538
|
+
loadEnv(config, cwd, mode, "development");
|
|
4539
|
+
return config;
|
|
4540
|
+
}
|
|
4541
|
+
async function startDevServer(cwd, config) {
|
|
4542
|
+
const pluginManager = new PluginManager(config, cwd, true);
|
|
4543
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
4544
|
+
await pluginManager.loadPlugins(config.plugins);
|
|
4545
|
+
}
|
|
4546
|
+
await pluginManager.runBeforeDevServer();
|
|
4547
|
+
let rspackConfig = createRspackConfig(config, cwd, { isDev: true });
|
|
4548
|
+
rspackConfig = await pluginManager.applyRspackConfigHooks(rspackConfig);
|
|
4549
|
+
const host = config.dev.host || "127.0.0.1";
|
|
4550
|
+
const preferredPort = config.dev.port || 3e3;
|
|
4551
|
+
const port = await getAvailablePort(preferredPort, host);
|
|
4552
|
+
const pluginNames = pluginManager.getPluginNames();
|
|
4553
|
+
if (port !== preferredPort) {
|
|
4554
|
+
console.log(chalk3.yellow(` Port ${preferredPort} is in use, using ${port} instead.
|
|
4536
4555
|
`));
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
}
|
|
4566
|
-
console.log();
|
|
4556
|
+
}
|
|
4557
|
+
const printer = new DevPrinter(host, port, pluginNames);
|
|
4558
|
+
printer.printBanner();
|
|
4559
|
+
printer.printBuildStart();
|
|
4560
|
+
printer.updateProgress(0, "preparing");
|
|
4561
|
+
rspackConfig.plugins = rspackConfig.plugins || [];
|
|
4562
|
+
rspackConfig.plugins.push(new rspack5.ProgressPlugin(createProgressHandler(printer)));
|
|
4563
|
+
rspackConfig.stats = "none";
|
|
4564
|
+
rspackConfig.infrastructureLogging = { level: "none" };
|
|
4565
|
+
if (rspackConfig.devServer) {
|
|
4566
|
+
const ds = rspackConfig.devServer;
|
|
4567
|
+
const existingClient = ds.client ?? {};
|
|
4568
|
+
ds.client = {
|
|
4569
|
+
...existingClient,
|
|
4570
|
+
logging: "warn",
|
|
4571
|
+
overlay: false,
|
|
4572
|
+
progress: false
|
|
4573
|
+
};
|
|
4574
|
+
}
|
|
4575
|
+
const compiler = rspack5(rspackConfig);
|
|
4576
|
+
compiler.hooks.done.tap("ywkf-dev-printer", (stats) => {
|
|
4577
|
+
const hasErrors = stats.hasErrors();
|
|
4578
|
+
if (hasErrors) {
|
|
4579
|
+
const info = stats.toJson({ errors: true });
|
|
4580
|
+
console.log();
|
|
4581
|
+
console.log(chalk3.red(" Compile error:"));
|
|
4582
|
+
for (const err of info.errors || []) {
|
|
4583
|
+
console.log(chalk3.red(` ${err.message}`));
|
|
4567
4584
|
}
|
|
4568
|
-
|
|
4569
|
-
}
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4585
|
+
console.log();
|
|
4586
|
+
}
|
|
4587
|
+
printer.printBuildDone(hasErrors);
|
|
4588
|
+
});
|
|
4589
|
+
compiler.hooks.invalid.tap("ywkf-dev-printer", () => {
|
|
4590
|
+
printer.markRebuildStart();
|
|
4591
|
+
printer.updateProgress(0, "rebuilding");
|
|
4592
|
+
});
|
|
4593
|
+
const devServerOptions = {
|
|
4594
|
+
...rspackConfig.devServer || {},
|
|
4595
|
+
host,
|
|
4596
|
+
port,
|
|
4597
|
+
setupExitSignals: false
|
|
4598
|
+
};
|
|
4599
|
+
const server = new RspackDevServer(devServerOptions, compiler);
|
|
4600
|
+
await server.start();
|
|
4601
|
+
await pluginManager.runAfterDevServer({ host, port });
|
|
4602
|
+
let closed = false;
|
|
4603
|
+
const close = async () => {
|
|
4604
|
+
if (closed) return;
|
|
4605
|
+
closed = true;
|
|
4606
|
+
await server.stop();
|
|
4607
|
+
await new Promise((resolve5, reject) => {
|
|
4608
|
+
compiler.close((err) => {
|
|
4609
|
+
if (err) reject(err);
|
|
4610
|
+
else resolve5();
|
|
4611
|
+
});
|
|
4573
4612
|
});
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4613
|
+
};
|
|
4614
|
+
return { printer, host, port, close };
|
|
4615
|
+
}
|
|
4616
|
+
async function dev(options = {}) {
|
|
4617
|
+
const cwd = options.cwd || process.cwd();
|
|
4618
|
+
const mode = options.mode || "development";
|
|
4619
|
+
const envSnapshot = { ...process.env };
|
|
4620
|
+
try {
|
|
4621
|
+
const config = await loadFullConfig(cwd, mode, envSnapshot);
|
|
4622
|
+
let current = await startDevServer(cwd, config);
|
|
4623
|
+
let shuttingDown = false;
|
|
4624
|
+
const shutdown = async () => {
|
|
4625
|
+
if (shuttingDown) return;
|
|
4626
|
+
shuttingDown = true;
|
|
4627
|
+
await current.close();
|
|
4628
|
+
process.exit(0);
|
|
4578
4629
|
};
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
registerShortcuts(printer, {
|
|
4583
|
-
port,
|
|
4630
|
+
registerShortcuts(() => current.printer, {
|
|
4631
|
+
getPort: () => current.port,
|
|
4632
|
+
getHost: () => current.host,
|
|
4584
4633
|
onQuit: async () => {
|
|
4585
4634
|
console.log(chalk3.gray("\n Shutting down...\n"));
|
|
4586
|
-
await
|
|
4587
|
-
process.exit(0);
|
|
4635
|
+
await shutdown();
|
|
4588
4636
|
}
|
|
4589
4637
|
});
|
|
4590
4638
|
const signals = ["SIGINT", "SIGTERM"];
|
|
4591
4639
|
for (const signal of signals) {
|
|
4592
|
-
process.on(signal,
|
|
4593
|
-
|
|
4594
|
-
process.exit(0);
|
|
4640
|
+
process.on(signal, () => {
|
|
4641
|
+
void shutdown();
|
|
4595
4642
|
});
|
|
4596
4643
|
}
|
|
4644
|
+
let isRestarting = false;
|
|
4645
|
+
let pending = false;
|
|
4646
|
+
watchForRestart({
|
|
4647
|
+
cwd,
|
|
4648
|
+
mode,
|
|
4649
|
+
onChange: async () => {
|
|
4650
|
+
if (isRestarting) {
|
|
4651
|
+
pending = true;
|
|
4652
|
+
return;
|
|
4653
|
+
}
|
|
4654
|
+
isRestarting = true;
|
|
4655
|
+
try {
|
|
4656
|
+
do {
|
|
4657
|
+
pending = false;
|
|
4658
|
+
console.log(chalk3.cyan("\n \u27F3 \u68C0\u6D4B\u5230\u914D\u7F6E\u53D8\u66F4\uFF0C\u6B63\u5728\u91CD\u542F dev server...\n"));
|
|
4659
|
+
let nextConfig;
|
|
4660
|
+
try {
|
|
4661
|
+
nextConfig = await loadFullConfig(cwd, mode, envSnapshot, { fresh: true });
|
|
4662
|
+
} catch (error) {
|
|
4663
|
+
console.error(
|
|
4664
|
+
chalk3.red(" \u2716 \u914D\u7F6E\u52A0\u8F7D\u5931\u8D25\uFF0C\u4FDD\u6301\u5F53\u524D dev server \u8FD0\u884C\uFF08\u4FEE\u6B63\u540E\u4FDD\u5B58\u53EF\u91CD\u8BD5\uFF09:")
|
|
4665
|
+
);
|
|
4666
|
+
console.error(error);
|
|
4667
|
+
restoreEnv(envSnapshot);
|
|
4668
|
+
continue;
|
|
4669
|
+
}
|
|
4670
|
+
try {
|
|
4671
|
+
await current.close();
|
|
4672
|
+
current = await startDevServer(cwd, nextConfig);
|
|
4673
|
+
} catch (error) {
|
|
4674
|
+
console.error(
|
|
4675
|
+
chalk3.red(" \u2716 dev server \u91CD\u542F\u5931\u8D25\uFF0C\u5F53\u524D\u670D\u52A1\u4E0D\u53EF\u7528\uFF0C\u8BF7\u4FEE\u6B63\u540E\u4FDD\u5B58\u91CD\u8BD5:")
|
|
4676
|
+
);
|
|
4677
|
+
console.error(error);
|
|
4678
|
+
}
|
|
4679
|
+
} while (pending);
|
|
4680
|
+
} finally {
|
|
4681
|
+
isRestarting = false;
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
});
|
|
4597
4685
|
} catch (error) {
|
|
4598
4686
|
console.error();
|
|
4599
4687
|
console.error(chalk3.red(" \u2716 Dev server failed to start"));
|
|
@@ -4603,7 +4691,7 @@ async function dev(options = {}) {
|
|
|
4603
4691
|
}
|
|
4604
4692
|
|
|
4605
4693
|
// src/router/plugin.ts
|
|
4606
|
-
import { existsSync as
|
|
4694
|
+
import { existsSync as existsSync14, watch as watch3 } from "fs";
|
|
4607
4695
|
import { join as join14 } from "path";
|
|
4608
4696
|
var ConventionalRoutePlugin = class {
|
|
4609
4697
|
options;
|
|
@@ -4623,7 +4711,7 @@ var ConventionalRoutePlugin = class {
|
|
|
4623
4711
|
callback();
|
|
4624
4712
|
});
|
|
4625
4713
|
if (this.options.watch && !this.isWatching) {
|
|
4626
|
-
this.watchPages();
|
|
4714
|
+
this.watchPages(compiler);
|
|
4627
4715
|
}
|
|
4628
4716
|
}
|
|
4629
4717
|
/**
|
|
@@ -4658,13 +4746,13 @@ var ConventionalRoutePlugin = class {
|
|
|
4658
4746
|
/**
|
|
4659
4747
|
* 监听页面目录变化
|
|
4660
4748
|
*/
|
|
4661
|
-
watchPages() {
|
|
4662
|
-
if (!
|
|
4749
|
+
watchPages(compiler) {
|
|
4750
|
+
if (!existsSync14(this.options.pagesDir)) {
|
|
4663
4751
|
return;
|
|
4664
4752
|
}
|
|
4665
4753
|
this.isWatching = true;
|
|
4666
4754
|
let debounceTimer = null;
|
|
4667
|
-
const watcher =
|
|
4755
|
+
const watcher = watch3(this.options.pagesDir, { recursive: true }, (_eventType, filename) => {
|
|
4668
4756
|
if (!filename?.match(/\.(tsx?|jsx?)$/)) {
|
|
4669
4757
|
return;
|
|
4670
4758
|
}
|
|
@@ -4676,8 +4764,12 @@ var ConventionalRoutePlugin = class {
|
|
|
4676
4764
|
this.generateRoutes();
|
|
4677
4765
|
}, 500);
|
|
4678
4766
|
});
|
|
4679
|
-
|
|
4767
|
+
compiler.hooks.shutdown.tap("ConventionalRoutePlugin", () => {
|
|
4768
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
4680
4769
|
watcher.close();
|
|
4770
|
+
this.isWatching = false;
|
|
4771
|
+
this.hasGenerated = false;
|
|
4772
|
+
this.lastGeneratedContent = "";
|
|
4681
4773
|
});
|
|
4682
4774
|
}
|
|
4683
4775
|
};
|