1.背景
公司项目采用 UniApp(Vue 2.x)开发,为了支持流水线打包和灵活控制版本,选择使用 安卓离线打包方式,自定义原生基座。
2.环境和前置配置
设备:mac mini m2 16+512
node 版本:v18.20.8
Android studio版本:(用的最新版本)
根据 开发环境 | uni小程序SDK配置好离线打包,跑通流程后,在这个基础上稍微做下调整即可。
如果不知道uniapp 离线appkey,没有申请的请参考官方文档申请 | uni小程序SDK
Hbuilderx 版本:4.57正式版本
离线基座版本:4.57正式版本(4.57.2025032405)
3.安卓工程介绍(熟悉安卓原生开发的可以略过)
可以把HBuilder-Integrate-AS 文件夹下面的内容放入git 下的基座仓库:
现在直接拖入Android studio开始配置安卓环境
配置安卓环境最重要是配置gradle 版本:
由于官方文档中告知

所以离线基座的gradle 版本是

1.第一步:
建议替换腾讯镜像
distributionUrl=https\://mirrors.tencent.com/gradle/gradle-8.11.1-bin.zip
或者通过Index of /gradle/下载到本地

然后配置jdk 版本,根据HBuilderX 4.41 官方要求,必须要jdk 配置到17,不然会报错。
以前的版本大多都是jdk 1.8或jdk 11 因为gralde 大多是6.5 版本 (JDK 1.8 + AGP 4.1.3 + Gradle 6.5 老配置,4.41后官方原生离线sdk不可用)Android Gradle Plugin 8.0+ 需要 JDK 17 起步。
2.第二步:配置jdk:

默认应该是21建议用17
3.simpleDemo/build.gradle 文件配置包名 版本号 证书密钥
版本号对应
4.simpleDemo/src/main/AndroidManifest.xml 配置基座权限(蓝牙,相机相册,manifest.json中的权限复制过来去掉引号反斜杠)


底部配置配置dcloud 离线打包配置中的AppKey(如不知道怎么生成请看顶部)
5.simpleDemo/src/main/assets/data/dcloud_control.xml 文件修改配置appId
6.simpleDemo/src/main/res 配置APP icon 和名称

