不会后端、没买服务器,从本地随机拼字到云函数接口,一个起名小程序的完整踩坑记录。
一、起因:想给起名这件事来点「技术浪漫」
大家好,我是一个前端小白(会点 JS,没写过后端)。前阵子朋友生娃为起名发愁,市面上起名 App 不是广告满天飞就是要充会员,我心想:不如自己做一个?
于是「天赐嘉名」诞生了——一个主打「无广告、不收费」的起名小程序,目前包含六大功能:
- 🎭 网名生成(文艺、古风、可爱等 9 种风格)
- 👶 宝宝起名(诗词典故,带出处)
- 🏮 店铺起名(9 大行业定制)
- 🐾 宠物起名
- 💕 情侣 ID / 游戏名
- 🔮 姓名打分(五维解析 + 重名估算)
这篇文章记录我从 0 到上线的全过程,特别是从本地数据源迁移到微信云开发的完整踩坑经历,希望能帮到同样想入门小程序的朋友。
二、技术选型:为什么选云开发
先说结论:个人开发者做小程序,云开发几乎是唯一解。
| 方案 | 成本 | 门槛 |
|---|---|---|
| 自建服务器 | 服务器 + 域名 + 备案 + HTTPS | 高 |
| 微信云开发 | 免费额度够用 | 低,前端就能写 |
云开发不需要买服务器、不需要配域名白名单,前端直接 wx.cloud.callFunction 调后端,对零基础太友好了。
三、第一版踩的最大的坑:本地随机拼字
第一版图省事,我把所有字库放在小程序本地,生成逻辑就是「随机挑字拼接」:
// ❌ 错误示范:随机拼字
const name = randomItem(surnames) + randomItem(chars) + randomItem(chars)
结果生成的都是什么鬼:
- 给男宝宝起出「李芙蓉」🤦
- 「王磨琢」这种完全不像名字的组合
- 店铺起名出现「煮辣铺」(用户选的是服装店!)
教训:起名不是排列组合,必须是人工精选的成品词库。
四、重构:数据层全部改为「成品词库」
我把所有数据源重构为精选模式。以诗词起名为例,59 首诗词人工标注了 111 个成品名:
// ✅ 每个名字都带性别标签、出处和寓意
{
quote: '既含睇兮又宜笑,子慕予兮善窈窕',
from: '《楚辞·九歌·山鬼》',
names: [
{ name: '含睇', gender: 'female', meaning: '含情微视,美好善良' },
{ name: '子慕', gender: 'neutral', meaning: '倾慕美好,心怀善意' }
]
}
生成逻辑也从「随机拼」变成「80% 成品直出 + 20% 受控模板」,名字质量立竿见影。
五、核心架构:一个云函数 + action 路由
云函数按调用次数给免费额度,所以我把所有接口收敛到一个云函数 nameApi,用 action 路由分发:
// cloudfunctions/nameApi/index.js
exports.main = async (event) => {
const { action, options = {}, count = 12 } = event
switch (action) {
case 'nickname': return ok(generateNicknames(options, count))
case 'babyname': return ok(generateBabyNames(options, count))
case 'shopname': return ok(generateShopNames(options, count))
case 'petname': return ok(generatePetNames(options, count))
case 'coupleid': return ok(generateCoupleIds(options, count))
case 'score': return ok(analyzeName(options.name))
case 'chars': return ok(analyzeChars(options.name))
default: return fail('unknown action')
}
}
前端封装一个 callApi,所有页面统一走它:
// utils/cloud.js
const CLOUD_ENV = 'huanting-xxxx' // 你的环境 ID
function callApi(action, options = {}, count = 12) {
return wx.cloud.callFunction({
name: 'nameApi',
data: { action, options, count }
}).then(res => {
if (res.result.code !== 0) throw new Error(res.result.message)
return res.result.data
})
}
页面上带加载态调用,体验比本地生成还丝滑:
async onGenerate() {
this.setData({ loading: true })
try {
const list = await callApi('nickname', { style, length })
this.setData({ list })
} finally {
this.setData({ loading: false })
}
}
六、姓名打分:确定性哈希的小心思
打分功能有个隐藏需求:同一个名字每次得分必须一样,不然用户会觉得是瞎编的。解决方案是哈希取种子:
function hashStr(s) {
let h = 0
for (let i = 0; i < s.length; i++) {
h = (h * 31 + s.charCodeAt(i)) & 0x7fffffff
}
return h
}
// 得分 = base + hash(name) % 区间 → 同名同分,完全确定性
重名人数则用「姓氏人口比例 × 名字用字频率」估算,并加了 ±20% 的确定性抖动。页面上明确标注「仅供娱乐参考」——这行字很重要,审核要看。
七、上线前踩的三个坑
坑 1:云函数部署了但没生效
在云控制台点「新建」创建的是 Hello World 模板函数,测试时日志里打印 Hello World 才反应过来。正确姿势:在开发者工具里右键云函数文件夹 →「创建并部署:云端安装依赖」,函数名由文件夹名决定。
坑 2:上传报「source size exceed max limit 2MB」
项目里放着小红书推广用的 5 张素材图(1.7MB),全被打进包了。解决方案是不删文件,用配置排除:
{
"packOptions": {
"ignore": [
{ "type": "folder", "value": "tiancijiaming-naming" },
{ "type": "file", "value": "preview.html" }
]
}
}
坑 3:真机调试 Timeout
调试半天连不上,最后发现是电脑开着代理。关掉 VPN/ClashX 立刻就好。另外「预览」扫码也能真机验证功能,不非要真机调试。
八、写在最后
从「想做」到「上线」,零基础真正卡人的从来不是写代码,而是这些细碎的坑。总结一下我的心得:
- 内容型产品,数据质量 > 算法花哨,精选词库吊打随机拼接
- 云函数收敛成单入口 + action 路由,省心省额度
- 确定性哈希让"伪随机"功能(打分、运势类)显得专业
- 审核敏感点(如重名数据)记得加「娱乐参考」免责声明
如果你也想做小程序,希望这篇能帮你少踩几个坑。欢迎微信扫码体验交流,有问题咱们评论区聊~
👇 微信扫码体验「天赐嘉名」,也欢迎一起交流小程序开发