c0db298449
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 5m12s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 5m29s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 4m46s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m43s
Project CI / Backend tests (pull_request) Failing after 11s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 4m38s
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m31s
Project CI / AI game creator shell web tests (pull_request) Failing after 4m35s
Project CI / Frontend tests (pull_request) Successful in 6m38s
Project CI / Native shell tests (pull_request) Successful in 8m25s
在 Vite 中排除 src-tauri/target,保留业务源码与共享组件热更新。 增加实际 Vite watcher 回归,验证构建目录排除及源码变更通知。 同步开发运维文档和共享排障记录,关联 Issue #324。
114 lines
4.1 KiB
JavaScript
114 lines
4.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { dirname, join } from 'node:path';
|
|
import { test } from 'node:test';
|
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
import { createServer, loadConfigFromFile, normalizePath } from 'vite';
|
|
|
|
test(
|
|
'AGC 排除 Rust 构建目录且保留源码与共享组件监听',
|
|
{ timeout: 30_000 },
|
|
async () => {
|
|
const loaded = await loadConfigFromFile(
|
|
{ command: 'serve', mode: 'development' },
|
|
fileURLToPath(new URL('../vite.config.ts', import.meta.url)),
|
|
);
|
|
assert.ok(loaded);
|
|
assert.notEqual(loaded.config.server?.watch, null);
|
|
assert.notEqual(loaded.config.server?.hmr, false);
|
|
assert.ok(
|
|
[loaded.config.server?.watch?.ignored]
|
|
.flat()
|
|
.includes('**/src-tauri/target/**'),
|
|
);
|
|
|
|
const fixture = await mkdtemp(join(tmpdir(), 'agc-vite-watch-'));
|
|
const root = join(fixture, 'apps', 'ai-game-creator-shell');
|
|
const source = join(root, 'src', 'main.js');
|
|
const css = join(root, 'src', 'styles.css');
|
|
const shared = join(fixture, 'packages', 'shared', 'src', 'component.js');
|
|
const target = join(root, 'src-tauri', 'target');
|
|
const artifact = join(target, 'debug', 'incremental', 'cache.bin');
|
|
let server;
|
|
try {
|
|
for (const file of [source, css, shared, artifact]) {
|
|
await mkdir(dirname(file), { recursive: true });
|
|
await writeFile(
|
|
file,
|
|
file === css ? 'body { color: red; }' : 'export default 1;',
|
|
);
|
|
}
|
|
// 使用真实 Vite watcher 和实际配置,仅将扫描根替换为小型夹具;
|
|
// 不加载业务插件、后端或原生窗口,也不扫描开发机上的大型 target。
|
|
server = await createServer({
|
|
configFile: false,
|
|
envFile: false,
|
|
root,
|
|
logLevel: 'silent',
|
|
server: {
|
|
watch: loaded.config.server?.watch,
|
|
middlewareMode: true,
|
|
hmr: false,
|
|
fs: { allow: [fixture] },
|
|
},
|
|
optimizeDeps: { noDiscovery: true, include: [] },
|
|
});
|
|
const waitForWatchedFile = async (file) => {
|
|
const normalized = normalizePath(file);
|
|
for (let attempt = 0; attempt < 100; attempt += 1) {
|
|
if (
|
|
Object.entries(server.watcher.getWatched()).some(
|
|
([directory, names]) =>
|
|
names.some(
|
|
(name) => normalizePath(join(directory, name)) === normalized,
|
|
),
|
|
)
|
|
)
|
|
return;
|
|
await delay(50);
|
|
}
|
|
assert.fail(`源码必须仍被监听:${normalized}`);
|
|
};
|
|
await waitForWatchedFile(source);
|
|
|
|
// 真实模块转换应将 root 外的共享源码加入监听。
|
|
await server.transformRequest(`/@fs/${normalizePath(shared)}`);
|
|
for (const file of [source, css, shared]) {
|
|
const normalized = normalizePath(file);
|
|
await waitForWatchedFile(file);
|
|
const changed = new Promise((resolve, reject) => {
|
|
const timer = setTimeout(() => {
|
|
server.watcher.off('change', onChange);
|
|
reject(new Error(`未收到源码变更:${normalized}`));
|
|
}, 5_000);
|
|
function onChange(path) {
|
|
if (normalizePath(path) !== normalized) return;
|
|
clearTimeout(timer);
|
|
server.watcher.off('change', onChange);
|
|
resolve();
|
|
}
|
|
server.watcher.on('change', onChange);
|
|
});
|
|
await writeFile(
|
|
file,
|
|
file === css ? 'body { color: blue; }' : 'export default 2;',
|
|
);
|
|
await changed;
|
|
}
|
|
const targetPath = normalizePath(target);
|
|
const targetDirectories = Object.keys(server.watcher.getWatched())
|
|
.map(normalizePath)
|
|
.filter(
|
|
(path) => path === targetPath || path.startsWith(`${targetPath}/`),
|
|
);
|
|
assert.deepEqual(targetDirectories, [], 'Rust target 不应创建目录监听器');
|
|
} finally {
|
|
await server?.close();
|
|
await rm(fixture, { recursive: true, force: true });
|
|
}
|
|
},
|
|
);
|