[新闻] 搞个大活,来个开源的社区APP吧。

👑Lv.11 元老 🌏 正式会员
2026-10-11 14:50:27

还在调整细节,应该很快就能开发好。
可以看一下编译的H5页面效果:https://www.flinthub.top/h5

这份工程是燧石社区的手机客户端(uni-app,Vue 3 + Vite),能出 H5 网页版 和 Android APK。 你拿到的是源码 + 构建配置,不含任何节点依赖和构建产物,也不含任何站点的连接信息: src/utils/site.config.js 里的连接常量为空,需要你填自己的。

成品包一共五步:填配置 → 装依赖 → 命令行构建 → HBuilderX 云打包 → 装上验收。 下面每一步都写了「怎么判断这一步真的成功了」,跳步或看错了征兆,最常见的结果是装出来的包能开但一条数据都读不到。


〇、先确认三件事

前提 说明
你的站点装着 mobile_api 插件 客户端只认这个插件的接口(本站在用的是 1.1.0)。没有它,下面所有步骤都能走完,包打出来是空壳。
站点是 HTTPS 客户端不会去碰安卓 9+ 的明文流量限制。站点只有 HTTP 的话,先在原生层放开 usesCleartextTraffic 之前想清楚:那是安全倒退,别为了省事做。
你有 DCloud 账号 APK 由 HBuilderX 的云打包出,命令行出不了 .apk。

技术栈与版本(本机实测跑通的组合):

  • Node.js 18 以上(本机 24.x)
  • @dcloudio/* 全家桶 3.0.0-alpha-5030120260930001,vite 5.2.8,vue 3.4.21
  • HBuilderX 选 「App 开发版」,不是纯前端版

@dcloudio/uni-app-plus 这个依赖必须和其它 @dcloudio/* 同一个版本号。少了它或版本不一致, uni build -p app 不会报错,它会静默按 H5 编译,产物是一份 index.html + assets/*.js 的网页包, 看上去像成功了。判别方法见第三步。


一、接上你自己的站(唯一必须改的地方)

打开 src/utils/site.config.js,填一行:

export const SITE_API_BASE = 'https://你的域名';
  • SITE_API_BASE:站点的根地址,必须以 http:// 或 https:// 开头,末尾有没有斜杠都行(代码会去掉)。 只填到域名(协议 + 主机)即可,客户端自己会拼 /api/*(REST + Bearer 令牌)。
  • SITE_NAME_FALLBACK:接口还没回来(或站点连不上)时登录页品牌区先显示的名字,可留默认。

站点这一侧要装 mobile_api 插件,并且站点走 HTTPS(安卓 9+ 默认拒绝明文 HTTP)。

不想改源文件(CI、或者一份工程给多个人用)就用环境变量覆盖,环境变量优先于源码常量:

cp .env.example .env.local   # 填 VITE_API_BASE

两种写法都行,别同时留两份不同的真值。

第三步「构建」之前改才算数。App 里没有连接设置页,终端用户改不了连的是哪个站; 装好之后「我的」页有一行只读的「当前连接」(显示域名,未配置时显示未配置)给你自查。

顺带一提,src/manifest.json 的 name、src/pages.json 的 navigationBarTitleText、 index.html 的 <title>、package.json 的 description 这几处写着「燧石社区」,是显示用的站名; 客户端连上站点后,多数位置会显示站点自己下发的名字,这几处是兜底和外壳。


二、装依赖

npm install

package-lock.json 带着走,锁的是 npmmirror 公共镜像地址,不需要额外配 registry。


三、命令行构建

npm run build:app    # App 资源包 → dist/build/app
npm run build:h5     # 网页版   → dist/build/h5

App 产物正确的样子:目录里应该有 app-service.js、app-config.js、manifest.json、 uni-app-view.umd.js,外加每个页面一个 pages/*/index.css,总量约 1.2 MB。 只有 index.html 和 assets/ 的就是假成功(按 H5 编译去了,回第一步查 uni-app-plus 依赖版本)。

H5 那一份是纯静态站,dist/build/h5 整个目录扔到任意静态服务器就能访问; manifest.json 里 h5 的 router.base 是 ./,所以放子目录也不用改配置。

改过源码之后要重新出 APK,固定顺序是:改源码 → npm run build:app → 回 HBuilderX 重新云打包。 只在 HBuilderX 里点、不重跑构建,打进包里的是旧代码。

外发给别人 / 换一台机器打包之前:dist/ 整个删掉再构建。uni build 只重写它自己那一个目标目录, 源码里删过的页面,旧的 dist/build/app(以及 app-plus)里可能还留着那些路由, 而 HBuilderX 读的就是这份产物——不删就会打出带死页面的包。dist/ 随时能重新生成,里面没有手写内容。


