add pack rpk

This commit is contained in:
2026-07-01 14:39:47 +08:00
parent 913f3a474e
commit 603530ec9b
6 changed files with 9707 additions and 57 deletions
+4
View File
@@ -3,6 +3,10 @@ node_modules/
# 构建输出目录 # 构建输出目录
dist/ dist/
build/
# 临时目录
.temp_*/
# 日志文件 # 日志文件
*.log *.log
+31 -6
View File
@@ -22,8 +22,33 @@ src/
### 环境要求 ### 环境要求
- 安装 AIoT-IDEXiaomi Vela JS 应用的集成开发环境) - Node.js 14+
- 支持 Ubuntu、Windows、MacOS 等操作系统 - npm
- 系统安装了 OpenSSLrelease 模式需要)
### 安装依赖
```bash
npm install
```
### 构建 rpk 文件
**开发模式构建**(生成 `.debug.rpk`):
```bash
npm run build
```
或直接:
```bash
node build.js
```
**生产模式构建**(生成 `.release.rpk`,需要签名文件):
```bash
npm run build:release
```
构建成功后,rpk 文件会输出到 `dist/` 目录。
### 运行应用 ### 运行应用
@@ -31,10 +56,10 @@ src/
2. 启动模拟器 2. 启动模拟器
3. 运行项目查看效果 3. 运行项目查看效果
### 打包应用 或使用命令行:
```bash
1. 在 AIoT-IDE 中使用打包功能 npm start
2. 生成安装包(.rpk 文件) ```
## 应用特点 ## 应用特点
+170 -48
View File
@@ -1,70 +1,192 @@
/** /**
* 构建脚本 * 构建脚本
* 用于构建 Xiaomi Vela JS 应用 * 用于构建 Xiaomi Vela JS 应用,生成 .rpk 安装包
*
* 使用方式:
* node build.js # 开发模式构建(生成 .debug.rpk
* node build.js --release # 生产模式构建(生成 .release.rpk,需要签名文件)
*/ */
const { execSync } = require('child_process');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
// 源目录 // ========== 配置 ==========
const srcDir = path.join(__dirname, 'src'); const projectDir = __dirname;
const srcDir = path.join(projectDir, 'src');
const distDir = path.join(projectDir, 'dist');
const signDir = path.join(projectDir, 'sign');
const isRelease = process.argv.includes('--release');
// 输出目录 // ========== 辅助函数 ==========
const distDir = path.join(__dirname, 'dist');
// 创建输出目录 /**
if (!fs.existsSync(distDir)) { * 执行命令并打印输出
fs.mkdirSync(distDir); */
function run(cmd, options = {}) {
console.log(`\n> ${cmd}`);
try {
const output = execSync(cmd, {
cwd: projectDir,
stdio: 'inherit',
...options,
});
return output;
} catch (error) {
console.error(`命令执行失败: ${cmd}`);
process.exit(1);
}
} }
// 复制文件函数 /**
function copyFileSync(source, target) { * 检查 aiot CLI 是否已安装
let targetFile = target; */
function isAiotInstalled() {
try {
execSync('aiot --version', { cwd: projectDir, stdio: 'pipe' });
return true;
} catch {
return false;
}
}
// 如果目标是一个目录,则在目录中创建同名文件 /**
if (fs.existsSync(target)) { * 检查 node_modules 是否存在且 aiot-toolkit 已安装
if (fs.lstatSync(target).isDirectory()) { */
targetFile = path.join(target, path.basename(source)); function isNodeModulesReady() {
const aiotBin = path.join(projectDir, 'node_modules', '.bin', 'aiot');
if (process.platform === 'win32') {
return fs.existsSync(aiotBin + '.cmd');
}
return fs.existsSync(aiotBin);
}
/**
* 安装项目依赖
*/
function installDependencies() {
console.log('\n📦 正在安装项目依赖...');
run('npm install');
}
/**
* 生成签名文件(用于 release 模式)
*/
function generateSignFiles() {
if (!fs.existsSync(signDir)) {
fs.mkdirSync(signDir, { recursive: true });
}
const privateKey = path.join(signDir, 'private.pem');
const certificate = path.join(signDir, 'certificate.pem');
if (fs.existsSync(privateKey) && fs.existsSync(certificate)) {
console.log('✅ 签名文件已存在,跳过生成');
return;
}
console.log('\n🔐 正在生成签名文件...');
const cmd = `openssl req -newkey rsa:2048 -nodes -keyout ${signDir}/private.pem -x509 -days 3650 -out ${signDir}/certificate.pem -subj "/CN=photo-viewer/O=Example/C=CN"`;
run(cmd);
}
/**
* 清理构建产物
*/
function cleanDist() {
if (fs.existsSync(distDir)) {
fs.rmSync(distDir, { recursive: true, force: true });
console.log('🧹 已清理 dist 目录');
}
}
/**
* 查找并展示构建产物
*/
function showBuildResult() {
if (!fs.existsSync(distDir)) {
console.error('❌ 构建失败:dist 目录不存在');
process.exit(1);
}
const files = [];
function walkDir(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
walkDir(fullPath);
} else if (entry.name.endsWith('.rpk')) {
const stats = fs.statSync(fullPath);
files.push({
path: fullPath,
size: (stats.size / 1024).toFixed(2),
});
}
} }
} }
fs.writeFileSync(targetFile, fs.readFileSync(source)); walkDir(distDir);
}
// 复制目录函数 if (files.length > 0) {
function copyFolderRecursiveSync(source, target) { console.log('\n✅ 构建成功!生成的 rpk 文件:');
let files = []; files.forEach((f) => {
console.log(` 📦 ${f.path} (${f.size} KB)`);
// 检查目标目录是否存在
const targetFolder = path.join(target, path.basename(source));
if (!fs.existsSync(targetFolder)) {
fs.mkdirSync(targetFolder);
}
// 检查源目录是否存在
if (fs.existsSync(source)) {
files = fs.readdirSync(source);
files.forEach(function (file) {
const curSource = path.join(source, file);
if (fs.lstatSync(curSource).isDirectory()) {
// 递归复制子目录
copyFolderRecursiveSync(curSource, targetFolder);
} else {
// 复制文件
copyFileSync(curSource, targetFolder);
}
}); });
} else {
console.warn('\n⚠️ 构建完成,但未在 dist 目录中找到 .rpk 文件');
console.log(' 请检查构建日志是否有错误信息');
} }
} }
// 开始构建 // ========== 主流程 ==========
console.log('开始构建 Xiaomi Vela JS 应用...');
try { function main() {
// 复制源文件到输出目录 const mode = isRelease ? '生产(release' : '开发(debug';
copyFolderRecursiveSync(srcDir, distDir); console.log(`\n🚀 Xiaomi Vela JS 应用构建工具`);
console.log('构建完成!'); console.log(`📋 构建模式: ${mode}`);
console.log('输出目录:', distDir); console.log(`📁 项目目录: ${projectDir}`);
} catch (error) {
console.error('构建失败:', error); // 1. 检查 src 目录
const manifestPath = path.join(srcDir, 'manifest.json');
if (!fs.existsSync(manifestPath)) {
console.error('❌ 未找到 src/manifest.json,请确认项目结构正确');
process.exit(1);
}
// 2. 安装依赖
if (!isNodeModulesReady()) {
installDependencies();
} else {
console.log('\n✅ 依赖已安装');
}
// 3. 检查 aiot 命令是否可用
if (!isNodeModulesReady()) {
console.error('❌ aiot-toolkit 安装失败,请手动运行 npm install');
process.exit(1);
}
// 4. 清理旧构建产物
cleanDist();
// 5. release 模式需要签名文件
if (isRelease) {
generateSignFiles();
}
// 6. 执行构建
console.log(`\n🔨 正在构建 rpk 文件...`);
if (isRelease) {
run('npx aiot release');
} else {
run('npx aiot build');
}
// 7. 展示构建结果
showBuildResult();
console.log('\n🎉 完成!');
} }
main();
+9491
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -5,7 +5,11 @@
"main": "build.js", "main": "build.js",
"scripts": { "scripts": {
"build": "node build.js", "build": "node build.js",
"start": "echo '请使用 AIoT-IDE 运行项目'" "build:release": "node build.js --release",
"start": "npx aiot start"
},
"dependencies": {
"aiot-toolkit": "^2.0.5"
}, },
"keywords": [ "keywords": [
"xiaomi", "xiaomi",
+6 -2
View File
@@ -6,10 +6,14 @@
"versionCode": 1, "versionCode": 1,
"minAPILevel": 1, "minAPILevel": 1,
"features": [], "features": [],
"config": {
"logLevel": "log",
"designWidth": 480
},
"router": { "router": {
"entry": "index", "entry": "pages/index",
"pages": { "pages": {
"index": { "pages/index": {
"component": "index" "component": "index"
} }
} }