4.uniapp vue/cli 项目配置
vue/cli 5.0.8
vue2.0
按照官方方法配置即可
uni-app官网
网上有很多人说vue/cli 5.x.x 会报错可以按照下面的链接配置
使用cli 创建使用vue2 uniapp的项目(防止再次踩坑)_vue2使用uniapp-CSDN博客
我这边只有警告暂无报错,如果有什么问题可以回复我
qingyunzu@qingyunzudeMac-mini uniapp_qyz_h5 % npm install
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: vue-loader@15.11.1
npm warn Found: css-loader@6.11.0
npm warn node_modules/@vue/vue-loader-v15/node_modules/css-loader
npm warn
npm warn Could not resolve dependency:
npm warn peer css-loader@"*" from @vue/vue-loader-v15@15.11.1
npm warn node_modules/@vue/vue-loader-v15
npm warn @vue/vue-loader-v15@"npm:vue-loader@^15.9.7" from @vue/cli-service@5.0.8
npm warn node_modules/@vue/cli-service
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: css-loader@2.1.1
npm warn Found: webpack@5.98.0
npm warn node_modules/webpack
npm warn peer webpack@"^4.0.0 || ^5.0.0" from @soda/friendly-errors-webpack-plugin@1.8.1
npm warn node_modules/@soda/friendly-errors-webpack-plugin
npm warn @soda/friendly-errors-webpack-plugin@"^1.8.0" from @vue/cli-service@5.0.8
npm warn node_modules/@vue/cli-service
npm warn 19 more (@vue/cli-plugin-babel, babel-loader, @vue/cli-service, ...)
npm warn
npm warn Could not resolve dependency:
npm warn peer webpack@"^4.0.0" from css-loader@2.1.1
npm warn node_modules/css-loader
npm warn css-loader@"^2.1.1" from @hap-toolkit/dsl-vue@0.6.13
npm warn node_modules/@hap-toolkit/dsl-vue
npm warn 1 more (vue-loader)
npm warn
npm warn Conflicting peer dependency: webpack@4.47.0
npm warn node_modules/webpack
npm warn peer webpack@"^4.0.0" from css-loader@2.1.1
npm warn node_modules/css-loader
npm warn css-loader@"^2.1.1" from @hap-toolkit/dsl-vue@0.6.13
npm warn node_modules/@hap-toolkit/dsl-vue
npm warn 1 more (vue-loader)
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: url-loader@2.3.0
npm warn Found: webpack@5.98.0
npm warn node_modules/webpack
npm warn peer webpack@"^4.0.0 || ^5.0.0" from @soda/friendly-errors-webpack-plugin@1.8.1
npm warn node_modules/@soda/friendly-errors-webpack-plugin
npm warn @soda/friendly-errors-webpack-plugin@"^1.8.0" from @vue/cli-service@5.0.8
npm warn node_modules/@vue/cli-service
npm warn 19 more (@vue/cli-plugin-babel, babel-loader, @vue/cli-service, ...)
npm warn
npm warn Could not resolve dependency:
npm warn peer webpack@"^4.0.0" from url-loader@2.3.0
npm warn node_modules/url-loader
npm warn url-loader@"^2.1.0" from @hap-toolkit/dsl-vue@0.6.13
npm warn node_modules/@hap-toolkit/dsl-vue
npm warn
npm warn Conflicting peer dependency: webpack@4.47.0
npm warn node_modules/webpack
npm warn peer webpack@"^4.0.0" from url-loader@2.3.0
npm warn node_modules/url-loader
npm warn url-loader@"^2.1.0" from @hap-toolkit/dsl-vue@0.6.13
npm warn node_modules/@hap-toolkit/dsl-vue
up to date, audited 1885 packages in 20s
151 packages are looking for funding
run `npm fund` for details
82 vulnerabilities (8 low, 55 moderate, 13 high, 6 critical)
To address issues that do not require attention, run:
npm audit fix
To address all issues possible (including breaking changes), run:
npm audit fix --force
Some issues need review, and may require choosing
a different dependency.
Run `npm audit` for details.
qingyunzu@qingyunzudeMac-mini uniapp_qyz_h5 %
这里是基本目录。
执行npm run 打包出来vue.config.js 配置环境变量
const path = require('path');
const TransformPages = require("uni-read-pages");
const TerserPlugin = require('terser-webpack-plugin');
const portfinder = require("portfinder");
const {
version
} = require("./package.json");
const {
webpack
} = new TransformPages();
// 获取运行参数
const appType = process.env.VUE_APP_TYPE || 'QYZ_APP';
const envConfig = require(`./src/config/platform/env.${appType.toLowerCase()}.js`);
const ENV_MODE = process.env.VUE_APP_MODE || 'tc1';
const rawEnv = envConfig[ENV_MODE];
const isDev = process.env.NODE_ENV === 'development';
// 拼接版本信息
Date.prototype.Format = function(fmt) {
const o = {
"M+": this.getMonth() + 1,
"d+": this.getDate(),
"h+": this.getHours(),
"m+": this.getMinutes(),
"s+": this.getSeconds(),
"q+": Math.floor((this.getMonth() + 3) / 3),
S: this.getMilliseconds()
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, this.getFullYear() + "");
for (const k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
return fmt;
};
const versionTime = new Date().Format("yyMMdd");
const enviroment = {
TC1: "TC1",
TC2: "TC2",
TC3: "TC3",
UAT: "UAT",
PRODUCTION: "PRODUCTION"
};
const versionName = `QYZ_${version}.${versionTime}(${enviroment[ENV_MODE]})`;
// 导出异步配置(用于动态端口)
module.exports = async () => {
const basePort = process.env.npm_config_port || 9000;
const port = await portfinder.getPortPromise({
port: basePort
});
let currentEnv = null
// 构造最终用于注入的环境变量
currentEnv = {
...rawEnv,
BASE_URL: rawEnv.BASE_URL,
XY_URL: rawEnv.XY_URL,
VUE_APP_MODE: ENV_MODE
};
console.log(`✅ 当前运行环境:${ENV_MODE}`);
console.log(`✅ 注入环境变量:`, currentEnv);
const BASE_PROXY_TARGET = rawEnv.BASE_URL || 'https://tc1-h5.qingyunzu.com/zyj-api-web/';
return {
publicPath: './',
outputDir: 'dist',
assetsDir: 'static',
productionSourceMap: false,
lintOnSave: true,
runtimeCompiler: false,
devServer: {
port,
open: false,
https: false,
proxy: {
'/api': {
target: BASE_PROXY_TARGET,
changeOrigin: true,
secure: false,
pathRewrite: {
'^/api': ''
}
}
}
},
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
console.log('✅ 使用了 TerserPlugin 进行代码压缩');
config.optimization = {
minimize: true,
minimizer: [new TerserPlugin({
terserOptions: {
mangle: true, // ✅混淆变量名
compress: true, // ✅ 只压缩
output: {
comments: false
}
}
})]
};
}
return {
stats: 'minimal',
plugins: [
new webpack.DefinePlugin({
'process.uniEnv': JSON.stringify(currentEnv),
ROUTES: webpack.DefinePlugin.runtimeValue(() => {
const tfPages = new TransformPages({
includes: ["path", "name", "aliasPath"]
});
return JSON.stringify(tfPages.routes);
}, true)
})
]
};
},
chainWebpack: config => {
config.resolve.alias
.set('@assets', path.resolve(__dirname, 'src/static'))
.set('@', path.resolve(__dirname, 'src'));
config.plugin("define").tap(args => {
args[0]["process.env"].versionName = JSON.stringify(versionName);
return args;
});
},
css: {
sourceMap: false,
loaderOptions: {
sass: {
prependData: `@import "@/uni.scss";`
}
}
},
parallel: require('os').cpus().length > 1,
transpileDependencies: [
// 'uview-ui',
]
};
};
可以配置多平台多环境
npm run xxx 命令以后 在dist/dev/app-plus/ 或者dist/build/app-plus/ 下面10几个文件
放入基座工程下面/simpleDemo/src/main/assets/apps/__UNI__xxxxx/www 目录底下
”xxxx“替换成appid ,直接运行原声工程,或者在基座工程上面打包点击后,下面outputs文件夹
下面会有.apk 文件,直接放入Hbuilderx dist/debug/文件下面