diff --git a/docs/MOBILE_APP_PACKAGING.md b/docs/MOBILE_APP_PACKAGING.md index de60ddfd..33fe2600 100644 --- a/docs/MOBILE_APP_PACKAGING.md +++ b/docs/MOBILE_APP_PACKAGING.md @@ -35,6 +35,7 @@ npm --prefix mobile-uni run build:app - 现有品牌源图仅为 64×64,因此这里生成的是**可用于自定义基座和测试包的派生资产**。正式提交商店前应替换为品牌方提供的高分辨率母版,再重新执行生成和预检。 - `androidPrivacy.json.example` 是**未启用的法务模板**,其中 `__TERMS_URL__` 与 `__PRIVACY_URL__` 必须替换为法务确认的 HTTPS 地址。复制为被 Git 忽略的 `androidPrivacy.json` 后,`npm --prefix mobile-uni run verify:app-release` 才会通过。 - iOS 已按实际功能填写麦克风和照片库用途说明;不申请相机、定位、通讯录、蓝牙或广告追踪权限。 +- `build:app` 依赖 `@dcloudio/uni-app-plus`(须与其他 `@dcloudio` 包同版本)。缺少该编译器时命令**不报错**,只静默产出带 `/h5/` 基路径的 H5 空壳,产物里没有 `app-service.js` 与 `app-renderjs.js`,App 平台代码等于从未编译。判定 `build:app` 是否真的成功要看产物中是否存在 `app-service.js`、`app-renderjs.js`、`manifest.json`,不能只看 `DONE Build complete.`。 - App-Plus 当前不启用浏览器 WebRTC 实时对练;界面必须降级为录音后转写,不能将该路径宣传为实时语音通话。 - 真机步骤和证据口径见 `docs/MOBILE_APP_DEVICE_ACCEPTANCE.md`。资源预检通过不等于 Android/iOS 真机或应用商店验收通过。 diff --git a/mobile-uni/package-lock.json b/mobile-uni/package-lock.json index 45846948..cdc47755 100644 --- a/mobile-uni/package-lock.json +++ b/mobile-uni/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "@dcloudio/uni-app": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-app-plus": "3.0.0-alpha-5020120260710001", "@dcloudio/uni-h5": "3.0.0-alpha-5020120260710001", "@dcloudio/uni-ui": "^1.5.12", "lxgw-wenkai-tc-webfont": "^1.0.0", @@ -1933,6 +1934,103 @@ "@dcloudio/types": "3.4.31" } }, + "node_modules/@dcloudio/uni-app-plus": { + "version": "3.0.0-alpha-5020120260710001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-plus/-/uni-app-plus-3.0.0-alpha-5020120260710001.tgz", + "integrity": "sha512-bYAMi9YqUH6/xGIf/KMlOPQAtLgYmXGCFtw9ZIUGKF4FMrYC/oeSYVJ/WhutgqVuvJau4BoSg/HGIWcqoz1QRA==", + "license": "Apache-2.0", + "dependencies": { + "@dcloudio/uni-app-uts": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-app-vite": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-app-vue": "3.0.0-alpha-5020120260710001", + "debug": "4.3.7", + "fs-extra": "10.1.0", + "licia": "1.41.1", + "postcss-selector-parser": "6.1.2" + } + }, + "node_modules/@dcloudio/uni-app-uts": { + "version": "3.0.0-alpha-5020120260710001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-uts/-/uni-app-uts-3.0.0-alpha-5020120260710001.tgz", + "integrity": "sha512-ajHJurf9oaVtMb7W31ACia96QDp87X2HO+V+XRzW9bnI8Oci6UkzJVoFGXTFWQ8J6ecSbdMkz2dtiHdLgqv22g==", + "license": "Apache-2.0", + "dependencies": { + "@babel/parser": "7.25.6", + "@babel/types": "7.25.6", + "@dcloudio/uni-cli-shared": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-console": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-i18n": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-nvue-styler": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-shared": "3.0.0-alpha-5020120260710001", + "@jridgewell/gen-mapping": "^0.3.3", + "@jridgewell/trace-mapping": "^0.3.19", + "@rollup/pluginutils": "5.1.0", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-sfc": "3.4.21", + "@vue/consolidate": "1.0.0", + "@vue/shared": "3.4.21", + "debug": "4.3.7", + "es-module-lexer": "1.5.4", + "estree-walker": "2.0.2", + "fast-glob": "3.3.3", + "fs-extra": "10.1.0", + "magic-string": "0.30.11", + "picocolors": "1.1.0", + "source-map-js": "1.2.1", + "unimport": "4.1.1" + } + }, + "node_modules/@dcloudio/uni-app-uts/node_modules/@vue/compiler-core": { + "version": "3.4.21", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.21", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@dcloudio/uni-app-uts/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@dcloudio/uni-app-vite": { + "version": "3.0.0-alpha-5020120260710001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vite/-/uni-app-vite-3.0.0-alpha-5020120260710001.tgz", + "integrity": "sha512-GBAUNnfhz0ln0KYGx87NcNHGULMr25ZTOBz0YdXl5q3Jggy6YkYe+C0w2P/4xxz3Q2pUVJ4kC0j/twotgfk6Ew==", + "license": "Apache-2.0", + "dependencies": { + "@dcloudio/uni-cli-shared": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-i18n": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-nvue-styler": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-shared": "3.0.0-alpha-5020120260710001", + "@rollup/pluginutils": "5.1.0", + "@vitejs/plugin-vue": "5.2.4", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-sfc": "3.4.21", + "debug": "4.3.7", + "fs-extra": "10.1.0", + "picocolors": "1.1.0" + } + }, + "node_modules/@dcloudio/uni-app-vue": { + "version": "3.0.0-alpha-5020120260710001", + "resolved": "https://registry.npmmirror.com/@dcloudio/uni-app-vue/-/uni-app-vue-3.0.0-alpha-5020120260710001.tgz", + "integrity": "sha512-xOHqxnQ9yJfDIkY0pSQ3bYZBT55HkUVwCfsx8ZhnEVEtcw4FF2GiIo6xk+Ft/sOtmxj9wChOA7mYkIafbN2Qow==", + "license": "Apache-2.0" + }, "node_modules/@dcloudio/uni-cli-shared": { "version": "3.0.0-alpha-5020120260710001", "resolved": "https://registry.npmmirror.com/@dcloudio/uni-cli-shared/-/uni-cli-shared-3.0.0-alpha-5020120260710001.tgz", @@ -3575,7 +3673,6 @@ "version": "5.2.4", "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", - "dev": true, "license": "MIT", "engines": { "node": "^18.0.0 || >=20.0.0" @@ -3954,6 +4051,15 @@ "@vue/shared": "3.4.21" } }, + "node_modules/@vue/consolidate": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/@vue/consolidate/-/consolidate-1.0.0.tgz", + "integrity": "sha512-oTyUE+QHIzLw2PpV14GD/c7EohDyP64xCniWTcqcEmTd699eFqTIwOmtDYjcO1j3QgdXoJEoWv1/cCdLrRoOfg==", + "license": "MIT", + "engines": { + "node": ">= 0.12.0" + } + }, "node_modules/@vue/devtools-api": { "version": "6.6.4", "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", @@ -5437,6 +5543,12 @@ "node": ">=8" } }, + "node_modules/licia": { + "version": "1.41.1", + "resolved": "https://registry.npmmirror.com/licia/-/licia-1.41.1.tgz", + "integrity": "sha512-XqObV8u1KEMdYWaNK0leRrTwhzKnLQEkhbnuUu7qGNH3zJoN7l9sfvF6PfHstSCuUOmpEP+0SBjRrk0I9uZs8g==", + "license": "MIT" + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", diff --git a/mobile-uni/package.json b/mobile-uni/package.json index d2e92bd7..32875577 100644 --- a/mobile-uni/package.json +++ b/mobile-uni/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@dcloudio/uni-app": "3.0.0-alpha-5020120260710001", + "@dcloudio/uni-app-plus": "3.0.0-alpha-5020120260710001", "@dcloudio/uni-h5": "3.0.0-alpha-5020120260710001", "@dcloudio/uni-ui": "^1.5.12", "lxgw-wenkai-tc-webfont": "^1.0.0", diff --git a/mobile-uni/tests/app-packaging.test.mjs b/mobile-uni/tests/app-packaging.test.mjs index 0509dc69..ececdf51 100644 --- a/mobile-uni/tests/app-packaging.test.mjs +++ b/mobile-uni/tests/app-packaging.test.mjs @@ -1,10 +1,12 @@ import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; +import { readFile } from 'node:fs/promises'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; import { dirname, resolve } from 'node:path'; const mobileRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +const readJson = async (path) => JSON.parse(await readFile(new URL(path, import.meta.url), 'utf8')); test('App 图标与启动图映射均可由预检脚本验证', () => { const output = execFileSync(process.execPath, ['scripts/verify-app-assets.mjs'], { @@ -13,3 +15,15 @@ test('App 图标与启动图映射均可由预检脚本验证', () => { }); assert.match(output, /App asset verification passed/); }); + +// 缺少 App 平台编译器时 `uni build -p app` 不会报错,只会静默产出带 /h5/ 基路径的 +// H5 空壳(无 app-service.js/app-renderjs.js),使 build:app 成为假绿,renderjs +// 实时对练代码实际从未被 App 编译器处理。 +test('App 平台编译器已声明且与其他 uni 包同版本,避免 build:app 静默回落 H5', async () => { + const pkg = await readJson('../package.json'); + const appPlus = pkg.dependencies?.['@dcloudio/uni-app-plus']; + + assert.ok(appPlus, '缺少 @dcloudio/uni-app-plus,build:app 会静默产出 H5 空壳'); + assert.equal(appPlus, pkg.dependencies['@dcloudio/uni-app']); + assert.equal(appPlus, pkg.devDependencies['@dcloudio/vite-plugin-uni']); +});