harmony-app-parser
v1.0.9
Published
解析鸿蒙应用安装包(app/hap/hsp/har)中的 pack.info、module.json 等配置信息,基于 fflate 实现,零依赖、浏览器优先
Maintainers
Readme
harmony-app-parser
解析鸿蒙(HarmonyOS)应用安装包(.app / .hap / .hsp / .har)中的 pack.info、module.json 等配置信息。基于 fflate 实现,零运行时依赖、浏览器优先。
特性
- 浏览器优先:直接接收
File对象,无需文件系统权限 - 懒加载:fflate 通过动态
import()在首次解析时才加载 - 自动识别压缩包格式并解压(zip/gzip/zlib/deflate 均由 fflate 处理)
- 与 JSZip 版本(parser.js)入参出参完全一致,可平滑替换
- 同时支持 ESM
import与window.*全局两种使用方式
安装
本地安装(如果发布到 npm 仓库):
npm install harmony-app-parser或直接将本目录下的 index.js 与 script.js 拷贝到项目中使用。
使用方式
方式 1:ESM 命名导入(推荐)
import { isHarmonyApp, harmonyParser } from 'harmony-app-parser';
const file = document.querySelector('input[type=file]').files[0];
if (isHarmonyApp(file.name)) {
harmonyParser(file).then(result => {
console.log('packInfo:', result.packInfo?.data);
console.log('moduleInfo:', result.moduleInfo?.data);
}).catch(err => {
console.error('解析失败:', err);
});
}方式 2:默认导入
import harmonyApi from 'harmony-app-parser';
harmonyApi.harmonyParser(file).then(result => { /* ... */ });
harmonyApi.isHarmonyApp('xxx.hap'); // true方式 3:浏览器 <script> 标签引入
<script type="module" src="./node_modules/harmony-app-parser/index.js"></script>
<script type="module">
// 加载后自动挂载到 window
window.harmonyParser(file).then(result => console.log(result));
</script>解析自定义文件
除默认的 pack.info / module.json 外,可通过 fileList 参数额外指定要解析的文件:
const result = await harmonyParser(file, [
{ key: 'configInfo', fileName: 'config.json' },
{ key: 'manifestInfo', fileName: 'manifest.json' }
]);
console.log(result.configInfo?.data); // config.json 解析后的对象
console.log(result.manifestInfo?.data); // manifest.json 解析后的对象API
isHarmonyApp(fileName)
判断文件名是否为鸿蒙应用包格式。
| 参数 | 类型 | 说明 |
| --- | --- | --- |
| fileName | string | 文件名(含扩展名) |
返回值:boolean,当扩展名为 app / hap / hsp / har(不区分大小写)时返回 true,否则返回 false。空字符串会通过 console.error 提示并返回 false。
harmonyParser(file, fileList?)
解析鸿蒙应用包,提取并解析其中的配置文件。
| 参数 | 类型 | 说明 |
| --- | --- | --- |
| file | File | 浏览器 <input type="file"> 选择的 File 对象 |
| fileList | Array<{key: string, fileName: string}> | 可选。需要额外解析的文件列表,每项需提供唯一的 key 与目标 fileName |
返回值:Promise<Object>,resolve 结构如下:
{
packInfo: {
key: 'packInfo',
fileName: 'pack.info',
strText: '<原始文本内容>',
data: { /* JSON.parse 后的对象 */ },
// 当 JSON 解析失败时:
// err: <Error>,
// message: 'pack.info toJSON 失败'
// 当文件不存在时:
// message: '未找到此文件,请检查文件名'
},
moduleInfo: {
key: 'moduleInfo',
fileName: 'module.json',
strText: '...',
data: { /* ... */ }
},
// 通过 fileList 传入的自定义项,按 key 命名
// ...
// 当 packInfo 与 moduleInfo 都缺失时:
// message: '未获取到文件配置信息'
}reject 行为(注意区分字符串与对象两种形式):
| 触发条件 | reject 值 |
| --- | --- |
| file 参数缺失 | '缺少必须参数file'(字符串) |
| 文件名非鸿蒙格式 | '请上传app/hap/hsp/har格式的'(字符串) |
| 解压后未拿到 files | { msg: '未获取到app文件信息' } |
| 文件读取或解压失败 | { msg: '加载APP失败', err: <Error> } |
错误处理示例
harmonyParser(file).catch(err => {
if (typeof err === 'string') {
// 参数/格式校验类错误
alert(err);
} else {
// 运行时错误
console.error(err.msg, err.err);
}
});实现说明
- fflate 的
unzipSync同步返回{ [filename]: Uint8Array }(已解压后的字节) - 内部通过
toJsZipLike将其包装为 JSZip 的r.files[filename]._data.compressedContent结构,使解析逻辑可与原 JSZip 版本(parser.js)完全一致 - fflate 通过
import('./script.js')动态加载并缓存 Promise,首次调用时加载,之后复用 - 浏览器
File同时兼容file.arrayBuffer()(现代 API)与FileReader(旧浏览器兜底)
运行环境要求
- 浏览器:需支持 ES Modules(
<script type="module">)与动态import()(Chrome ≥ 63 / Firefox ≥ 67 / Safari ≥ 11.1) - Node.js:≥ 16.6.0(依赖
Array.prototype.at、动态import()、TextDecoder)
License
ISC
