小兔鲜儿 UniApp 项目 - 第五周综合笔记
小兔鲜儿 UniApp 项目 - 第五周综合笔记
第五周学习内容,主要涵盖项目收尾阶段的工作:将开发完成的 uni-app 项目打包发布到不同平台。核心内容包括微信小程序打包全流程、条件编译处理多端差异、H5 端打包与路由配置。
一、微信小程序端打包与发布
1.1 整体流程
将 uni-app 项目发布为微信小程序,涉及三个工具的协作:
VSCode(编码 + 编译) --> 微信开发者工具(预览 + 上传) --> 微信公众平台(审核 + 发布)| 阶段 | 工具 | 做什么 |
|---|---|---|
| 编译 | VSCode / 命令行 | 执行pnpm build:mp-weixin,将 Vue 代码编译为原生小程序代码 |
| 调试 | 微信开发者工具 | 导入编译产物,本地预览、真机调试、性能检测 |
| 上线 | 微信公众平台 | 提交审核、灰度发布、正式上线 |
1.2 编译产物
执行pnpm build:mp-weixin后,项目根目录生成/dist/build/mp-weixin文件夹。这个文件夹就是微信小程序的原生代码包,包含:
app.js/app.json/app.wxss—— 小程序入口文件pages/—— 每个 Vue 页面对应一个原生页面文件夹(含 wxml、wxss、js、json)components/—— 组件编译后的原生代码static/—— 静态资源
需要注意的是,开发时使用的/dist/dev/mp-weixin是开发编译产物(含 sourcemap、未压缩),上线时必须使用/dist/build/mp-weixin。
1.3 微信开发者工具的正确导入
导入时容易搞混路径:
- 正确:选择
/dist/build/mp-weixin目录 - 错误:选择项目根目录(那是 uni-app 源码,不是小程序代码)
- 错误:选择
/dist/dev/mp-weixin(那是开发版,不能用于发布)
导入后需要填入 AppID。如果只是本地预览可以用测试号,但要上传发布必须使用已注册的小程序 AppID。
1.4 上传与审核
- 在微信开发者工具中确认预览效果无误
- 点击工具栏"上传",填写版本号(如 1.0.0)和备注
- 登录 微信公众平台,进入"管理 -> 版本管理"
- 在"开发版本"中找到刚上传的版本,点击"提交审核"
- 等待微信官方审核(通常 1-7 个工作日)
- 审核通过后点击"发布",用户即可搜索到该小程序
也可以配置 CI/CD 自动上传,微信官方提供了 miniprogram-ci 工具,适合团队协作场景下的自动化流程。
二、条件编译
2.1 为什么需要条件编译
uni-app 的核心理念是"一套代码,多端运行",但不同平台存在本质差异:
- 微信小程序有专属 API(
wx.login、wx.requestPayment、wx.chooseMedia) - 网页端没有微信授权能力,登录方式完全不同
- 小程序支持特殊的按钮属性(
open-type="getPhoneNumber"),H5 不支持 - 某些样式特性只在特定平台上生效
如果不在代码中做平台区分,轻则功能失效,重则编译报错。条件编译就是用来解决这个问题的。
2.2 基本语法
条件编译使用特殊的注释语法(这些注释在编译时会被处理,不是普通的代码注释):
// #ifdef 平台标识 // 只有在指定平台才保留的代码 // #endif // #ifndef 平台标识 // 只有在非指定平台才保留的代码 // #endif#ifdef相当于"如果定义了该平台"(if defined),#ifndef相当于"如果没定义该平台"(if not defined)。
支持多平台组合:
// #ifdef H5 || MP-WEIXIN // H5 端 或 微信小程序端都保留 // #endif2.3 条件编译的作用范围
条件编译几乎可以出现在项目的任何文件中:
| 文件类型 | 示例场景 |
|---|---|
.vue的<script> | 调用平台特有 API |
.vue的<template> | 使用平台特有组件或属性 |
.vue的<style> | 处理平台样式兼容 |
.ts/.js | 平台特有逻辑 |
pages.json | 不同平台的页面配置、tabBar 差异 |
.scss/.css | 不同平台的样式变量 |
2.4 实际应用场景
场景一:微信小程序特有 API
小程序提供了wx.login()、wx.requestPayment()等专属 API,在 H5 端调用会报错。这些调用需要用条件编译包裹:
// #ifdef MP-WEIXIN wx.login() wx.requestPayment() // #endif场景二:平台特有的按钮能力
小程序的<button>支持open-type属性实现特殊功能(获取手机号、打开设置、客服会话等),这些属性在 H5 端无效且可能引起警告:
<!-- #ifdef MP-WEIXIN --> <button open-type="openSetting">授权管理</button> <button open-type="feedback">问题反馈</button> <button open-type="contact">联系我们</button> <!-- #endif -->场景三:登录方式的差异化
这是项目中最大的条件编译应用。微信小程序使用wx.login()+getPhoneNumber实现一键授权登录,而 H5 端需要传统表单登录。整个登录页的模板结构在不同平台下完全不同,需要大段的条件编译区分。
场景四:样式兼容
page { /* #ifdef H5 */ background-color: #f5f5f5; // H5 端背景色 /* #endif */ /* #ifdef MP-WEIXIN */ background-color: #f7f7f8; // 小程序端背景色 /* #endif */ }场景五:pages.json 配置差异
H5 端通常不需要底部 tabBar(导航在顶部),小程序端则需要:
{ "tabBar": { // #ifdef MP-WEIXIN "list": [ { "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/cart/cart", "text": "购物车" }, { "pagePath": "pages/my/my", "text": "我的" } ] // #endif // #ifdef H5 "list": [ { "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/my/my", "text": "我的" } ] // #endif } }2.5 开发注意事项
- 条件编译注释必须以
//开头,不能使用/* */块注释 - 代码写完建议搜索项目中的
wx.、open-type等平台关键词,确保所有平台特有代码都已被条件编译包裹 - 条件编译的代码在不同的编译目标下会被完全移除(不是隐藏),所以不会增大其他平台的包体积
三、H5 端打包
3.1 编译与预览
pnpm build:h5编译产物在/dist/build/h5,是一个标准的静态网站目录结构:
index.html—— 入口文件static/js/—— 编译后的 JavaScriptstatic/css/—— 编译后的 CSSstatic/img/—— 图片资源
本地预览直接用浏览器打开index.html即可。但如果路由基础路径配置不对,可能会出现页面空白。
3.2 路由基础路径
manifest.json中h5.router.base决定了所有路由的前缀:
{ "h5": { "router": { "base": "./" } } }| 配置值 | 适用场景 |
|---|---|
"/" | 部署在域名根路径,如example.com/ |
"/app/" | 部署在子目录,如example.com/app/ |
"./" | 相对路径,兼容性最好,本地预览首选 |
如果部署后资源 404(JS/CSS 加载失败),首先检查base是否和服务端路径匹配。
3.3 H5 端与小程序端的主要差异
| 能力 | 微信小程序 | H5 |
|---|---|---|
| 微信登录 | 支持 | 不支持,需要自己实现 |
| 微信支付 | 支持wx.requestPayment | 不支持,需走 H5 支付或扫码支付 |
| 原生导航 | 有原生导航栏和 tabBar | 全部需要自己写 |
| 手机号授权 | 支持getPhoneNumber | 不支持 |
| 滚动驱动动画 | animate()方法 | 不支持,需用 CSS 或 JS 实现 |
| 文件上传 | uni.uploadFile | 可用 axios 或 fetch |
| 分包加载 | 支持 | 无此概念 |
| 包体积限制 | 主包 2MB,总包 20MB | 无限制(但体积过大会影响加载速度) |
这些差异就是条件编译需要处理的核心内容。项目开发的思路是以小程序为主要目标平台,把小程序不支持的功能在 H5 端降级或提供替代方案。
四、其他打包目标简介
4.1 打包为 APP 端
小兔鲜儿项目主要以小程序和 H5 为目标,APP 端的打包使用 HBuilderX 工具完成。打包 APP 时使用的是 App 端的条件编译标识APP-PLUS。
4.2 其他小程序平台
打包到其他小程序平台(百度、支付宝、字节跳动等)的流程类似,替换打包命令和对应的开发者工具即可。但需要注意:
- 不同平台的 API 支持程度不同,可能需要额外的条件编译
- 各平台的审核规范不同
- 包体积限制不同(如支付宝小程序主包限制 2MB)
五、TypeScript 补充
5.1 环境变量
import.meta.env.DEV // 开发模式为 true import.meta.env.PROD // 生产模式为 true项目中利用import.meta.env.DEV来区分开发/生产行为——支付模块在开发环境走模拟支付,生产环境走真实微信支付;模拟发货功能也只在开发环境显示。
5.2 Page 类型扩展
当 uni-app 的类型定义缺少某些平台特有方法时(如微信小程序的animate),需要通过类型扩展来补全:
// 基于小程序的 Page 类型扩展 uni-app 的 Page type PageInstance = Page.PageInstance & WechatMiniprogram.Page.InstanceMethods<any> const pageInstance = pages.at(-1) as PageInstance这种方式在保证类型安全的前提下,让 TypeScript 不再报错,同时 IDE 也能提供代码提示。
六、项目整体回顾
至此,小兔鲜儿 uni-app 项目的全部模块学习完成:
| 周次 | 模块 | 核心内容 |
|---|---|---|
| 第一周 | 项目起步 | uni-app 脚手架、pages.json 配置、条件编译基础 |
| 第二周 | 首页 & 分类 | 轮播图、分类导航、商品列表、下拉刷新 |
| 第三周 | 登录 & 用户 & 地址 & SKU | 微信授权、个人信息、地址管理、SKU 弹窗 |
| 第四周 | 购物车 & 订单 | 购物车 CRUD、订单流转、支付、物流 |
| 第五周 | 打包发布 | 小程序打包、H5 打包、条件编译总结 |
七、常见报错速查
| 问题 | 原因 | 解决 |
|---|---|---|
| 小程序运行白屏 | 导入目录错误 | 确认导入/dist/build/mp-weixin而非项目根目录 |
| 微信开发者工具正常,真机异常 | 条件编译遗漏 | 搜索wx.和open-type,确保有#ifdef包裹 |
| H5 端 wx is not defined | 小程序 API 未条件编译 | 所有wx.xxx用// #ifdef MP-WEIXIN包裹 |
| H5 本地预览空白 | 路由 base 为绝对路径 | 改为"./"相对路径 |
| 打包后 H5 资源 404 | base 与服务器路径不一致 | 按运维提供的路径调整h5.router.base |
animate方法 TS 报错 | uni-app 类型缺失 | 扩展 Page 类型:Page.PageInstance & WechatMiniprogram.Page.InstanceMethods<any> |
| 小程序上传失败 | 未配置 AppID 或不是管理员 | 在开发者工具中填入正确的 AppID |
| 真机预览"未找到页面" | 页面路径未注册 | 检查 pages.json 是否包含该页面 |
八、实用命令速查
# 微信小程序开发(热更新) pnpm dev:mp-weixin # 微信小程序打包 pnpm build:mp-weixin # H5 开发(热更新) pnpm dev:h5 # H5 打包 pnpm build:h5