从 0 搭建 uni-app 多端项目的目录结构

分层的依据:按变更频率,而不是按文件类型

很多项目的目录是「按文件类型」堆出来的:所有 js 放一起,所有组件放一起。项目小时没问题,一旦要同时面向微信、抖音和 App,就会出现「改一个端、三个端都得重新验证」的局面。

更稳的做法是按变更频率分层:越靠下的层越稳定,越靠上的层越易变。稳定层被多个端共享,易变层承载端差异,这样大部分改动被限制在局部,不会产生跨端连锁回归。

目录骨架

src/
├── pages/           页面,按业务域分子目录(如 home、post、user)
├── components/      跨页面复用组件
├── api/             接口定义与请求封装
├── store/           全局状态
├── utils/           纯函数与工具(含平台网关)
├── config/          多环境配置
├── static/          图片、字体等静态资源
└── App.vue / main.js

页面按业务域划分,而不是按端划分。端差异不体现在目录上,而体现在文件内的条件编译块与 utils/platform 网关里——这是控制目录膨胀的关键。

公共层如何组织,避免循环依赖

公共层最容易失控的是相互引用。约束方式非常简单:依赖只能单向向下

  • api 只依赖 utilsconfig,不反向依赖页面或组件;
  • utils 是叶子层,不依赖 storeapicomponents
  • components 可以依赖 apiutils,但不依赖 pages
  • store 可以依赖 apiutils,但不依赖 pagescomponents

一旦出现「组件去读页面数据」的需求,说明这段状态应该上提到 store,而不是让组件反向依赖页面。此外,跨页面的公共逻辑优先抽成 utils 里的纯函数,纯函数没有副作用,天然易测。

条件编译文件放哪里

条件编译是 uni-app 处理端差异的主要手段,但写法需要有统一约定,否则会散落各处:

  • 平台专属组件:放在组件目录内,文件名后缀标识平台(如 xxx.mp-weixin.vue),并在同目录 README 中说明用途;
  • 平台专属逻辑:抽到 utils/platform/ 下,函数内部用 // #ifdef MP-WEIXIN 之类的注释块包裹,对外暴露统一函数名;
  • 平台专属页面配置:统一写在 pages.json 对应页面的条件编译块中,不要散落到业务代码。

原则是:端差异集中在少数几个文件里,页面层保持「不知道有几个端」

多环境配置的命名约定

配置建议拆为 config/dev.jsconfig/test.jsconfig/prod.js,再由 config/index.js 按编译环境统一导出。业务代码只 import config from '@/config',不直接引用具体环境文件。这样切换环境只改构建配置,不动业务代码。

小结

目录结构的本质是把「经常改的」和「很少改的」分开。稳定层向下沉淀、易变层向上收敛、端差异集中隔离,这套结构在后续接入新端时,改动范围可以被控制在 utils/platform 与配置文件之内,而不需要翻遍整个工程。

我们为什么重做团队官网:技术选型与取舍

动因:问题不在「不好看」,而在「不好改」

启动重做最常见的触发点是视觉过时。但推进过程中我们会发现,真正的阻力来自维护端:栏目结构被写死在页面模板里,新增一个专题要改代码;文章列表与详情页的样式散落在多个文件中,换一次主色需要全局搜索替换;同一个信息在两三个模板里各写一遍,改一处忘一处。

视觉只是表象,可维护性才是持续成本。因此我们把这次重做的目标定义为:让非技术同事能独立完成日常内容发布,让开发同学能在不改动核心模板的前提下扩展栏目

先定内容模型,再定视觉

内容模型回答三个问题:一篇内容属于什么类型、包含哪些字段、以什么关系被引用。官网上的内容通常归为几类:文章(分类、标签、封面、摘要、正文)、服务或产品条目(标题、卖点、图标、跳转)、团队成员,以及若干落地页。

如果先做页面设计,很容易把「某一条内容的特殊排版」当成通用结构,后期新增内容时被迫做大量例外处理。反过来,先把内容类型和字段定下来,视觉就变成「如何渲染这套字段」的问题,风格调整不再牵动结构。

三类方案的取舍

方案 优势 代价
纯静态生成器(SSG) 首屏快、部署简单、安全面小 非技术同事改内容门槛高;表单、评论、会员等动态能力需另配后端
前台框架 + 自建后端 交互自由度高,前后端可完全按需设计 内容管理后台要自建,长期维护成本随功能增长快速上升
WordPress + 自研主题 内容管理成熟、插件生态完善、二次开发资料充足 需要额外的性能与安全治理,防止插件无序膨胀

我们最终选择 WordPress + 自研主题。理由有三:其一,内容由非技术同事维护,后台可用性优先;其二,站点需要会员、表单、站内检索等动态能力,使用成熟后台能省下大量自建成本;其三,团队长期深耕 WordPress 主题与插件二次开发,方案与自身能力栈匹配。

我们放弃了什么

选择必然伴随放弃,这部分同样需要提前讲清。

  • 放弃纯静态方案:代价是首屏性能要靠额外治理补回来——缓存策略、CDN、资源压缩与图片格式优化都需要单独投入,这部分后来被拆成一个独立的性能优化专项处理。
  • 放弃完全自建后端:代价是无法完全掌控数据模型,需要把业务字段映射到 WordPress 的内容结构上,映射规则必须文档化,否则后续接手者难以理解。
  • 放弃「一步到位」的栏目大而全:代价是部分边缘栏目只能先上线基础版,靠后续迭代补齐,换来的是更短的上线周期与更低的试错成本。

选型结论

官网是长期运营资产,不是一次性交付物。因此我们给选型排定的优先级是:内容可维护性 > 二次开发成本 > 首屏视觉复杂度。首屏效果可以靠后续优化打磨,而内容模型一旦定错,返工代价会随时间累积放大。