收紧宿主壳结构门禁
补齐桌面壳单端 Rust 根目录和分层文件清单检查 将移动壳 src/env.d.ts 纳入根级结构门禁和文档反查 同步宿主壳结构门禁的架构文档与共享记忆
This commit is contained in:
@@ -860,6 +860,36 @@ function assertSameList(actual, expected, label) {
|
||||
}
|
||||
}
|
||||
|
||||
function readDirectoryEntryList(directory, label) {
|
||||
const entries = fs
|
||||
.readdirSync(directory, { withFileTypes: true })
|
||||
.map((entry) => {
|
||||
if (entry.isFile()) {
|
||||
return `file:${entry.name}`;
|
||||
}
|
||||
if (entry.isDirectory()) {
|
||||
return `dir:${entry.name}`;
|
||||
}
|
||||
throw new Error(`${label} must not contain special entries: ${entry.name}`);
|
||||
})
|
||||
.sort();
|
||||
if (entries.length === 0) {
|
||||
throw new Error(`${label} must not be empty`);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
function readDirectoryFileList(directory, label) {
|
||||
const files = [];
|
||||
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
||||
if (!entry.isFile()) {
|
||||
throw new Error(`${label} must not contain nested entries: ${entry.name}`);
|
||||
}
|
||||
files.push(entry.name);
|
||||
}
|
||||
return files.sort();
|
||||
}
|
||||
|
||||
function extractTauriBuildCommands(source) {
|
||||
const match = source.match(/\.commands\(\s*&\[\s*([^\]]*?)\s*\]\s*\)/);
|
||||
if (!match) {
|
||||
@@ -1465,28 +1495,40 @@ const sharedTauriCommand = extractTsStringConst(
|
||||
'HOST_BRIDGE_TAURI_COMMAND',
|
||||
);
|
||||
const allowedTauriCommands = [sharedTauriCommand];
|
||||
const expectedRustRootEntries = [
|
||||
'dir:host_bridge',
|
||||
'dir:shell',
|
||||
'file:app.rs',
|
||||
'file:main.rs',
|
||||
];
|
||||
const expectedRustHostBridgeFiles = [
|
||||
'capabilities.rs',
|
||||
'dispatch.rs',
|
||||
'files.rs',
|
||||
'mod.rs',
|
||||
'protocol.rs',
|
||||
'share.rs',
|
||||
];
|
||||
const expectedRustShellFiles = [
|
||||
'deep_link.rs',
|
||||
'events.rs',
|
||||
'file_drop.rs',
|
||||
'lifecycle.rs',
|
||||
'menu.rs',
|
||||
'mod.rs',
|
||||
'navigation.rs',
|
||||
'network.rs',
|
||||
'runtime.rs',
|
||||
'tray.rs',
|
||||
'url.rs',
|
||||
'webview.rs',
|
||||
'window_state.rs',
|
||||
];
|
||||
const requiredRustHostModules = [
|
||||
'app.rs',
|
||||
'host_bridge/capabilities.rs',
|
||||
'host_bridge/dispatch.rs',
|
||||
'host_bridge/files.rs',
|
||||
'host_bridge/mod.rs',
|
||||
'host_bridge/protocol.rs',
|
||||
'host_bridge/share.rs',
|
||||
...expectedRustHostBridgeFiles.map((fileName) => `host_bridge/${fileName}`),
|
||||
'main.rs',
|
||||
'shell/deep_link.rs',
|
||||
'shell/events.rs',
|
||||
'shell/file_drop.rs',
|
||||
'shell/lifecycle.rs',
|
||||
'shell/menu.rs',
|
||||
'shell/mod.rs',
|
||||
'shell/navigation.rs',
|
||||
'shell/network.rs',
|
||||
'shell/runtime.rs',
|
||||
'shell/tray.rs',
|
||||
'shell/url.rs',
|
||||
'shell/webview.rs',
|
||||
'shell/window_state.rs',
|
||||
...expectedRustShellFiles.map((fileName) => `shell/${fileName}`),
|
||||
];
|
||||
const requiredRustHostSnippets = [
|
||||
'tauri_plugin_single_instance::init',
|
||||
@@ -1666,6 +1708,27 @@ assertSameList(
|
||||
['host_bridge_request'],
|
||||
'shared Tauri HostBridge command',
|
||||
);
|
||||
assertSameList(
|
||||
readDirectoryEntryList(rustSourceDir, 'desktop shell Rust root entries'),
|
||||
expectedRustRootEntries,
|
||||
'desktop shell Rust root entries',
|
||||
);
|
||||
assertSameList(
|
||||
readDirectoryFileList(
|
||||
new URL('host_bridge/', rustSourceDir),
|
||||
'desktop shell host_bridge Rust files',
|
||||
),
|
||||
expectedRustHostBridgeFiles,
|
||||
'desktop shell host_bridge Rust files',
|
||||
);
|
||||
assertSameList(
|
||||
readDirectoryFileList(
|
||||
new URL('shell/', rustSourceDir),
|
||||
'desktop shell shell Rust files',
|
||||
),
|
||||
expectedRustShellFiles,
|
||||
'desktop shell shell Rust files',
|
||||
);
|
||||
assertSameList(
|
||||
collectRustSourceRelativePaths(rustHostSourceFiles),
|
||||
requiredRustHostModules,
|
||||
|
||||
@@ -2538,7 +2538,7 @@
|
||||
## 2026-06-19 三端宿主桥接层结构文档反查
|
||||
|
||||
- 背景:三端桥接层已经拆出移动 `scanner.ts`、桌面 `menu.rs`、`window_state.rs` 等职责文件,但如果只更新代码和目录门禁,`宿主壳能力统一协议` 与 `ExpoReactNative与Tauri宿主壳方案` 可能继续保留旧清单,后续开发者按文档扩展时仍会把能力放回错误 owner。
|
||||
- 决策:`scripts/check-native-shells.mjs` 的三端桥接层目录清单同时作为文档反查来源。根级门禁会确认两份前端架构文档都按完整相对路径列出微信桥接层、微信 shell、微信页面包装层、移动桥接层、移动 shell、桌面入口、桌面桥接层和桌面 shell 的当前生产文件,并拒绝这些目录出现未登记子目录或生产入口;`apps/mobile-shell/scripts/check-config.mjs` 必须用精确移动壳源码清单拦截 `src/host-bridge` / `src/shell` 单端结构漂移,`apps/desktop-shell/scripts/check-config.mjs` 必须用精确 Rust 模块清单拦截桌面壳单端结构漂移。新增、删除或改名这些职责文件时,必须同时更新脚本清单、两份架构文档、单端门禁和相关实现,不允许只改一端。
|
||||
- 决策:`scripts/check-native-shells.mjs` 的三端桥接层目录清单同时作为文档反查来源。根级门禁会确认两份前端架构文档都按完整相对路径列出微信桥接层、微信 shell、微信页面包装层、移动源码根 `env.d.ts`、移动桥接层、移动 shell、桌面入口、桌面桥接层和桌面 shell 的当前生产文件,并拒绝这些目录出现未登记子目录或生产入口;`apps/mobile-shell/scripts/check-config.mjs` 必须用精确移动壳源码清单拦截 `src/host-bridge` / `src/shell` 和 `src` 根入口单端结构漂移,`apps/desktop-shell/scripts/check-config.mjs` 必须用 Rust 根目录 entry、`host_bridge/` 文件清单、`shell/` 文件清单和 Rust 模块清单共同拦截桌面壳单端结构漂移。新增、删除或改名这些职责文件时,必须同时更新脚本清单、两份架构文档、单端门禁和相关实现,不允许只改一端。
|
||||
- 影响范围:`scripts/check-native-shells.mjs`、`docs/【前端架构】宿主壳能力统一协议-2026-06-17.md`、`docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md`、三端宿主壳源码布局。
|
||||
- 验证方式:`npm run check:native-shells`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -155,6 +155,11 @@ const expectedMobileHostBridgeFiles = [
|
||||
'scanner.ts',
|
||||
'share.ts',
|
||||
];
|
||||
const expectedMobileSrcRootEntries = [
|
||||
'dir:host-bridge',
|
||||
'dir:shell',
|
||||
'file:env.d.ts',
|
||||
];
|
||||
const expectedMobileShellFiles = [
|
||||
'QrScannerOverlay.tsx',
|
||||
'ShellApp.tsx',
|
||||
@@ -225,6 +230,10 @@ const documentedShellLayerGroups = [
|
||||
.map((fileName) => `miniprogram/pages/${route}/${fileName}`),
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'mobile src root entries',
|
||||
files: ['apps/mobile-shell/src/env.d.ts'],
|
||||
},
|
||||
{
|
||||
label: 'mobile host bridge files',
|
||||
files: expectedMobileHostBridgeFiles
|
||||
@@ -1299,6 +1308,12 @@ function assertHostBridgeLayerLayout() {
|
||||
}
|
||||
}
|
||||
|
||||
assertSameList(
|
||||
readDirectoryEntryList('apps/mobile-shell/src', 'mobile shell src root entries'),
|
||||
expectedMobileSrcRootEntries,
|
||||
'mobile shell src root entries',
|
||||
);
|
||||
|
||||
assertSameList(
|
||||
readDirectoryFileList(
|
||||
'apps/mobile-shell/src/host-bridge',
|
||||
|
||||
Reference in New Issue
Block a user