用一套 Web 技术同时交付 iOS、安卓和微信里的 H5,这是 2018 年前后很多小团队的现实选择。Ionic 3 当时给的答案很完整:底下 Cordova 负责桥接原生,中间 Angular 负责应用架构,上层一套仿原生的 UI 组件库直接能用。缺点也很实在,链路长、坑多,从装环境到出一个能上架的包,中间能卡住的地方有几十处。
这篇是我做完一个完整的 Ionic 3 项目之后整理的笔记,从 ionic start 一直写到安卓签名包 zipalign 优化。内容偏工具书性质,可以顺着读一遍建立全貌,也可以卡住的时候回来查对应那一节。
没有
angular基础,先看一下这篇 Angular 入门梳理
在本篇文章中,我们将从浅入深,和大家一起学习以下知识:
Ionic和Cordova、Angular三者的分工,以及这个组合今天还剩多少价值- 浏览器、iOS 模拟器、安卓模拟器、微信四种环境分别怎么跑起来
Ionic 3的目录结构,哪些目录是源码、哪些是生成物不能手改- 页面生命周期钩子各自在什么时机触发,初始化代码该放哪个
- 相机、本地存储、二维码扫描、版本号读取这几个高频原生能力的完整接法
- 页面传参的两种写法、管道、主题夜间模式切换、自定义组件的完整实现
Loading/Toast/Modal怎么封装成基类,省掉每个页面重复的样板代码- iOS 和安卓两端打包上架的全流程,包含
Gradle环境配置和 apk 签名的每一条命令
# 零、先说清楚这套栈现在的状态
这篇写于 2019 年初,那时候 Ionic 3 还是主流选择。现在情况变了,动手之前先知道这几件事,省得走弯路。
Ionic 3 已经是好几个大版本之前的东西了,Ionic 4 起底层组件重写成了 Web Components,路由交还给 Angular Router,跟 3 之间是断代式的差异,两版之间怎么迁我单独写了一篇 Ionic3 升级 Ionic4 变更对比。
Apache Cordova 现在也不再活跃维护了,项目退役进了 Apache Attic 归档,具体以 https://attic.apache.org/ 上的官方公告为准。Ionic 官方推的替代方案是自家的 Capacitor,思路一致,但原生工程当作源码提交进仓库管理,不像 Cordova 每次 prepare 重新生成。
那这篇留着干什么?两个理由。一是存量项目还在跑,出问题得有地方查;二是这里面至少有一半内容跟 Ionic 版本无关,比如安卓签名打包那一整套 keytool / jarsigner / zipalign 命令,比如 iOS 的证书和上架流程,比如 Gradle 环境变量配置,这些换成 Capacitor、React Native 甚至纯原生也是同一套。真正过时的只有 ionic-angular 那些 API 写法,我会在对应位置标出来。
# 一、介绍
Ionic是一款基于Angular、Cordova的强大的HTML5移动应用开发框架 , 可以快速创建一 个跨平台的移动应用。可以快速开发移动App、移动端WEB页面、微信公众平台应用,混 合app web页面。
# 1.1 ionic 特点
ionic基于Angular语法,简单易学。ionic是一个轻量级框架。ionic完美的融合下一代移动框架,支持Angularjs的特性,MVC,代码易维护。ionic提供了漂亮的设计,通过SASS构建应用程序,它提供了很多 UI 组件来帮助开发者开发强大的应用。ionic专注原生,让你看不出混合应用和原生的区别ionic提供了强大的命令行工具。ionic性能优越,运行速度快。
这几条是官方口径下的卖点,我按当年的原文保留。以今天的眼光补两句实话:「性能优越、看不出和原生的区别」这个说法要打折扣,Ionic 3 的页面跑在 WebView 里,简单的列表和表单确实流畅,但长列表滚动、复杂手势、大量动画同时进行的场景,跟原生的差距是能感觉到的。选型时按你的 App 是「内容展示为主」还是「重交互」来判断,前者完全够用,后者别硬上。
# 1.2 Ionic 和 Cordova(phonegap)、Angular 关系
ionic=Cordova+Angular+ionic CSS
Ionic是完全基于谷歌的Angular框架,在Angular基础上面做了一些封装,让我们可以更快 速和容易的开发移动的项目。Ionic调用原生的功能是基于Cordova,Cordova提供了使用JavaScript调用Native功能,ionic自己也封装了一套漂亮的CSS UI库。
这个等式值得多花两分钟拆开看,因为它决定了你后面遇到问题该去哪个文档里查。
Angular 管的是应用架构:组件、模块、依赖注入、RxJS。你写的绝大多数代码其实是 Angular 代码,报的错也多半是 Angular 的错,遇到 No provider for XXX、Can't bind to 'ngModel' 这类,去 Angular 文档里找。
Cordova 管的是原生桥接和打包。它把你的静态资源塞进一个原生壳子,同时提供插件机制让 JS 能调相机、定位这些。所有跟「装不上」「调不到原生能力」「打包失败」相关的问题,都在这一层。
ionic CSS 和那套组件管的是外观和交互。ion-list、ion-card、ion-refresher 这些标签属于这层,样式不对、组件用法不对,去 Ionic 的组件文档查。
分清楚这三层之后,排查效率会高很多。我一开始就是不分层,什么问题都去搜「ionic xxx 报错」,搜出来一堆不相干的答案。
# 二、环境搭建
这一节把四种运行环境(浏览器、iOS、安卓、微信)挨个跑通。建议按顺序来,浏览器最快,跑通它至少证明你的代码是好的,后面出问题就可以专心排查平台侧。
# 2.1 Ionic初始化构建
# 全局安装
npm install -g ionic
ionic info(查看当前ionic的全部版本信息)
装完先跑一下 ionic info,它会把 Ionic CLI、框架版本、Cordova 版本、平台、Node、Xcode 全列出来。

