☰
AI生成小程序+miniprogram-ci:命令行实现从代码到发布
2026/10/28 10:51:05 网站建设 项目流程

以前我给人演示小程序开发,最麻烦的一步不是写代码,而是“先装一个微信开发者工具”。很多朋友会问:能不能像写 ChatGPT 提示词那样,说一句“我想要一个XX小程序”,东西就真的能上线?当时我的回答是:代码可以生成,但发布还是绕不过那个 IDE。直到我把miniprogram-ci的路子跑通,才发现从生成到发布,确实可以全程不点开图形化界面。这篇文章我就把完整链路拿出来说一遍:AI 怎么把一句话变成工程代码,微信官方提供的命令行工具怎么把代码直接推到微信服务器,以及上线前那些容易翻车的细节。

1. “一句话生成”不是魔法:AI 到底替你干了哪几件事

“一句话上线”听起来玄,实际上拆开看就三步:说需求、出代码、传代码。AI 能做的是把第一步到第二步,把自然语言翻译成一整套小程序工程文件;第三步靠的是官方自动化接口,跟 AI 没关系。这两部分需要分开理解。

1.1 从“想法”到“文件结构”的翻译

AI 生成小程序,本质上是生成一套符合微信 MINA 框架的源码工程,而不是在你电脑上装一个运行时环境。你给它一句话,它会在内部完成这几件事:

  • 拆解需求:从“输入车牌号生成图片”这句话里识别出“输入框”“按钮”“canvas 绘制”“图片预览”这些功能点;
  • 规划目录:决定事情应该放在pages/index还是一个独立组件里;
  • 生成语法:输出WXML结构、WXSS样式、JS逻辑和JSON配置;
  • 补齐配置文件:包括project.config.json、app.json等,让这个工程能被工具链识别。

你可以把大模型想象成一个“练过小程序语法但没见过你业务”的初级工程师。它非常熟悉wx.request、setData、onLoad这些 API,但对你行业里的规则一无所知。这决定了它适合干什么、不适合干什么。

1.2 适合生成的场景与不适合生成的场景

我实测下来,AI 在下面这些需求上效率很高:

适合生成的场景典型例子
工具类页面计算器、二维码生成、车牌号图片生成
内容展示列表页、详情页、轮播图
简单交互表单提交、Tab 切换、本地数据筛选
云函数基础框架一个返回 JSON 的云函数、定时触发器

不适合生成的场景,也相当明显:

  • 需要行业判断的业务逻辑。比如“判断一张发票是否合规”不能只靠前端规则,AI 不知道财务口径;
  • 高质量图片、音频、视频素材。AI 生成的代码只能引用素材,素材本身需要另外处理;
  • 涉及账户、支付、复杂权限体系的完整业务。AI 能搭出壳,但无法设计合理的数据库角色权限;
  • 性能要求很高的长列表、复杂动画。生成代码往往不做防抖、不懒加载,上线后会卡。

我记得有一次让 AI 生成一个“用户扫码签到”的小程序,它把签到页、排行榜、个人中心全写好了,但根本没有设计数据表结构。“扫码”之后的用户身份从哪来、重复签到怎么处理,全部没提。这不是 AI 不聪明,而是我没有在提示词里给它业务规则。所以把 AI 当“翻译”而不是“架构师”,是第一条觉悟。

1.3 提示词里加“约束条件”,比加“功能”更重要

很多人的提示词是:“做一个车牌号生成图片的小程序。”结果 AI 给出的代码会很飘——生成一个不可用的页面,图片引用了一个本地不存在的文件,按钮点击后没反应。我会加这类约束:

  • “不要请求任何网络接口,所有数据本地处理”;
  • “页面保持简洁,适配 iPhone 底部安全区”;
  • “使用原生语法,不要引入第三方组件库”。

这些约束直接决定了生成的代码能不能在你没有开发者工具的情况下顺利跑起来。如果引了组件库,你却没法打开 IDE 看样式,排查问题会非常痛苦。

2. 发布链路的最小骨架:AppID、密钥和命令行工具

