目录
5.1.1 .env.development / .env.production
5.1.2 修改 vite.config.ts,增加 base
5.2.1 如何使用 Live Server,测试打包效果?
5.3.1.1 打包时,依赖解析失败,会导致添加 android 平台失败
5.3.2 构建、同步原生app资源,打开 Android Studio
5.3.2.3 执行 ionic cap sync 后 在 Android Studio 中报错
5.3.2.4 升级完 Android Studio 后,找不到相关依赖
5.4.1 打包报错 vue-tsc 解决方案,调整 package.json 打包配置,删除 vue-tsc
5.4.4 打包后,图片地址能单独打开,但是在页面里又不显示
5.4.7 添加 file-transfer 插件后,打包报错乱码
5.4.8 解决 android.support.v4.app.CoreComponent... 插件版本不匹配的问题
解决方案一(使用 jetifier 将项目中的 android.support.v4 代码转换成 androidx)
5.4.9 解决 Android SDK 版本 和 打包工具版本 不匹配导致的报错
为什么要尽量保持 compileSdkVersion 和 buildToolsVersion 版本一致?
Android SDK Build Tools 打包工具安装
查看 Andorid Studio 中的虚拟机 所用的 Android 版本信息
解决 cordova-camera 插件点击拍照后,app闪退、报错非法参数的问题
为什么在 org.apache.cordova 中,找不到 imagepicker 插件?
nvm install 16.20.2
npminstall -g @ionic/cli@latest
ps:某个平常的清晨,我的 ionic 自动从7掉到了6,导致我 7 的项目运行不起来了,而且还装不上7,最后重启就自动恢复成7了,so...遇事别慌,重启试试
ionic start weihai-patrol-app tabs --type vue
之前的 ionic 项目,index.html 都是在 public 下面的
最新版的 ionic7,因为采用 vite,所以 index.html 在根目录下,而不是 public 下
新建 config.js 用于存放 ip,该文件需要在 index.html 中引入
目前两个 config.js 缺一不可,需要保持一致
之所以要全局设置,是因为项目运行起来后,默认展示 Android 样式,刷新后才展示 IOS 样式
在 Ionic 7 + Vue 3 + Vite 项目中
- import { createApp } from 'vue';
- import { IonicVue } from '@ionic/vue';
- import App from './App.vue';
- import router from './router';
- const app = createApp(App)
- .use(IonicVue, { mode: 'ios' }) // 设置默认全局使用 iOS 样式
- .use(router);
- router.isReady().then(() => {
- app.mount('#app');
- });
使用原因:日历组件默认展示英文
- // 添加 elementplus 国际化
- import ElementPlus from 'element-plus';
- import zhCn from 'element-plus/dist/locale/zh-cn.mjs';
- import * as ElementPlusIconsVue from '@element-plus/icons-vue';
-
- const app = createApp(App)
- .use(ElementPlus, {
- locale: zhCn,
- });
为啥我不用 ionic 的日历组件呢?
路由,虽然我很想拆分,但打包 h5 的时候:
这一节可以结合下面的打包遇到的问题一块看
如果有大佬可以帮忙解决这个问题,请联系我,感恩的心
- import { createRouter, createWebHashHistory, createWebHistory } from '@ionic/vue-router';
-
- // 可以使用 require 时,才能用下面的方法
- // // 自动添加router目录下的所有ts路由模块
- // const files = require.context('./', false, /\.ts$/);
- // files.keys().forEach((route) => {
- // // 如果是根目录的 index.js、 不做任何处理
- // if (route.startsWith('./index')) {
- // return;
- // }
- // const routerModule = files(route);
- // // 兼容 import export 和 require module.export 两种规范 ES modules commonjs
- // routes.push(...(routerModule.default || routerModule));
- // });
-
- /**
- * 接所有路由文件导出的内容
- * @description 不能使用 require 时,采用此方法
- * @param routeFiles 路由文件对象数组
- * @returns
- */
- const importAll = async (routeFiles: any) => {
- // console.log('路由文件对象数组 ---', routeFiles);
-
- // 拼接好的最终路由配置
- const routes = [];
- // 遍历路由配置文件
- for (const path in routeFiles) {
- // console.log('path 路由文件名', path);
- const routeModule = await routeFiles[path]();
- console.log('routeModule 路由文件导出内容', routeModule);
- const route = routeModule?.default || routeModule;
- // 将导出的数组填充到最终数组中
- route.forEach((elem: any) => routes.push(elem));
- }
- return routes;
- };
-
- // 使用动态导入来导入所有路由文件
- const routeFilesArr = import.meta.glob('./*.ts');
-
- // 拼接所有路由文件导出的内容
- const routes = await importAll(routeFilesArr);
-
- // 创建路由实例(Hash 路由)
- const router = createRouter({
- history: createWebHashHistory(import.meta.env.BASE_URL),
- routes,
- });
-
- export default router;
打包分为两种,一种是 h5 包,一种是移动端
注意事项:
- 这两个文件名字是固定的
- 打 h5包 时需要新增,打 移动端包 时需要移除
patrol-app\.env.development
- NODE_ENV=development
-
- VITE_BASE_PATH='/'
patrol-app\.env.production
- NODE_ENV=production
-
- BASE_URL=/weihai-patrol/
注意事项:
- h5 改成 /weihai-patrol/
- 移动端改成 ./
-
- /**
- * 判断是否是生产环境
- * @returns {boolean}
- */
- function isProd() {
- return process.env.NODE_ENV === 'production';
- }
-
- base: '/weihai-patrol/',
- // 解决打包不知道干啥的
- build: {
- minify: 'terser',
- terserOptions: {
- compress: {
- // drop_console: true,
- drop_debugger: true,
- },
- },
- },
添加完打包相关的文件后(注意在 vite.config.js 中使用的 base 相对路径),直接执行 yarn build 就行
将生成的 dist 目录,cv 到当前打开的 vscode 里,和当前项目同级
把 dist 改名成 weihai-patrol,右击 index.html,使用 live server 打开
添加完打包相关的文件后(注意在 vite.config.js 中使用的 base 相对路径),还要执行下面的操作
ionic capacitor add android
添加成功是这种感觉:
执行完毕后:
解决方案:这个包是用来进行 vue 单元测试的,直接移除安装吧
npm uninstall @vue/cli-plugin-unit-jest
ionic cap sync
构建成功是这种感觉:
此时,会自动打开 android studio,自动执行 gradle 下载
Gradle 是一个开源的构建自动化工具,它被广泛用于 Android 开发中,用于构建和管理 Android 应用程序的构建过程
在 Android 开发中,Gradle 被用作 Android 项目的构建工具。它可以编译源代码、处理资源文件、打包生成 APK 文件,并支持多种构建变体和构建类型。通过 Gradle,你可以轻松地管理和配置你的 Android 项目的构建过程,包括添加第三方库、处理多渠道打包、配置签名等
修改下载源
- maven { url 'https://maven.aliyun.com/repository/google' }
- maven { url 'https://maven.aliyun.com/repository/jcenter' }
- maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
Cannot convert string value 'UNIFIED_TEST_PLATFORM' to an enum value of type 'com.android.builder.model.AndroidGradlePluginProjectFlags$BooleanFlag' (valid case insensitive values: APPLICATION_R_CLASS_CONSTANT_IDS, TEST_R_CLASS_CONSTANT_IDS, TRANSITIVE_R_CLASS, JETPACK_COMPOSE, ML_MODEL_BINDING)
升级 Android Studio 版本就行
根据下面的报错信息:下载源找不到相关路径,因此,我把下载源切回了 google,然后打包正常了
也可能是因为多注释了:mavenCentral()
这个问题我是玄学解决的,我不懂为啥……,把 history 路由改成 hash 就好了
一般打包成 h5 都需要替换成 hash 路由
- // 创建路由实例
- const router = createRouter({
- // history: createWebHistory(import.meta.env.BASE_URL),
- history: createWebHashHistory(import.meta.env.BASE_URL), // 使用哈希路由模式
- routes,
- });
出现原因:
- const importAll = async (routeFiles: any) => {
- // console.log('路由文件对象数组 ---', routeFiles);
-
- // 拼接好的最终路由配置
- const routes = [];
- // 遍历路由配置文件
- for (const path in routeFiles) {
- // console.log('path 路由文件名', path);
- const routeModule = await routeFiles[path]();
- // console.log('routeModule 路由文件导出内容', routeModule);
- const route = routeModule.default || routeModule;
- // 将导出的数组填充到最终数组中
- route.forEach((elem: any) => routes.push(elem));
- }
- return routes;
- };
不用路由分组,不用 await
npm install vite-plugin-top-level-await -D --force
vite-plugin-top-level-await - npm
解决 vite build打包报错Top-level await is not available in the configured target environment - 简书
使用了这个插件之后,打包确实不报错了,但是打包后预览:
检查是不是使用了 IonImg 标签,并且没有 import,没 import 就会把他当成 html 标签处理,自然无法解析
项目中应该有两份 assets、config.js
第一份在 public 下面
第二份在 根目录下面放个 config.js、在 src/assets 下面放静态资源
二者保持一致,缺一不可,一个是打包的时候会读取,一个是运行项目的时候会读取
把下面的删了就行
解决方案:https://www.cnblogs.com/dndt/p/17133266.html
- // import org.apache.cordova.Whitelist;
- import org.apache.cordova.AllowList;
- // Whitelist whitelist = (Whitelist)gwl.invoke(webView);
- // shouldAllowRequest = whitelist.isUrlWhiteListed(source);
-
- AllowList whitelist = (AllowList)gwl.invoke(webView);
- shouldAllowRequest = whitelist.isUrlAllowListed(source);
在项目中,按顺序执行下方命令:
npm install jetifier
npx jetifynpx cap sync android
此时代码已经同步到 Android Studio 中了,不需要再执行 ionic cap sync 了
但是这种方法可能转换失败,转换无效,就要考虑第二种方法了
Andorid SDK Buid Tools —— 是一组用于构建和打包 Android 应用程序的工具集合。它提供了一系列的命令行工具和构建脚本,用于编译、打包和签名Android应用程序。
compile sdk —— 在 Android Studio 中,compileSdkVersion 是指定你的应用程序编译时使用的Android SDK版本的设置。它决定了你的应用程序可以使用的 Android API 级别和功能。
总之,尽量保持 compileSdkVersion 和 buildToolsVersion 版本一致可以确保构建工具和编译时使用的SDK版本之间的兼容性,并提供一致性、稳定性和最新功能的好处。
点击这里,会列出所有可以安装的版本
比如下面,可以选择安装 Andorid SDK Buid Tools34 版本的,每个版本差不多几百兆
再比如下面,可以选择安装 Android 12 版本的,有了这个,就可以使用指定版本的 虚拟机了
右键点击项目 android,选择 Modules,如下图所示,会列出当前项目拆分的不同模块,可以这么理解:
首先是在 node_modules 里,搜索了上面的非法参数报错,找到了他在 CameraLauncher.java 文件里
在 Andorid Studio 中找到这个文件:找 org.apache.cordova 这个包,下面很轻松就看到 camera 了
在代码里行号旁边,点一下,出现一个红点,表示断点
点击下图右上角,小虫子,表示开启调试,此时链接手机后,会自动安装app
点击执行断点的地方,比如拍照按钮,就会进入这个方法,这个过程会比较卡
点击下面终端的红框内第一个按钮,表示进入方法,逐行调试
这个 org.apache.cordova 是个包名,是作者可以自定义的东西,所以他不一定按照规范来
虽然在 node_modules 中,这个插件看起来好像是 cordova 的插件
但是,他的真实包名,可以看 node_modules 下的 plugin.xml 文件
随便找个文件,target-dir 标识了作者写的包名
在 android 包里,也顺利的找到了
xml 文件,在 cordova 里通常用于放一些 常量配置,比如国际化语言啊之类的
找到 node_modules 里面的这个插件,寻找 xml 文件,修改遇到问题的文字
当执行 ionic cap sync 的时候,会把 node_modules 编译到 android 文件夹下面,两者内容有相似的地方(比如 java 文件,可以进行调试),也有不同的地方
一般情况下: