
做智慧社区这块前前后后我折腾了小半年。从最初接到“要一个能管社区娱乐服务的小程序”这个需求到最终交付一套能跑通预约、报名、点播、后台审核、数据统计的完整平台中间踩过的坑比我这几年写业务代码加起来都多。先说这个项目最终的形态终端用户用的微信小程序由uniapp一套代码编译出来后端是PHP负责常规业务接口与数据管理Node.js承担即时推送、视频转码和流媒体这类对并发和性能更敏感的活管理端则是Vue搭建的Web后台运营人员用它处理审核、排期、数据看板。整套系统覆盖了社区娱乐服务的“用户端 管理端 服务端”三条完整链路。这篇文章不打算讲那些“项目演示”式的空话我想把技术选型背后的考虑、每个模块实现时的核心细节、以及上线过程中真正让人头疼的环境和兼容问题全部摊开来讲。尤其是那些你在官方文档里翻不到但实际开发中一定会撞上的坑比如小程序顶部导航栏适配、npm权限报错、m3u8播放器选型我会用自己的实战经验给你一条可以直接抄作业的路径。1. 项目背景与整体架构1.1 这个平台到底解决什么问题智慧社区早就不停留在“门禁扫码”“物业报修”这种基础功能上了。居民对社区公共空间的使用需求越来越多样化想约个乒乓球室、想报名周五晚上的亲子烘焙课、想在大屏上看社区活动的录播视频、甚至想预约社区广场舞的音响设备。如果这些事都靠物业前台人工登记、微信群接龙效率低不说还特别容易产生纠纷——时间撞车、名额超报、设备损坏责任说不清。这个平台要做的就是把社区里所有和“娱乐服务”相关的资源统一数字化管理。对居民来说微信小程序里就能完成场地预约、活动报名、点播观看对运营人员来说Vue后台能看到所有资源占用情况、一键排期、处理退款和审核对技术服务方来说这是一套完整的多端项目涉及小程序端、Web管理端、双后端服务非常适合拆开成模块去学习或者二次改造。整个平台的核心模块包括场地与设备预约、活动发布与报名、社区视频点播含直播回放、积分与签到、消息通知、后台数据看板。1.2 整体架构三端并行双后端支撑架构上我用了“123”策略来理解一套小程序微信小程序给居民用两个后端PHP主业务Node.js副业分工三个核心端用户端、运营管理端、服务端。画个简单的数据流关系。用户在小程序上提交一个“预约乒乓球室”的请求请求先到PHP接口层PHP校验用户登录态、检查场地排期冲突写库成功后往消息队列丢一条通知。Node.js服务监听队列把预约成功消息通过微信订阅消息推送给用户。同时运营后台Vue从PHP接口拉取所有场地订单数据生成每日排期表。这里的核心设计原则是PHP不碰长连接和直播流Node不碰复杂业务表结构。PHP处理像用户、订单、活动、场地的CRUD开发效率高、生态成熟Node.js专注做WebSocket消息推送、视频分片转码、m3u8流代理这些偏实时的场景。数据层共用一套MySQLNode只读它需要的表或者通过PHP提供内部接口拿数据避免双写导致的不一致。2. 技术选型为什么是 PHP Node.js Vue uniapp2.1 小程序端选择 uniapp 的核心逻辑微信原生小程序其实也能开发但我最终选了uniapp。原因不是赶时髦而是需求里明显有“未来可能要做支付宝小程序、抖音小程序”的倾向。社区服务类项目往往由地方物业公司运营他们很多同时有支付宝渠道场景比如支付宝里的社区生活号。uniapp的价值在于用Vue语法写一套代码编译到微信小程序、支付宝小程序、H5、甚至App。对于我这个已经熟悉Vue的开发者来说学习成本几乎为零组件部分用uni-ui或者uview都能快速搭页面。这里有个容易忽视的细节uniapp编译到微信小程序时运行时的代码是转换成小程序原生代码执行的不是嵌套WebView。这意味着性能上和原生小程序差距不大但部分DOM操作、某些CSS特性是不支持的。如果你习惯了Web开发里随意操作DOM或者依赖一些原生浏览器API到了uniapp里会非常痛苦。刷子就是所有页面一律用view、text组件布局用flex。2.2 PHP 与 Node.js 的分工逻辑很多人一听到“一个项目同时用PHP和Node.js”就觉得很重其实两个服务之间只要边界清晰体量完全可控。PHP这边主要负责用户登录、注册、手机号验证场地/设备/活动的CRUD与状态流转预约订单的产生、取消、退单处理后台管理员的权限体系数据库迁移与备份Node.js这边主要负责WebSocket连接维护用于社区大屏实时刷新预约状态视频文件上传后的FFmpeg转码和m3u8切片微信订阅消息的异步发送因为PHP同步发太慢接口响应会拖到2秒以上简单的接口聚合层比如给小程序提供“首页聚合信息”一次拉取所有模块数据为什么要这样拆你可以理解成PHP像个踏实的前台经理把每一单业务都记录清楚Node像个灵活的调度员专门处理那些需要“实时响应”的急事。如果让PHP去跑视频转码一个大型活动现场视频可能把PHP-FPM的进程池全部占满其他用户请求全部排队。用Node.js的child_process去调FFmpeg主进程保持空闲用户感觉到的是“虽然视频还在转但其他页面照样秒开”。2.3 Vue 管理后台的适配性后台管理用Vue是大概率事件生态成熟、组件丰富Element Plus或者Ant Design Vue都能直接搬不需要自己从零写表格、表单、日期选择器这些基础设施。我这边选了Vue 3 Vite Element Plus。Vite的冷启动速度比webpack时代提升太多后台东西多经常要反复调试启动快真的能省不少生命。路由用Vue Router状态管理使用PiniaHTTP请求统一用axios封装拦截器里自动携带token、统一处理401跳转登录。后台的页面结构大概有登录页、工作台数据卡片今日预约数、活动报名数本月活跃用户、场地管理、设备管理、活动管理创建、审核、下架、订单管理筛选、导出Excel、用户管理状态、积分明细、内容管理视频上传、分类维护、系统设置管理员账号、角色权限。3. 微信小程序端开发实录uniapp3.1 项目初始化与目录结构创建uniapp项目的方式有两种HBuilderX图形化创建或者命令行npx degit dcloudio/uni-preset-vue#vite my-project。我推荐命令行方式因为它可以纳入Git管理而且不依赖HBuilderX这个IDE。项目创建后选择vue3版本带上TypeScript支持。目录结构上我给前端分得比较细src/ ├── api/ // 接口请求统一封装按模块拆文件 ├── components/ // 公共组件场地卡片、活动卡片、空状态 ├── pages/ // 小程序页面 │ ├── index/ // 首页 │ ├── reserve/ // 预约模块 │ ├── activity/ // 活动列表与详情 │ ├── video/ // 视频点播 │ ├── user/ // 个人中心 │ └── order/ // 订单列表 ├── static/ // 静态资源tabBar图标 ├── stores/ // Pinia状态管理 ├── utils/ // 工具函数request封装、时间格式化 └── App.vue // 全局生命周期获取登录态一个被很多人忽略的点是pages.json 的配置比页面代码本身还重要因为小程序的导航栏样式、tabBar、页面路由都在这一个JSON文件里管理。尤其是在配置tabBar图标时图片路径必须是静态资源目录下的不能再网络图片路径。3.2 顶部导航栏高度与安全区适配热词里那个“微信小程序顶部导航栏高度”能上热搜我真的一点都不意外。开发过小程序的人都知道每台手机的状态栏高度不一样iPhone 14 Pro的灵动岛和普通安卓机型差了不是一星半点。如果导航栏是自定义的不对高度做适配标题文字直接会被状态栏遮住。异形屏的适配我是在App.vue的onLaunch阶段获取系统信息并存到全局变量// App.vue const systemInfo uni.getSystemInfoSync() const menuButtonInfo uni.getMenuButtonBoundingClientRect() // 胶囊按钮信息仅微信小程序有效 const navBarHeight (menuButtonInfo.top - systemInfo.statusBarHeight) * 2 menuButtonInfo.height globalData.statusBarHeight systemInfo.statusBarHeight globalData.navBarHeight navBarHeight这里把胶囊按钮的顶部坐标减掉状态栏高度再乘2是因为胶囊按钮上下留白是对称的这个值加上胶囊按钮本身高度基本就是自定义导航栏的合理总高度。如果你的项目用的是原生导航栏那么navigationStyle保持默认就行不用折腾这套。但社区项目的首页想做个渐变背景的导航栏效果必须用自定义导航这一套适配代码就绕不开。另一个与底部有关的坑是iPhone X之后的Home Indicator区域。页面里有“提交订单”这类固定底部的按钮时要加一个安全区适配padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);建议全局封装一个.safe-bottom的公共类避免每个页面重复写。3.3 登录态与手机号获取登录流程设计得不合理后面所有接口都会跟着遭殃。小程序的登录不能简单调一个login接口拿session就完事。我采用的是标准的三步走wx.login获取临时codecode发送到后端PHPPHP调微信接口交换openid和session_key后端生成自有的token返回给前端后续所有请求都带着这个token那“获取手机号”是什么逻辑呢自2023年起微信强烈要求改用手机号快捷验证组件用button open-typegetPhoneNumber的方式在用户授权后拿到一个动态的code把这个code传给后端后端拿它向微信接口换取真实的手机号。这里要注意前端永远拿不到手机号明文所有解密都在后端完成。实操中的常见坑是用户第一次拒绝授权后再次点击按钮无法唤起授权弹窗。这是微信的硬性限制处理方式只能是引导用户手动点击“重新授权”。但收回授权选项只会在微信“设置-隐私”里出现前端能做的最多是弹窗提醒没法强制执行。3.4 娱乐服务核心功能落地平台的核心娱乐功能我拆成了三个场景场地预约、活动报名、视频点播。场地预约的页面做了日历选择器按天展示每个场地的空闲时段。用户选定时间后后端会校验冲突并锁定场地。这里最关键的是防止“并发抢同一时段”PHP后端用了悲观锁当用户发起预约时先执行SELECT ... FOR UPDATE锁住该场地当日记录再判断时段是否已被占用。虽然对数据库压力大一点但社区预约的并发量本身不大这样的一致性保障最直接。活动报名相对简单活动表有一个total_count和signed_count每次报名时用一条UPDATE语句做原子自增然后判断UPDATE activity SET signed_count signed_count 1 WHERE id ? AND signed_count total_count如果影响行数为0说明名额已满这就是用数据库约束来防超报。视频点播的坑在于格式。社区活动现场视频常用手机录制格式五花八门H5端的浏览器未必都能播。后面我单独安排一节详细讲m3u8的解决方案这里先提一句不要试图让所有端都直接播原始MP4文件统一转码成m3u8分片是更稳的路。3.5 天地图集成与社区服务社区服务有个特殊性服务和地理位置强相关。预约的场地你得知道在哪栋楼、怎么走组织的户外活动你要能给用户展示活动集散点。热词里的“天地图集成微信小程序”正好对应这个需求。天地图和百度地图、高德地图的差异在于它基于国家地理信息公共服务平台合规性方面对政企类项目更友好。在小程序里集成天地图常规做法是用web-view加载天地图的JavaScript API页面。但web-view的性能和交互体验都差点意思。更推荐的做法是用官方提供的微信小程序原生地图组件map然后通过天地图的Web服务API拿到坐标数据再渲染到原生地图上。比如我一个“社区周边设施查询”功能请求天地图的地点搜索API返回经纬度列表后用uni.createMapContext配合markers属性标记到地图上手感是原生的完全不像内嵌网页。需要提醒的是使用天地图API必须先到官网申请Key而且开发环境和正式环境的域名白名单要提前配好。很多人在本地调试时发现地图加载不出来十有八九是Key的域名白名单里没加localhost。4. PHP 后端核心实现4.1 接口设计与安全校验PHP后端的接口风格我统一用RESTful 统一返回结构。每个接口都返回同样的JSON格式{ code: 0, message: success, data: {} }前端request封装里code为0时直接resolve.data非0时根据message弹出错误提示并reject。这比前端各个接口单独处理错误要清爽得多。接口安全方面三件套不能少HTTPS强制跳转、Token校验、参数过滤。Token用中间件机制处理PHP里我直接用ThinkPHP框架的路由中间件在需要登录的接口分组统一校验。参数过滤用框架自带的验证器每个接口定义规则不合法直接拦掉。这里必须吐槽一个很多人犯的错误以为做了HTTPS就安全了却不防重放攻击。社区项目的预约场景里用户连续点击“提交”按钮几次就可能生成多个重复订单。我用的方案是前端在提交时生成一个uuid作为requestIdPHP端以requestId作为唯一索引重复插入会直接失败。4.2 数据库表设计思路数据库表我设计了大概15张核心几张表的结构值得拿出来讲user表id、openid、unionid、nickname、avatar、phone、status、point积分余额、created_at。field表场地/设备id、name、type1场地/2设备、location、opening_start、opening_end、duration_slotsJSON表示每个时间段是否可约、cover_image、status。order表id、order_no、user_id、field_id、visit_date、time_slot、status0待支付/1已确认/2已完成/3已取消、amount、request_id、created_at。activity表id、title、cover、start_time、location、total_count、signed_count、sign_start_time、sign_end_time、content、status。预约表设计时有一个容易漏掉的字段是request_id就是刚才提到的防重复提交。没有这个唯一键测试阶段你可能就发现了重复订单但要改表结构就麻烦了提前设计好吗。另外duration_slots用JSON字段存时段状态在MySQL 5.7以上就支持JSON类型了查询时用JSON_CONTAINS判断某时段是否可预约比单独建一张时隙表简单许多适合场地数量不多的场景。4.3 跨域与 JSONP 的正确姿势管理后台Vue跑在8080端口PHP接口跑在8000端口跨域问题是必然的。Vue端用axios发的都是XMLHttpRequest不是JSONP所以我实际上不需要PHP输出JSONP格式。正确做法是PHP设置CORS响应头header(Access-Control-Allow-Origin: *); header(Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS); header(Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With);注意处理OPTIONS预检请求很多PHP新手在调试时发现前端报跨域错误其实是后端没处理预请求。如果是ThinkPHP可以在全局中间件中判断如果是OPTIONS请求直接返回200结束不需要执行真正的控制器逻辑。热词里有“PHP跨域JSONP”这个组合猜测可能是旧项目里的前端用了jQuery的JSONP方式。JSONP是老的跨域方案适合不支持CORS的老浏览器或某些CMS场景但JSONP只支持GET而且没有错误码状态调试比较痛苦。现在新项目统一用CORS才是主流。如果历史项目确实存在JSONPPHP端的输出格式形如echo $_GET[callback] . ( . json_encode($data) . );但这种方案我强烈建议逐步替换掉。4.4 PHP 8 环境与常见报错热词里出现“php 8 phpstorm”和“安装php的时候提示:no package libzip found”这是PHP环境搭建时的常见坎。PHP 8相比PHP 7在性能上有显著提升还加入了JIT编译但它的类型系统更严格很多老代码跑在PHP 8上会疯狂报错。比如strlen(null)在PHP 8.0后会直接抛TypeError而PHP 7只是返回0。改造老项目时可以先用PHP 8的降级模式选项跑起来逐个文件排查。PHPStorm配置PHP 8解释器时要保证CLI版本和项目要求的版本一致。php -v确认版本后在Settings - PHP里指向对应的可执行文件。如果用到扩展模块比如swoole或者redis要确认php --modules里有对应的项。Linux下编译安装PHP遇到no package libzip found是因为缺少libzip开发库。Debian系执行apt install libzip-dev如果默认源里的libzip版本太老还需要先装libzip 1.x的最新版。编译时加上--enable-zip参数装完记得make clean make make install避免残留旧的对象文件导致链接错误。5. Node.js 服务端补充5.1 实时通知与消息推送做社区服务消息触达很重要。用户预约成功了、活动报名审核通过了、场地临时关闭了都需要及时通知。微信小程序官方提供了订阅消息机制但订阅消息的发送是一次性的用户订阅一次只能接收一次。Node.js在这条链路里承担的是“消息中心”的角色。PHP端在订单状态变化时向Redis的队列里推送一条消息体。Node脚本监听队列拿到消息后调用微信接口发送订阅消息。选择Node.js做这件事的另一个理由是WebSocket。社区里有一块LED大屏上面要实时显示全场馆占用情况和活动排队状态。PHP实现WebSocket比较麻烦而Node.js用ws库几行代码就能开好一个服务const WebSocket require(ws) const wss new WebSocket.Server({ port: 3001 }) wss.on(connection, (ws) { ws.send(JSON.stringify({ type: connected, message: ok })) })每次PHP端的数据表变更触发Node端广播一条增量数据给所有连接的大屏客户端。大屏页面收到消息后局部更新UI不用整页刷新。5.2 视频转码与 m3u8 点播方案视频点播这块的实验数据最有说服力。一开始直接用video标签播放MP4结果iPhone上部分H.265编码的视频黑屏安卓上码率大的视频拖动进度条卡顿。最终方案是所有上传的视频统一用FFmpeg转码为H.264 AAC格式再做成分片m3u8流。Node.js里的核心处理逻辑const { exec } require(child_process) const ffmpeg require(ffmpeg-static) exec(${ffmpeg} -i input.mp4 -codec:v libx264 -codec:a aac -hls_time 10 -hls_list_size 0 -f hls output.m3u8, (err, stdout, stderr) { if (err) { console.error(转码失败:, err) return } // 转码完成后更新数据库中的视频状态 })-hls_time 10表示每10秒切一个分片-hls_list_size 0表示m3u8播放列表里保留所有分片记录。如果你的业务希望支持视频回看但不想让人下载原片这样处理之后用户拿到的始终是分片ts文件单独下载一个分片没有意义。前端小程序播放m3u8微信原生video组件直接支持m3u8格式这点比H5浏览器省心。但管理后台的Vue页面要预览视频时H5端的浏览器不支持直接播m3u8。这里我用了hls.js库几行代码搞定import Hls from hls.js if (Hls.isSupported()) { const hls new Hls() hls.loadSource(videoUrl) hls.attachMedia(videoElement) }还有一种更省事的取巧方案直接把video地址指向一个转好格式的MP4但如果你要给多个运营人员同时看不同码率的预览转换流统一走m3u8更规范。6. Vue 管理后台搭建6.1 项目架构与路由设计后台管理前端的工程化配置比业务代码本身还重要。路由方案上我用了动态路由用户登录后后端返回该用户有权限的菜单码前端在前置守卫里动态addRoute。权限码不到位即使你手动输入某个路由地址也会被拦回404页根治“越权访问”问题。路由这个热词我能多聊两句。Vue Router 4配合Vue 3时路由模式要用createWebHistory但生产环境部署时Nginx要记得配置try_files把所有请求转发到index.htmllocation / { try_files $uri $uri/ /index.html; }不配这个刷新后台某个二级页面时直接404。6.2 数据管理与权限控制后台的权限模型我采用RBAC角色-权限-用户。三张核心表admin_user、role、permission。role和permission是多对多关联。编码时权限点是静态返回的比如“field:add”“field:edit”“order:export”后端维护一个常量文件再通过API动态下发给前端。菜单权限接口返回的是树形结构前端再按结构渲染侧边栏。这个方案在中小后台里够用也易于理解。如果你的权限粒度要细化到按钮级别可以在每个按钮的v-if里校验一个自定义指令指令内部查询当前用户的action列表。6.3 后台的视频预览与审核流运营人员要审核用户上传的活动视频能在线预览是最基本的需求。刚才说了方案是hls.js。但这里有个坑如果运营人员用的浏览器版本太老不支持MSEhls.js也救不了。我的兜底方案是提供一个“复制视频地址”按钮让运营直接访问m3u8所在URL由Nginx配置audio/video模块直接处理。审核流的业务逻辑不复杂但状态机的设置要前后端统一。视频状态有0待审核、1审核通过、2审核拒绝、3已下架、4转码中。PHP端用枚举常量管理前端Vue里也用同一个枚举渲染Tag颜色避免两边状态码不一致导致显示错乱。7. 常见环境配置与实战避坑7.1 Node.js 安装与 npm 权限问题热词里“npm : 无法加载文件 c:\program files\nodejs\npm.ps1因为在此系统上禁止运行脚本”这个报错是因为Windows系统默认禁止运行PowerShell脚本导致的。解决办法是右键开始菜单进入PowerShell管理员执行Set-ExecutionPolicy -Scope CurrentUser RemoteSigned设置完成后再运行npm命令就正常了。这是Windows下开发环境配置最典型的一个坑很多新手会误以为Node.js没装好重装好几遍。安装Node.js时另一个需要注意的细节是版本选择。社区平台用的Node端服务依赖了一些较新的API我用的是Node 18 LTS。如果你要玩前端工程化尽量也选择LTS版本不要追奇数版本那些只有半年的维护期到时候安全补丁跟不上。7.2 npm 换源与依赖安装npm默认源在国外的CDN安装依赖时经常慢到怀疑人生。解决方案是切换为国内镜像源npm config set registry https://registry.npmmirror.com或者直接安装cnpm用作备用npm install -g cnpm --registryhttps://registry.npmmirror.com但这里我提醒一下如果你的项目有native模块比如node-sass、nodejieba这类需要编译的包用cnpm安装时偶尔会出现二进制不匹配的问题。处理手段是装完后执行npm rebuild重新编译。7.3 uniapp 打包到微信小程序流程uniapp开发完打包到微信小程序的路径是HBuilderX里选择“发行 - 小程序-微信”或者命令行执行npm run build:mp-weixin打包完成后会在dist/build/mp-weixin目录下生成小程序源码。接着用微信开发者工具导入这个目录填入自己的AppID就可以预览。这里有两个坑。第一个是必须用微信开发者工具的“详情 - 本地设置”里把ES6转ES5打开否则某些语法在真机上直接报错。第二个是调试时若提示“域名不合法”那是没配request合法域名。微信小程序上线要求所有请求域名必须HTTPS且在后台白名单内。本地开发时可以勾选“不校验合法域名”方便联调但发布前一定要改回来。另外热词里有“uniapp 不打印日志信息”这个现象通常是打包后条件编译代码被移除导致的。console.log在部分uniapp版本的生产包中会被自动过滤调试时应使用开发版并且通过HBuilderX内置的控制台查看微信开发者工具里的Console也被依赖但不是所有日志都会原样透传。7.4 Vue 与 uniapp 环境变量配置前端项目有两套环境是非常基本的开发环境和生产环境。Vite下用.env.development和.env.production文件管理变量通过import.meta.env.VITE_API_BASE_URL取值。uniapp同样支持Vite环境变量机制。注意以VITE_开头之外的自定义环境变量是访问不到的。图省事的人写个API_URL xxx结果运行发现是undefined先看命名是否带上了VITE_。另外小程序端的网络请求不去访问localhost或IP的真机调试时你的手机和电脑不处于同一网段直接请求开发机IP可能被拒绝。我的经验是开发阶段在.env.development里配置电脑的局域网IP确保手机和电脑连同一个WiFi然后微信开发者工具里“不校验合法域名”勾选上就能愉快联调了。8. 我踩过的几个典型问题实录8.1 场地预约的时间冲突并发问题这个问题在测试阶段没有暴露上线后第一次活动抢购直接爆发。两个人同时提交同一个场地同一时段的订单。原因前面提过我没有一开始就用乐观锁或悲观锁只是先查询再插入中间有时间窗口。解决方案分两层PHP端在插入订单前使用SELECT ... FOR UPDATE锁定数据行当前事务提交或回滚前其他事务拿不到这把锁从根上禁止并发写。前端在用户点提交按钮后立即禁用按钮防止用户重复点击这不是安全机制但能减少人为触发的并发。8.2 视频转码排队导致的任务堆积上线头几天运营上传了一大批老活动视频FFmpeg任务全挤在Node.js单进程里视频转码要排好几个小时。后来的优化是引入了一个简单的任务队列用Redis的list结构左侧push任务右侧pop任务Node启动时开多个worker并发处理worker数量 os.cpus().length - 1每个worker同一时间只跑一个FFmpeg任务避免资源争抢导致服务器CPU跑满影响PHP接口响应。8.3 微信订阅消息的模板匹配问题项目开发时微信小程序订阅消息的模板是需要先在公众平台申请通过的审核通过后的模板ID才能用。这里有个经验同一个模板下的多个字段名称尽量和微信后台的模板内容字段名保持一致。不一致时接口调用会报“field mismatch”错误排查起来要对照两家字段定义特别费劲。8.4 小程序包体超过2MB的保险方案开发到后期发现小程序主包代码加静态资源超过了2MB限制无法上传。解决方案是使用分包加载把“视频点播”“活动详情”这类不常用页面放入subPackages中这样主包只保留tabBar页面和公共库。{ pages: [pages/index/index, pages/reserve/reserve], subPackages: [ { root: pages/video/, pages: [index, detail] } ] }分包的目的不是删除功能而是让用户首次打开只加载主包用到视频模块时再加载分包。对于社区服务这种用户可能一周才看一次视频的项目这个优化效果很明显。做这种多端业务系统最容易让人抓狂的不是某个单点技术多难而是不同技术组件之间的协作成本。PHP安全稳、Node实时强、Vue开发效率高、uniapp多端复用四者各司其职才让整个平台在人力有限的情况下顺利上线并运行稳定。最后再分享一个我个人的习惯项目里所有环境变量的配置统一记录在一个docs/env.md文档里包括PHP扩展依赖、Node版本、npm源地址、微信公众平台配置项。换一台新电脑时照着文档半小时就能搭完整个开发环境不用靠记忆力去回顾扔人坑。尤其是社区这类长期需要维护迭代的项目文档就是防止“开发一时爽、维护火葬场”的最佳防线。