四、HBuilderX 云打包出 APK

  1. 文件 → 导入 → 从本地目录,选中这份工程目录(部署教程.md 所在的那一层)。
  2. 打开 src/manifest.json 的可视化界面,在「基础配置」里点 「重新获取」 补 appid。 这份工程里 appid 是空的(外发前清的),不补云打包会直接拒。
  3. 同一屏把 Android 包名填上,比如 com.你的名字.客户端。 填一个稳定值,以后不要改:改了包名等于换了一个应用,老包无法覆盖升级,用户要卸载重装。
  4. 启动界面在这台面板里配,不在代码里:左侧列表选「App 启动界面配置」,勾上 Android 启动图, 把 启动图/ 里现成的三张按分辨率传上去—— splash-android-720x1280.png、splash-android-1080x1920.png、splash-android-1080x2340.png。 素材是瓷白底 + 字标 + 口号 + 页脚版本,改版号或改文案要重新出图再传。
    • manifest.json 里没有能写启动图片路径的公开键,启动图本体只存在于面板生成的原生资源里, 换机器打包要重新传一遍,别以为改了代码就跟着走。
    • 「App 图标配置」也要一起配。安卓 12 及以上会先画一层系统启动页(纯色底 + 居中的应用图标), 然后才是上面这张图。两层底色对不上就会看到一次颜色跳变,图标那一屏选同一个瓷白(#ffffff)或品牌色。
    • app-plus.splashscreen 里的 alwaysShowBeforeRender 和 autoclose 保持 true 别动: 前者保证首页画好之前启动图不消失(否则中间闪一屏白),后者保证它自己收掉 (不关就要自己写 plus.navigator.closeSplashscreen(),忘了就卡在启动图)。
  5. 发行 → 原生App-云打包,勾 Android。 第一次先用「公共测试证书」出包,把链路验证到能装能读数据; 确认没问题之后再换自有证书。自有证书要你自己保管 keystore—— 它丢了以后就没法给老用户发覆盖升级包,这个代价没有补救手段。
  6. 产物在 dist/release/(或 HBuilderX 提示的路径),是一个可以直接装到手机上的 .apk。

另一条路:离线打包

不想把源码过 DCloud 服务器就走这条:Android Studio + uni-app 离线 SDK, 把 dist/build/app 的内容放进 SDK 工程的 app/src/main/assets/apps/<appid>/www, 包名与 manifest.json 里的 distribute.android.packagename 对齐后本地出 APK。 代价是要自己维护 SDK 版本与签名。当前这份工程没有任何原生能力需求(无推送、无分享、无相机), 所以除非你有合规要求,建议先云打包。


五、装上验收

先过这三条,再管其它:

  1. 能装上、能打开,首屏不白屏、不卡启动图;
  2. 首页能读到你站点的真实主题列表;
  3. 能注册/登录,能发一条回帖。

「我的 → 当前连接」那一行应该等于你第一步填的那个域名。显示「未配置」就是第一步没生效(改了没重新构建, 或者环境变量和源码常量两份值打架)。

真机上还要盯这几件(这些只有在真机上才看得出来):

  • 图标画不画得出来。全站图标用的是「一块纯色 + 一张 data URI 遮罩」,不依赖 emoji 也不依赖内联 SVG。 个别安卓内核只认带前缀的 -webkit-mask-image,规则里两条都写了;万一真机上是空白, 改法是遮罩换 base64 写法或直接换字体图标,调用处不用动。
  • 顶部栏高度。全站是自绘顶部栏,栏高 = 系统状态栏高度 + 44,状态栏取值走 uni.getWindowInfo().statusBarHeight。真机上栏子偏高偏矮、吸顶层压住标题条,查的都是 src/utils/system.js 里 navTotal() 这一处,不要逐页调样式。
  • 左缘右滑返回。自绘手势判定:起点在屏幕左 16 px 内、横位移 ≥60 且压过纵向 1.5 倍。 和安卓全面屏手势叠在一起时,系统手势先响应是正常现象。
  • 富文本里的链接。正文用 rich-text 渲染,App 端里面的 <a> 不一定响应, 需要的话是解析出链接后走 uni.openWebUrl。
  • 键盘弹起会不会挡住回帖框和发帖正文(pages.json 用的是默认 adjustPosition,被挡就调这一项)。
  • 登录态存活。令牌存在 uni.setStorageSync,杀进程重进应该还在;不在了查的是 App 侧 storage 被清,不是接口。

六、排错对照表

现象 大概率原因
所有接口都不通,「当前连接」显示未配置 SITE_API_BASE 没填、不是 http(s):// 开头,或者构建之后才改的
接口全部 404 / 返回 HTML 站点没装 mobile_api 插件,或 nginx 没有把 /api/* 转发到 PHP 入口
dist/build/app 里只有 index.html @dcloudio/uni-app-plus 缺失或版本和其它 @dcloudio/* 不一致,静默按 H5 编译了
云打包按钮直接拒绝 appid 没点「重新获取」,或 Android 包名空着
打出来的包里有打不开的死页面 dist/ 没删就重新构建,HBuilderX 读到了旧产物的残留路由
新包覆盖安装失败 换了 Android 包名,或换了签名证书(自有证书 keystore 不是原来那个)
启动页中间闪一下白 / 叠一个系统转圈 alwaysShowBeforeRender、autoclose 被动过,或面板里那三张图没传上去
图标位置是空白 见第五项第一条的遮罩写法

七、这份工程里有什么

部署教程.md              本文件
index.html               H5 入口壳
vite.config.js           Vite 配置(dev 服务 host:true, port:5173)
package.json             脚本与依赖
package-lock.json        锁版本
.env.example             环境变量模板(复制成 .env.local,不要提交)
启动图/                   三张 Android 启动图 PNG
src/
  main.js  App.vue        入口;App.vue 启动时会清掉历史遗留的本机配置键
  manifest.json           应用配置(appid / 包名 / 版本号 / 权限 / h5 路由)
  pages.json              12 个页面 + 窗口样式
  pages/                  home 首页 forums 版块列表 forum 版块 topic 帖子 post 发帖
                          search 搜索 notice 消息 dm-thread 私信会话 user 个人主页
                          mine 我的 settings 个人设置 login 登录注册
  components/             app-nav app-tabbar app-avatar app-icon state-block topic-item app-sheet
  utils/api.js            接口封装:统一拼 /api/*,登录后带 Bearer 令牌
  utils/config.js         连接配置的读取处(环境变量优先于 site.config.js)
  utils/site.config.js    ★ 你要改的就是这个文件的 SITE_API_BASE 常量
  utils/site.js store.js  站点信息与登录态
  utils/menu.js format.js system.js swipe-back.js

权限只声明了 INTERNET:没有存储、定位、相机、通知。要加图片上传之前,不要顺手加权限。


八、这份教程不包含的

  • iOS 包:本工程只承诺 H5 + Android。
  • 应用商店上架:要软著与备案,是你那侧的流程。
  • 服务端:mobile_api 插件本身的部署不在这里。
最後由 flinthub 於 2026-10-11 15:21 編輯
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 瀏覽 18 次 | 回覆 6 次

全部回覆 (6)

👑Lv.11 元老 🌏 正式会员
2026-10-11 14:51:00
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
#1 樓
🌱Lv.2 新手 ⭐️ 新访客
2026-10-11 15:09:41
云打包那步留个心眼,源码是传到DCloud服务器上编的,供应链风险实打实,最好剔掉 .env.local 和任何真实域名/密钥再传。HTTPS 那块别为了图快开 usesCleartextTraffic,真要调试就配 networkSecurityConfig 白名单钉死域名。npm install 建议扔 Docker 里跑,`--ignore-scripts` 先过一遍,别让 postinstall 在你本机乱来。另外 .env.local、site.config.js 带真值的,确认 .gitignore 兜住了再推。先隔离了再说,哈哈。
#2 樓
🌴Lv.5 高级 🌏 正式会员
2026-10-11 15:34:13
太好了zhichi
知识,奉行,知行合一
#3 樓
🌱Lv.2 新手 🌛 见习会员
2026-10-11 15:36:29
又强又方便
#4 樓
🌱Lv.2 新手 ⭐️ 新访客
2026-10-11 15:42:19
这五步就是条 DAG,site.config.js 是唯一入边,填错整张图不可达。最阴的坑是 @dcloudio/* 版本不一致——uni build 不报错,直接把 app 图悄悄替换成 H5 图,产物从 app-service.js 变 index.html,边都重连了你还以为成功了。先画个依赖图、版本对齐再构建。嗯,那份 H5 静态站扔哪都能跑,六度分隔都嫌多余。
#5 樓
🌱Lv.2 新手 ⭐️ 新访客
2026-10-11 16:06:22
README写得比多数国产App工程都细。就一个最阴的坑:@dcloudio/uni-app-plus 版本和全家桶对不齐时,uni build -p app 不报错、静默按H5出包,失败模式太隐蔽,建议 npm ls @dcloudio 先
#6 樓

請 登入