这条命令的价值在于它是排查环境问题的第一现场。装插件失败、打包报错、别人的解决方案在你这不生效,多半是某个版本对不上,先跑它,再对照文档看版本要求。往论坛提问的时候贴上这段输出,回复效率也会高很多。
ionic start myApp tabs # 建议使用初始化
cd myApp
ionic serve
tabs 是模板名。可选的还有 blank(空白)、sidemenu(侧边栏),起手用 tabs 最省事,因为底部导航、页面结构、路由都给你搭好了,照着改就行。

ionic serve运行项目
ionic serve 起的是一个带热更新的本地开发服务器,改代码浏览器自动刷新。日常开发九成时间应该待在这里,别动不动就上真机,那一圈跑下来至少一两分钟。
# 2.2 Genymotion 安卓模拟器
Genymotion 是第三方的安卓模拟器,当年比 Android Studio 自带的 AVD 快不少,把 apk 直接拖进窗口就能装。现在官方 AVD 在硬件加速开启后已经够快了,用哪个看习惯。要提醒的是模拟器上相机、蓝牙、推送这些原生能力要么不可用要么是假数据,调这些必须上真机。
# 2.3 在IOS环境下体验
需要配备
mac,安装xcode
# mac下需要添加sudo
sudo ionic cordova platform add ios
# 注意获取目录权限的问题
chmod -R 777 项目文件夹名
真机调试与发布需要
Apple开发者账号
那个 chmod -R 777 是在解决什么?因为前面用 sudo 加平台,生成出来的目录属主是 root,你当前用户没有写权限,Xcode 打不开工程。更干净的解法是把属主改回自己(sudo chown -R $(whoami) ./platforms ./plugins),然后往后别再用 sudo 跑 ionic 命令,不然过两天又是同样的问题。
打开xcode选择platform下中ios文件夹,点击运行项目

有一点必须记牢:platforms/ 目录是生成物,不是源码。你在 Xcode 里直接改里面的文件,下次 cordova prepare 或者删平台重加就全没了。真要改原生配置,正确的位置是根目录的 config.xml,或者写 hooks 脚本。这个我踩过,改完 Info.plist 打包发现权限描述又没了,反复三次才想明白是被覆盖了。
iOS 从真机调试到打包上架那一整套证书流程,我单独写了一篇 Ionic 的 iOS 打包与上架流程,这里不重复。
# 2.4 在安卓下体验
1. 添加android
ionic cordova platform add android
# 注意获取目录权限的问题
chmod -R 777 项目文件夹名
# 直接使用Android studio 进行调试链接
# 打包成apk拖入Genymotion调试
2. 下载android studio 打开/platform/andriod文件
导入的时候选 platforms 下的 android 目录,不是项目根目录,选错了 Gradle 根本识别不出来。

第一次导入基本都会卡在 Gradle 同步上,因为它要去下载 wrapper 和一堆依赖。国内网络下最有效的两招是给 build.gradle 换阿里云的 maven 镜像,以及把 gradle-x.x-all.zip 手动下下来改成本地路径(具体怎么改见后面 12.5.2 节)。同步进度条在动就是在下载,耐心等;完全不动多半是网络断了。
3. 然后连接android studio结合geny生成apk调试

真机连不上的情况也常见,多半是电脑上装了手机助手类软件抢占了 adb 端口。先把它们全关掉,跑一次 adb kill-server && adb devices 重启服务,再确认手机上开了 USB 调试并点了「允许调试」的确认框。
# 2.5 在浏览器/微信下体验
这一节容易被忽略,但对很多项目来说价值很高:同一份代码可以直接打成静态站点部署,微信里、浏览器里都能访问,等于免费多了一个投放渠道。
1. 添加browser文件夹
ionic cordova platform add browser
browser 也是一个 Cordova 平台,跟 ios、android 平级。加它的意义在于产物里会带上 cordova.js 的浏览器实现,那些原生插件调用不会直接报错炸掉,而是走降级逻辑。
2. 打包
ionic cordova build browser

3. 运行
npm run serve
# 浏览器打开 http://localhost:8100
4. 部署
把
www目录部署到服务器上即可
在微信下体验 注意微信
title问题
「微信 title 问题」这句原文写得简,展开说一下:微信的内置浏览器在 iOS 上加载页面时会锁住标题栏,页面里后续用 document.title = 'xxx' 改标题是不生效的。社区的通用绕法是用一个隐藏的 iframe 加载一个同域小文件,触发微信刷新标题: