add pack rpk
This commit is contained in:
@@ -3,6 +3,10 @@ node_modules/
|
||||
|
||||
# 构建输出目录
|
||||
dist/
|
||||
build/
|
||||
|
||||
# 临时目录
|
||||
.temp_*/
|
||||
|
||||
# 日志文件
|
||||
*.log
|
||||
|
||||
@@ -22,8 +22,33 @@ src/
|
||||
|
||||
### 环境要求
|
||||
|
||||
- 安装 AIoT-IDE(Xiaomi Vela JS 应用的集成开发环境)
|
||||
- 支持 Ubuntu、Windows、MacOS 等操作系统
|
||||
- Node.js 14+
|
||||
- npm
|
||||
- 系统安装了 OpenSSL(release 模式需要)
|
||||
|
||||
### 安装依赖
|
||||
|
||||
```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. 启动模拟器
|
||||
3. 运行项目查看效果
|
||||
|
||||
### 打包应用
|
||||
|
||||
1. 在 AIoT-IDE 中使用打包功能
|
||||
2. 生成安装包(.rpk 文件)
|
||||
或使用命令行:
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
## 应用特点
|
||||
|
||||
|
||||
@@ -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 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');
|
||||
// ========== 辅助函数 ==========
|
||||
|
||||
// 创建输出目录
|
||||
/**
|
||||
* 执行命令并打印输出
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 aiot CLI 是否已安装
|
||||
*/
|
||||
function isAiotInstalled() {
|
||||
try {
|
||||
execSync('aiot --version', { cwd: projectDir, stdio: 'pipe' });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 node_modules 是否存在且 aiot-toolkit 已安装
|
||||
*/
|
||||
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)) {
|
||||
fs.mkdirSync(distDir);
|
||||
console.error('❌ 构建失败:dist 目录不存在');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 复制文件函数
|
||||
function copyFileSync(source, target) {
|
||||
let targetFile = target;
|
||||
|
||||
// 如果目标是一个目录,则在目录中创建同名文件
|
||||
if (fs.existsSync(target)) {
|
||||
if (fs.lstatSync(target).isDirectory()) {
|
||||
targetFile = path.join(target, path.basename(source));
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(targetFile, fs.readFileSync(source));
|
||||
}
|
||||
|
||||
// 复制目录函数
|
||||
function copyFolderRecursiveSync(source, target) {
|
||||
let files = [];
|
||||
|
||||
// 检查目标目录是否存在
|
||||
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);
|
||||
}
|
||||
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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 开始构建
|
||||
console.log('开始构建 Xiaomi Vela JS 应用...');
|
||||
|
||||
try {
|
||||
// 复制源文件到输出目录
|
||||
copyFolderRecursiveSync(srcDir, distDir);
|
||||
console.log('构建完成!');
|
||||
console.log('输出目录:', distDir);
|
||||
} catch (error) {
|
||||
console.error('构建失败:', error);
|
||||
}
|
||||
|
||||
walkDir(distDir);
|
||||
|
||||
if (files.length > 0) {
|
||||
console.log('\n✅ 构建成功!生成的 rpk 文件:');
|
||||
files.forEach((f) => {
|
||||
console.log(` 📦 ${f.path} (${f.size} KB)`);
|
||||
});
|
||||
} else {
|
||||
console.warn('\n⚠️ 构建完成,但未在 dist 目录中找到 .rpk 文件');
|
||||
console.log(' 请检查构建日志是否有错误信息');
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 主流程 ==========
|
||||
|
||||
function main() {
|
||||
const mode = isRelease ? '生产(release)' : '开发(debug)';
|
||||
console.log(`\n🚀 Xiaomi Vela JS 应用构建工具`);
|
||||
console.log(`📋 构建模式: ${mode}`);
|
||||
console.log(`📁 项目目录: ${projectDir}`);
|
||||
|
||||
// 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();
|
||||
|
||||
Generated
+9491
File diff suppressed because it is too large
Load Diff
+5
-1
@@ -5,7 +5,11 @@
|
||||
"main": "build.js",
|
||||
"scripts": {
|
||||
"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": [
|
||||
"xiaomi",
|
||||
|
||||
+6
-2
@@ -6,10 +6,14 @@
|
||||
"versionCode": 1,
|
||||
"minAPILevel": 1,
|
||||
"features": [],
|
||||
"config": {
|
||||
"logLevel": "log",
|
||||
"designWidth": 480
|
||||
},
|
||||
"router": {
|
||||
"entry": "index",
|
||||
"entry": "pages/index",
|
||||
"pages": {
|
||||
"index": {
|
||||
"pages/index": {
|
||||
"component": "index"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user