就算 AI 把代码写得天花乱坠,最终走到用户手机上,还是要经过微信的服务器。微信规定:小程序必须通过官方渠道上传代码。早年只有图形化开发者工具能做这件事,后来微信开放了miniprogram-ci,一个 Node.js 库,专门给持续集成用。我们用它的目的很直接:在终端里完成上传,不碰图形界面。

2.1 注册一个小程序账号,拿到 AppID

打开微信公众平台,选择“小程序”注册。个人主体也可以注册,比企业主体省事很多,不需要对公账户验证。注册完成后,在“开发管理 > 开发设置”里能看到AppID。这个 AppID 是唯一的,千万不能复制错,后面上传全靠它识别“你是谁”。

个人主体有一些限制,比如不能开通微信支付、部分类目不能选。但如果你只是做一个工具类小程序,或者先做体验版验证想法,个人主体完全够用。我身边不少独立开发者第一个产品都是用个人主体上的,后续要商业化再转企业主体。

2.2 生成代码上传密钥并设置 IP 白名单

这一步是很多人卡住的地方。在同一个“开发设置”页面往下拉,找到“小程序代码上传”区域,点击“生成”。微信会要求你填写一个密钥名称,然后下载一个.key文件。

这个私钥文件只下载一次,微信不会保存,丢了只能作废重新生成。下载后我习惯放到项目根目录的keys/文件夹里,并在.gitignore中把它排除掉。私钥就是你的发布凭证,一旦泄露,别人就能往你的小程序里传代码。

同时还要配置 IP 白名单。这里有个很容易踩的坑:你配置的服务器或本机公网 IP 不在白名单里,上传时会直接报错Error: ip not in whitelist。如果你用的是家用宽带,IP 可能经常变,建议把需要执行上传的机器 IP 加进去,或者干脆在能保持固定出口 IP 的服务器/CI 环境里跑上传。

2.3 安装 miniprogram-ci

在你的项目根目录执行:

npm init -y npm install miniprogram-ci --save-dev

这个库是微信官方发布的,不是第三方逆向产物,放心用。它会读取你本地的小程序工程目录,然后调用 HTTPS 接口,把代码打包上传。整个过程中不需要启动任何 IDE,也不需要你手动点“上传”按钮。

2.4 开发版、体验版、正式版怎么选

小程序的版本类型有三个,第一次用命令行的朋友容易搞混:

版本类型谁能看到用途
开发版该小程序账号的成员/开发者自己调试
体验版绑定的体验成员给产品、测试、身边朋友试用
正式版所有用户需要提交审核,审核通过后发布

建议刚开始时只上传“体验版”。因为体验版不需要微信审核,上传成功就能生成二维码,发给同事朋友试用。等产品稳定了,再提“正式版”审核。

3. 实战:一句“生成一个车牌号图片工具”到跑通的完整过程

空谈没有意义,我说一个真实做过的例子。你要解决的问题是:用户输入车牌号,点击按钮,生成一张看起来像“交警拍摄入场记录”的图片,能预览也能保存。这个需求非常适合用 AI 生成本地代码,因为不依赖后端,也没有复杂鉴权,纯 canvas 绘制。

3.1 一个能落地的提示词模板

我实际使用的提示词如下:

生成一个微信小程序工程。功能: 1. 首页有一个 input 输入框,用于输入车牌号; 2. 有一个按钮“生成图片”; 3. 点击按钮后,在页面 canvas 上绘制一张 750x400 的“入场记录”图片,背景是浅绿色渐变,中间显示车牌号文字,模拟新能源绿牌; 4. 图片生成后,显示在页面下方; 5. 提供“保存到相册”按钮; 6. 使用原生小程序语法,不要引入任何第三方组件库; 7. 不要请求任何网络接口,所有逻辑本地完成; 8. 适配 iPhone 底部安全区。

注意几个关键点:

  • 明确尺寸,避免 canvas 在不同手机上显示比例不对;
  • 明确“本地完成”,AI 就不会给你塞一个不存在的wx.request;
  • 明确“不要第三方组件库”,否则生成后的工程还要安装 npm 依赖,而你在没 IDE 的环境里处理依赖会很痛苦。

