锁定微信壳页面包装层结构
原生壳门禁新增微信页面目录和页面文件清单反查 宿主壳方案文档同步微信页面包装层和微信能力清单 共享记忆补充三端壳结构和能力文档反查口径
This commit is contained in:
@@ -2453,7 +2453,7 @@
|
||||
## 2026-06-19 原生壳 capability profile 来源收口
|
||||
|
||||
- 背景:Expo 移动壳、Tauri 桌面壳和方案文档都需要维护真实 capability 子集;如果移动端源码、桌面 Rust 镜像和文档各自手写完整清单,后续新增能力时容易出现入口 URL、`host.getRuntime` 回包、文档和门禁漂移。
|
||||
- 决策:`packages/shared/src/contracts/hostBridge.ts` 中的 `HOST_BRIDGE_WECHAT_MINI_PROGRAM_CAPABILITIES`、`HOST_BRIDGE_EXPO_MOBILE_BASE_CAPABILITIES`、`HOST_BRIDGE_EXPO_MOBILE_IOS_CAPABILITIES` 和 `HOST_BRIDGE_TAURI_DESKTOP_CAPABILITIES` 是三端宿主壳 capability profile 来源。Expo 移动壳只通过 `apps/mobile-shell/src/host-bridge/capabilities.ts` 引用共享 profile 并选择平台差异;微信小程序 `miniprogram/host-bridge/protocol.js` 和 Tauri 桌面壳 `capabilities.rs` 仍保留运行时镜像,但 `miniprogram/host-bridge/protocol.test.js`、`apps/desktop-shell/scripts/check-config.mjs` 和 `npm run check:native-shells` 必须反查对应共享 profile。新增 capability 必须先进入共享白名单和对应平台 profile,再补真实壳实现、H5 fallback、测试和文档。
|
||||
- 决策:`packages/shared/src/contracts/hostBridge.ts` 中的 `HOST_BRIDGE_WECHAT_MINI_PROGRAM_CAPABILITIES`、`HOST_BRIDGE_EXPO_MOBILE_BASE_CAPABILITIES`、`HOST_BRIDGE_EXPO_MOBILE_IOS_CAPABILITIES` 和 `HOST_BRIDGE_TAURI_DESKTOP_CAPABILITIES` 是三端宿主壳 capability profile 来源。Expo 移动壳只通过 `apps/mobile-shell/src/host-bridge/capabilities.ts` 引用共享 profile 并选择平台差异;微信小程序 `miniprogram/host-bridge/protocol.js` 和 Tauri 桌面壳 `capabilities.rs` 仍保留运行时镜像,但 `miniprogram/host-bridge/protocol.test.js`、`apps/desktop-shell/scripts/check-config.mjs` 和 `npm run check:native-shells` 必须反查对应共享 profile。根级门禁同时反查宿主壳方案文档里的微信 / Expo / Tauri 能力清单,新增 capability 必须先进入共享白名单和对应平台 profile,再补真实壳实现、H5 fallback、测试和文档。
|
||||
- 影响范围:`packages/shared/src/contracts/hostBridge.ts`、`miniprogram/host-bridge/protocol.js`、`miniprogram/host-bridge/protocol.test.js`、`apps/mobile-shell/src/host-bridge/capabilities.ts`、`apps/mobile-shell/scripts/check-config.mjs`、`apps/desktop-shell/scripts/check-config.mjs`、`scripts/check-native-shells.mjs`、HostBridge 方案文档。
|
||||
- 验证方式:`npm run check:native-shells`、`npm run mobile-shell:typecheck`、`npm run desktop-shell:typecheck`、`npm run test -- packages/shared/src/contracts/hostBridge.test.ts miniprogram/host-bridge/protocol.test.js`、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
@@ -2523,7 +2523,7 @@
|
||||
## 2026-06-19 三端宿主桥接层结构文档反查
|
||||
|
||||
- 背景:三端桥接层已经拆出移动 `scanner.ts`、桌面 `menu.rs`、`window_state.rs` 等职责文件,但如果只更新代码和目录门禁,`宿主壳能力统一协议` 与 `ExpoReactNative与Tauri宿主壳方案` 可能继续保留旧清单,后续开发者按文档扩展时仍会把能力放回错误 owner。
|
||||
- 决策:`scripts/check-native-shells.mjs` 的三端桥接层目录清单同时作为文档反查来源。根级门禁会确认两份前端架构文档都显式列出微信桥接层、微信 shell、移动桥接层、移动 shell、桌面入口、桌面桥接层和桌面 shell 的当前生产文件;新增、删除或改名这些职责文件时,必须同时更新脚本清单、两份架构文档和相关实现,不允许只改一端。
|
||||
- 决策:`scripts/check-native-shells.mjs` 的三端桥接层目录清单同时作为文档反查来源。根级门禁会确认两份前端架构文档都显式列出微信桥接层、微信 shell、微信页面包装层、移动桥接层、移动 shell、桌面入口、桌面桥接层和桌面 shell 的当前生产文件;新增、删除或改名这些职责文件时,必须同时更新脚本清单、两份架构文档和相关实现,不允许只改一端。
|
||||
- 影响范围:`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`。
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ src/
|
||||
|
||||
三端宿主桥接层按职责对齐命名:微信小程序页面路由仍保留在 `miniprogram/pages/*`,`miniprogram/host-bridge/protocol.js` 只沉淀微信壳能力、页面 URL、结果 hash / storage key 和分享消息类型等常量,`dispatch.js` 只作为 `protocol`、`webView`、`payment`、`shareGrid`、`subscribeMessage` 的薄索引,真实协议归一、支付 / 订阅 / 分享结果编解码仍分别在 `webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,不把微信小程序硬改成 Expo / Tauri 的 request 总线;Page 生命周期、`wx.*` 容器调用、WebView 容器行为和页面工厂统一放在 `miniprogram/shell/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`,页面入口只做 `Page(createWechat...Page())` 装配。Expo 移动壳使用 `apps/mobile-shell/src/host-bridge/protocol.ts` 承接 envelope、request 校验、ok / failure 响应和 replay 基础类型,`capabilities.ts` 只引用共享 HostBridge capability profile 并选择 iOS 差异能力,`dispatch.ts` 承接 method 分发和宿主能力调用,`files.ts` / `share.ts` / `scanner.ts` 分别承接文件、分享和扫码能力,`bridge.ts` 只作为 WebView message 入口、request id replay 编排和对外 facade;`apps/mobile-shell/App.tsx` 只装配 `apps/mobile-shell/src/shell/ShellApp.tsx`,由 `apps/mobile-shell/src/shell/*.ts(x)` 承接 WebView 容器、URL、导航、网络、生命周期、安全区、扫码 overlay 和 WebView policy。Tauri 桌面壳使用 `apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs` 承接 envelope、method 白名单、request 校验和 replay 状态,`capabilities.rs` 承接共享桌面 capability profile 的 Rust 运行时镜像,`dispatch.rs` 承接 method 分发和宿主能力调用,`files.rs` / `share.rs` 分别承接文件和分享能力,`mod.rs` 只保留模块声明、必要 re-export、`host_bridge_request` command facade 和 replay 编排;`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs`、`menu.rs`、`window_state.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘、应用菜单、窗口状态持久化和 WebView 门面,`apps/desktop-shell/src-tauri/src/app.rs` 承接 Tauri builder / plugin / window 装配,`main.rs` 只保留薄入口并调用 `app::run()`。
|
||||
|
||||
当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;移动桥接层 `bridge.ts`、`capabilities.ts`、`dispatch.ts`、`files.ts`、`protocol.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `capabilities.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`protocol.rs`、`share.rs`;桌面 shell 层 `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`。
|
||||
当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信页面包装层 `share-grid/index.js`、`share-grid/index.json`、`share-grid/index.wxml`、`share-grid/index.wxss`、`subscribe-message/index.js`、`subscribe-message/index.json`、`subscribe-message/index.wxml`、`subscribe-message/index.wxss`、`web-view/index.js`、`web-view/index.json`、`web-view/index.wxml`、`web-view/index.wxss`、`wechat-pay/index.js`、`wechat-pay/index.json`、`wechat-pay/index.wxml`、`wechat-pay/index.wxss`;移动桥接层 `bridge.ts`、`capabilities.ts`、`dispatch.ts`、`files.ts`、`protocol.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `capabilities.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`protocol.rs`、`share.rs`;桌面 shell 层 `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`。
|
||||
|
||||
## HostBridge 消息协议
|
||||
|
||||
@@ -281,6 +281,8 @@ GameBridge 禁止:
|
||||
|
||||
当前状态:已新增 `src/services/host-bridge/nativeAppHostBridge.ts`,支持 React Native WebView `postMessage` 和 Tauri `invoke('host_bridge_request')` 两种真实 transport。两条 transport 都会按 `timeoutMs` 在 H5 侧释放请求,超时统一抛出 `timeout / host_bridge_timeout`。登录、支付和原生页跳转如果宿主明确返回 `unsupported_method` / `unsupported_capability`,H5 回退到原有路径;生产代码不返回 mock 成功。
|
||||
|
||||
2026-06-19 追加:微信小程序壳当前真实能力完整清单为 `auth.requestLogin`、`payment.request`、`share.setTarget` 和 `share.open`。
|
||||
|
||||
### Phase 2:Expo 移动壳 MVP
|
||||
|
||||
- 新增 `apps/mobile-shell/`。
|
||||
|
||||
@@ -39,7 +39,7 @@ AI H5 sandbox
|
||||
|
||||
桥接层文件结构按宿主统一为“协议 / 能力清单 / 分发 / 宿主容器行为”四类职责。微信小程序不硬套 Expo / Tauri 的 request 总线:`miniprogram/host-bridge/protocol.js` 只沉淀微信壳能力、页面 URL、结果 hash / storage key 和分享消息类型等常量,`dispatch.js` 只作为 `protocol`、`webView`、`payment`、`shareGrid`、`subscribeMessage` 的薄索引,真实协议归一、支付 / 订阅 / 分享结果编解码仍分别放在 `webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js`;`miniprogram/shell/webView.js`、`payment.js`、`shareGrid.js`、`subscribeMessage.js` 承接 Page 生命周期、`wx.*` 容器调用、WebView 容器行为、支付页和订阅页装配,页面目录只保留 `Page(createWechat...Page())` 装配。Expo 移动壳使用 `apps/mobile-shell/src/host-bridge/protocol.ts` 承接 envelope、request 校验、ok / failure 响应和 replay 基础类型,`capabilities.ts` 只引用共享 HostBridge capability profile 并选择 iOS 差异能力,`dispatch.ts` 承接 method 分发和宿主能力调用,`files.ts` / `share.ts` / `scanner.ts` 分别承接文件、分享和扫码能力,`bridge.ts` 只作为 WebView message 入口、request id replay 编排和对外 facade;`apps/mobile-shell/App.tsx` 只装配 `apps/mobile-shell/src/shell/ShellApp.tsx`,由 `apps/mobile-shell/src/shell/*.ts(x)` 承接 WebView 容器、URL、导航、网络、生命周期、安全区、扫码 overlay 和 WebView policy。Tauri 桌面壳使用 `apps/desktop-shell/src-tauri/src/host_bridge/protocol.rs` 承接 envelope、method 白名单、request 校验和 replay 状态,`capabilities.rs` 承接共享桌面 capability profile 的 Rust 运行时镜像,`dispatch.rs` 承接 method 分发和宿主能力调用,`files.rs` / `share.rs` 分别承接文件和分享能力,`mod.rs` 只保留模块声明、必要 re-export、`host_bridge_request` command facade 和 replay 编排;`apps/desktop-shell/src-tauri/src/shell/runtime.rs`、`url.rs`、`navigation.rs`、`network.rs`、`lifecycle.rs`、`file_drop.rs`、`events.rs`、`deep_link.rs`、`tray.rs`、`menu.rs`、`window_state.rs` 和 `webview.rs` 分别承接运行态、入口 URL、导航 / 下载、网络、生命周期、拖拽图片、HostBridge 事件注入、深链、托盘、应用菜单、窗口状态持久化和 WebView 门面,`apps/desktop-shell/src-tauri/src/app.rs` 承接 Tauri builder / plugin / window 装配,`main.rs` 只保留薄入口并调用 `app::run()`。`npm run check:native-shells` 会检查这些目录清单。
|
||||
|
||||
当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;移动桥接层 `bridge.ts`、`capabilities.ts`、`dispatch.ts`、`files.ts`、`protocol.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `capabilities.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`protocol.rs`、`share.rs`;桌面 shell 层 `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`。
|
||||
当前 `npm run check:native-shells` 锁定的生产文件清单为:微信桥接层 `dispatch.js`、`payment.js`、`protocol.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信 shell 层 `payment.js`、`shareGrid.js`、`subscribeMessage.js`、`webView.js`;微信页面包装层 `share-grid/index.js`、`share-grid/index.json`、`share-grid/index.wxml`、`share-grid/index.wxss`、`subscribe-message/index.js`、`subscribe-message/index.json`、`subscribe-message/index.wxml`、`subscribe-message/index.wxss`、`web-view/index.js`、`web-view/index.json`、`web-view/index.wxml`、`web-view/index.wxss`、`wechat-pay/index.js`、`wechat-pay/index.json`、`wechat-pay/index.wxml`、`wechat-pay/index.wxss`;移动桥接层 `bridge.ts`、`capabilities.ts`、`dispatch.ts`、`files.ts`、`protocol.ts`、`scanner.ts`、`share.ts`;移动 shell 层 `QrScannerOverlay.tsx`、`ShellApp.tsx`、`deepLink.ts`、`lifecycle.ts`、`loadFailure.ts`、`navigation.ts`、`network.ts`、`runtime.ts`、`safeArea.ts`、`url.ts`、`webViewGlobals.d.ts`、`webViewHistory.ts`、`webViewPolicy.ts`;桌面入口 `app.rs`、`main.rs`;桌面桥接层 `capabilities.rs`、`dispatch.rs`、`files.rs`、`mod.rs`、`protocol.rs`、`share.rs`;桌面 shell 层 `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`。
|
||||
|
||||
Tauri 桌面壳启动时必须按 `label="main"` 解析 `tauri.conf.json` 主窗口配置,并在创建 WebView 前补写 `native_app`、`tauri_desktop` 和真实 capability 上下文;缺少主窗口配置时启动直接失败,不允许按 `windows[0]` 兜底或无主窗口静默运行。
|
||||
|
||||
|
||||
@@ -115,6 +115,18 @@ const expectedWechatShellFiles = [
|
||||
'webView.js',
|
||||
'webView.test.js',
|
||||
];
|
||||
const expectedWechatPageFilesByRoute = {
|
||||
'share-grid': ['index.js', 'index.json', 'index.wxml', 'index.wxss'],
|
||||
'subscribe-message': ['index.js', 'index.json', 'index.wxml', 'index.wxss'],
|
||||
'web-view': [
|
||||
'index.js',
|
||||
'index.json',
|
||||
'index.style.test.js',
|
||||
'index.wxml',
|
||||
'index.wxss',
|
||||
],
|
||||
'wechat-pay': ['index.js', 'index.json', 'index.wxml', 'index.wxss'],
|
||||
};
|
||||
const expectedMobileHostBridgeFiles = [
|
||||
'bridge.test.ts',
|
||||
'bridge.ts',
|
||||
@@ -186,6 +198,15 @@ const documentedShellLayerGroups = [
|
||||
(fileName) => !fileName.includes('.test.'),
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'wechat page wrapper files',
|
||||
files: Object.entries(expectedWechatPageFilesByRoute).flatMap(
|
||||
([route, files]) =>
|
||||
files
|
||||
.filter((fileName) => !fileName.includes('.test.'))
|
||||
.map((fileName) => `${route}/${fileName}`),
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'mobile host bridge files',
|
||||
files: expectedMobileHostBridgeFiles.filter(
|
||||
@@ -215,6 +236,7 @@ const capabilityListMarkers = {
|
||||
desktop: '桌面壳当前真实能力完整清单为',
|
||||
mobile: '移动壳当前通用真实能力完整清单为',
|
||||
mobileIosExtra: '移动壳 iOS 额外真实能力为',
|
||||
wechat: '微信小程序壳当前真实能力完整清单为',
|
||||
};
|
||||
const sharedHostBridgeContractPath =
|
||||
'packages/shared/src/contracts/hostBridge.ts';
|
||||
@@ -579,6 +601,28 @@ function assertSameList(actual, expected, label) {
|
||||
}
|
||||
}
|
||||
|
||||
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 readDirectoryNameList(directory, label) {
|
||||
const directories = [];
|
||||
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
||||
if (!entry.isDirectory()) {
|
||||
throw new Error(`${label} must not contain root files: ${entry.name}`);
|
||||
}
|
||||
directories.push(entry.name);
|
||||
}
|
||||
return directories.sort();
|
||||
}
|
||||
|
||||
function assertShellLayerLayoutDocumented(source, label) {
|
||||
for (const group of documentedShellLayerGroups) {
|
||||
for (const fileName of group.files) {
|
||||
@@ -806,6 +850,11 @@ function assertNativeShellCapabilityPlan() {
|
||||
],
|
||||
'native shell documented method table',
|
||||
);
|
||||
assertSameList(
|
||||
extractDocumentCapabilityList(planSource, capabilityListMarkers.wechat),
|
||||
sharedWechatCapabilities,
|
||||
'wechat mini program documented capabilities',
|
||||
);
|
||||
assertSameList(
|
||||
extractDocumentCapabilityList(planSource, capabilityListMarkers.mobile),
|
||||
mobileCapabilities,
|
||||
@@ -976,35 +1025,39 @@ function assertWechatMiniProgramRouteParity() {
|
||||
}
|
||||
|
||||
function assertHostBridgeLayerLayout() {
|
||||
const wechatBridgeFiles = fs
|
||||
.readdirSync('miniprogram/host-bridge', { withFileTypes: true })
|
||||
.filter((entry) => entry.isFile())
|
||||
.map((entry) => entry.name)
|
||||
.sort();
|
||||
assertSameList(
|
||||
wechatBridgeFiles,
|
||||
readDirectoryFileList(
|
||||
'miniprogram/host-bridge',
|
||||
'wechat host bridge files',
|
||||
),
|
||||
expectedWechatHostBridgeFiles,
|
||||
'wechat host bridge files',
|
||||
);
|
||||
|
||||
const wechatShellLayerFiles = fs
|
||||
.readdirSync('miniprogram/shell', { withFileTypes: true })
|
||||
.filter((entry) => entry.isFile())
|
||||
.map((entry) => entry.name)
|
||||
.sort();
|
||||
assertSameList(
|
||||
wechatShellLayerFiles,
|
||||
readDirectoryFileList('miniprogram/shell', 'wechat shell files'),
|
||||
expectedWechatShellFiles,
|
||||
'wechat shell files',
|
||||
);
|
||||
|
||||
const wechatPagePaths = [
|
||||
'miniprogram/pages/web-view/index.js',
|
||||
'miniprogram/pages/wechat-pay/index.js',
|
||||
'miniprogram/pages/share-grid/index.js',
|
||||
'miniprogram/pages/subscribe-message/index.js',
|
||||
];
|
||||
for (const pagePath of wechatPagePaths) {
|
||||
assertSameList(
|
||||
readDirectoryNameList('miniprogram/pages', 'wechat page directories'),
|
||||
Object.keys(expectedWechatPageFilesByRoute).sort(),
|
||||
'wechat page directories',
|
||||
);
|
||||
|
||||
for (const [route, expectedFiles] of Object.entries(
|
||||
expectedWechatPageFilesByRoute,
|
||||
)) {
|
||||
assertSameList(
|
||||
readDirectoryFileList(
|
||||
`miniprogram/pages/${route}`,
|
||||
`wechat ${route} page wrapper files`,
|
||||
),
|
||||
expectedFiles,
|
||||
`wechat ${route} page wrapper files`,
|
||||
);
|
||||
const pagePath = `miniprogram/pages/${route}/index.js`;
|
||||
const source = fs.readFileSync(pagePath, 'utf8');
|
||||
if (!source.includes("require('../../shell/")) {
|
||||
throw new Error(`${pagePath} must import from miniprogram/shell`);
|
||||
|
||||
Reference in New Issue
Block a user