3.2 生成结果的“四件套”体检

AI 生成后,我一般先看四个文件:

  • project.config.json:确认 appid 是占位符还是真实值;
  • app.json:确认所有页面都注册了;
  • pages/index/index.wxml:看结构是否符合预期;
  • pages/index/index.js:看交互逻辑是否完整。

最容易出的问题在app.json。我有一次生成的代码里pages数组只有一项"pages/index/index",但工程目录里却有pages/pay这个页面。没什么大碍,不过如果 AI 给出了tabBar配置且指定了图标,容易踩坑:本地没有对应图标文件,预览时 Tab 栏图标空白,还会影响体验版二维码扫描后的显示。遇到这种情况,干脆把tabBar整段注释掉。

一个可用的最小app.json大概长这样:

{ "pages": [ "pages/index/index" ], "window": { "navigationBarTitleText": "车牌生成", "navigationBarBackgroundColor": "#ffffff" }, "style": "v2", "sitemapLocation": "sitemap.json" }

这里没有写permission、没有requiredBackgroundModes,因为我们的场景不需要。

3.3 canvas 绘制车牌的几个坑

车牌号生成工具的核心是 canvas 绘制。AI 会给你生成一段代码,但直接跑的失败率很高,我遇到过的坑有三个。

第一个坑:canvas 初始化时机。新版小程序推荐用<canvas type="2d" id="plateCanvas">,不能只依赖旧版wx.createCanvasContext。旧版 API 虽然还能用,但真机兼容性参差不齐。AI 生成时经常混用旧版,我建议统一改成 type="2d" 方案:先在wx.createSelectorQuery()中选中 canvas 节点,拿到canvas实例和ctx,再执行绘制。

第二个坑:字体和文字位置。车牌上的文字要在背景中间偏下,形成“牌照内文字”的视觉。AI 生成的绘制代码经常忽略ctx.font里的字号和字重,导致文字在真机上过于纤细。比较好的做法是固定值,比如ctx.font = "bold 80px sans-serif",然后通过ctx.measureText测量文字宽度,调整起始 x 坐标,保证文字水平居中。

第三个坑:canvas 导出图片。绘制完成后,要调用wx.canvasToTempFilePath把 canvas 转成临时图片文件,再设置到<image>上预览。很多 AI 生成的代码漏了这步,用户只看到 canvas 区域空着。检查一下生成的代码里有没有canvasToTempFilePath的调用,没有就补上。

3.4 保存图片到相册的授权链

“保存到相册”按钮背后有一整套授权链路。wx.saveImageToPhotosAlbum需要用户授权scope.writePhotosAlbum,没有授权时会直接走 fail 回调。

AI 生成的代码经常是:点按钮,直接wx.saveImageToPhotosAlbum。正确做法是:

  • 先调用wx.getSetting查看是否已授权;
  • 如果没授权,调用wx.authorize({ scope: "scope.writePhotosAlbum" })主动弹窗;
  • 用户拒绝后,再引导去wx.openSetting打开设置页手动开启。

这里要注意,2023 年后微信对隐私协议审核变严了。如果代码里声明了“保存到相册”能力,小程序管理后台也需要同步配置对应的隐私保护指引,告诉用户“我们将保存你生成的车牌图片到相册”。否则在提交审核时,会被判定为“未声明个人信息收集使用规则”。

4. 真正“不用开发者工具”的部分:命令行上传与自动发布

工程代码就绪,接下来是整篇文章最核心的地方:绕过图形化开发者工具,把代码推到微信服务器。

4.1 miniprogram-ci 为什么能绕过 IDE

微信开发者工具本质上是把本地工程打包,然后调用微信服务器提供的上传接口。既然有接口,就能用程序代替人点击。miniprogram-ci就是官方封装的 Node.js 版上传工具,它直接替代 IDE 的“上传”按钮。

在自动化链路里,AppID 是你的身份,私钥是你的密码,而miniprogram-ci就是那个替你按下“确认上传”的机器人。整个过程都在命令行里完成,所以标题说“不用开发者工具”,准确讲是“不用打开 IDE 图形界面”,背后的工程结构依然是微信原生小程序工程。

4.2 一个带注释的 upload.js

在项目根目录创建upload.js:

const ci = require("miniprogram-ci"); (async () => { const project = new ci.Project({ appid: "wx你的AppID", // 小程序 AppID type: "miniProgram", // 项目类型:普通小程序 projectPath: "./", // 小程序工程目录(含 project.config.json) privateKeyPath: "./keys/private.key", ignores: ["node_modules"], // 上传时忽略的目录 }); const result = await ci.upload({ project, version: "1.0.0", // 版本号,不能和线上已提交的重复太多 desc: "AI 生成的车牌图片工具", // 本次上传备注 setting: { es6: true, // ES6 转 ES5 minify: true, // 压缩代码 }, robot: 1, // 指定机器人编号 1-30,可并行上传多个项目 }); console.log("upload success:", result); })().catch((err) => { console.error("upload failed:", err); process.exit(1); });

执行:

node upload.js

如果看到upload success,说明代码已经躺在了微信服务器上。登录小程序后台,在“版本管理”里能看到刚上传的开发版记录。

这里有几个细节值得说:

  • projectPath建议用绝对路径或相对于upload.js的路径,避免在 CI 里因为工作目录变化找不到工程;
  • setting.es6打开后会有代码转译,如果小程序依赖某些高级语法,建议打开;
  • robot参数在团队协作时很有用,不同机器人上传的开发版互不干扰,不会出现一个人把另一个人的版本顶掉。

4.3 体验版二维码与试用反馈闭环

上传只是第一步,米还没煮熟。要让别人能用,需要把刚上传的代码设为体验版。在微信公众平台后台,找到刚上传的版本,点击“选为体验版”,然后获取体验版二维码,发给同事朋友。

如果你想连这一步都自动化,可以在upload.js里追加:

const previewResult = await ci.preview({ project, desc: "体验版预览", qrcodeFormat: "image", qrcodeOutputDest: "./preview-qrcode.jpg", });

生成二维码后,直接扔到群里,让同事扫。试用的反馈建议让他们集中填一个简单的在线文档:机型、系统、问题描述、截图。你不需要现在做一个反馈功能,一个表格足够。收集几天之后,把反馈分类:页面崩溃类的优先处理,样式类的排期修复,需求建议类的先记录。

4.4 把上传接进 Git 钩子或持续集成

项目迭代到后期,手动node upload.js还是显得繁琐。可以进一步把上传挂到 Git 提交钩子上。

举例:在.git/hooks/pre-push里写一段判断,当提交到main分支时自动执行:

#!/bin/sh while read oldrev newrev refname do if [ "$refname" = "refs/heads/main" ]; then node upload.js fi done

这样每次git push origin main,代码就自动上传为开发版。再接上 GitHub Actions,理论上可以实现“合并代码后自动上传体验版”。但从安全角度说,私钥不要直接提交进仓库,应该放在 CI 的 Secret 变量里,由 CI 在运行时读取并写入临时文件。

5. 上线前绕不开的审核细节与兼容性硬坑

AI 生成的代码能跑通、能上传,不代表能顺利过审。我见过太多人卡在“代码没问题但审核被拒”这一环。这一章把高频问题集中列一遍,都是硬货。

5.1 权限声明不是越多越好

AI 生成代码有个毛病:它喜欢“预留能力”。生成一个车牌号工具,它可能在某个没有被调用的组件里请求了地理位置权限,或者在app.json里写入了摄像头权限。一旦后台检测到代码里有权限声明或 API 调用,就会要求你添加隐私保护指引,审核时也会重点看。

我的做法是全局搜一下wx.authorize、wx.getLocation、scope.userInfo这些关键词,凡是用不到的全部清理。

以车牌生成工具为例,真正需要的权限只有一个“保存图片到相册”。记住一个原则:用户主动触发时再弹授权,进页面不弹权限。如果页面一加载就弹出“允许保存图片吗”,用户会反感,审核也可能以“频繁骚扰用户”为由驳回。

5.2 顶部导航栏与安全区适配

“微信小程序顶部导航栏高度”是个经典问题。导航栏在 iPhone 和 Android 上高度不同,刘海屏更复杂。普通页面用默认导航栏还好,系统自己会适配;一旦你用了navigationStyle: "custom",整条导航栏都得自己画,AI 生成的代码在这里经常翻车。

我一般不推荐新手自定义导航栏。非要自定义时,用官方胶囊按钮的位置反推导航栏高度:

const menu = wx.getMenuButtonBoundingClientRect(); // statusBarHeight 可通过 wx.getSystemInfoSync().statusBarHeight 获取 // 导航栏高度大约 = (menu.top - statusBarHeight) * 2 + menu.height

底部安全区更简单,用 CSS 环境变量:

padding-bottom: env(safe-area-inset-bottom);

生成代码如果漏了这条,iPhone 底部会有一段被手势条遮住,按钮点不到。审查时优先检查页面的底部按钮。

5.3 “加载更多”列表的实现

如果你的小程序里有一个列表页,AI 大概率会生成一个渲染全部数据的长页面,而不是分页加载。体验上有两个问题:数据量大了页面卡顿;上滑查看历史记录时无法触发翻页。

正确做法是利用页面的onReachBottom生命周期:

Page({ data: { list: [], page: 0, pageSize: 10, hasMore: true, }, onReachBottom() { if (!this.data.hasMore) return; this.loadNextPage(); }, loadNextPage() { const nextPage = this.data.page + 1; const start = nextPage * this.data.pageSize; const end = start + this.data.pageSize; const allData = this.data.allData || []; const newItems = allData.slice(start, end); if (newItems.length === 0) { this.setData({ hasMore: false }); return; } this.setData({ list: this.data.list.concat(newItems), page: nextPage, }); }, });

这段逻辑不复杂,但 AI 生成时经常遗漏hasMore判断,导致触底后反复加载空数据。建议在提示词里直接写明“列表需要通过 onReachBottom 分页加载”。

5.4 提交审核前必查清单

检查项说明
隐私保护指引后台配置了“用户隐私保护指引”吗
首页内容可用性打开小程序是不是空白页
权限弹窗时机是否一进入就弹授权
类目选择车牌工具建议选“工具-效率”,别选错类目
测试账号如果涉及登录,提供测试账号给审核员
版权合规生成的图片素材是否有版权风险

AI 生成的代码在功能上不容易出问题,但上面这些“非功能”项才是审核驳回的重灾区。我见过一个项目,功能完美,但因为类目选错了被卡了四天。所以每次提交前,打开后台检查一遍类目和隐私声明,完全值得。

6. 实际操作中的体会:AI生成加命令行发布的工作流复盘

最后聊点个人感受。

这套工作流我最常用的场景不是做“完整产品”,而是做“可行性验证”。想法在脑子里停留三天,不如用 AI 一小时生成一个体验版丢给朋友扫码。我最快的一次,从写提示词到体验版二维码出现在群里,只花了四十分钟。其中大部分时间不是等代码,而是在调 canvas 绘制和补充安全区样式。

但我也必须提醒一句:不用开发者工具,不代表不需要测试。命令行上传的只是代码包,真机上的表现如何、按钮触控区域有没有被遮挡、iOS 和 Android 字体渲染是否一致,这些在 IDE 模拟器里看不出来,更别说命令行。我的习惯是每上一次体验版,自己先用 iPhone 和一部 Android 手机各扫一遍,过一遍主流程,再发给别人试用。

还有一点很重要:AI 生成代码的速度会给人一种“上线很简单”的错觉,真正决定一个小程序能不能活下去的,还是你围绕这个工具设计的完整使用链路。举个例子,车牌号生成图片的工具,AI 两小时就完成了;但有没有考虑用户保存图片之后怎么分享、生成的图片是否需要加水印、连续生成多个车牌号会不会记录历史,这些才是产品差异点。代码是起点,不是终点。

如果你也是一个人负责需求、开发、发布,这套“AI 生成 + 命令行上传”的组合值得试试。先用一句话把一个最小可用版本跑上线,收集反馈后再决定要不要投入资源认真做。这比闷头开发两三个月再发布,要稳妥得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询