JS 应用入门与工程结构
本文档以 samples/js_samples/helloworld 为例,说明 HiDiTing JS 应用的基本概念、开发环境、工程创建、编译安装、工程代码结构、组件、接口、OH应用市场和类型定义,帮助开发者基于示例扩展自己的 JS demo。
OpenHarmony JS应用知识背景
JS 应用是基于 OpenHarmony Ability 模型运行的轻量应用形态,主要使用 HML、CSS 和 JavaScript 描述页面结构、页面样式和交互逻辑。对于 HiDiTing 穿戴设备,JS 应用通常以 HAP 包或转换后的 BIN 包形式交付,通过系统应用管理能力安装、卸载或预置到设备中。
开发者在实现 JS 应用时,需要关注三类内容:一是工程与构建配置,包括包名、设备类型、Ability 入口和页面路由;二是页面源码,包括 hml、css、js、app.js 和多语言资源;三是运行环境提供的组件与接口,例如通用组件、容器组件、基础组件、页面路由、日志、定时器、网络和蓝牙 BLE 等能力。
本文后续章节按实际开发流程组织:先通过仓内已有 BIN 包快速跑通 Hello World JS Demo,再结合 HelloWorld Demo 走读工程文件;随后完成工具和环境准备、工程创建、编译打包、安装、卸载和预置。由于 HelloWorld 示例只展示最小页面能力,工程代码走读章节还会补充可用组件和接口参考,最后说明 OH应用市场和类型定义。
快速跑通 Hello World JS Demo
本章用于直接安装仓内已生成的 Hello World JS Demo BIN 包,帮助开发者在不重新创建工程的情况下验证 JS 应用安装和运行链路。示例应用包位于:
准备 HelloWorld BIN 包
确认本地存在以下应用包:
该文件是可安装到板端的 Hello World JS Demo 应用包,包名对应 com.vendor.helloworld。如果本地文件不存在,需要先按“编译打包”章节重新生成应用包,或从仓库中恢复该 BIN 文件。
上传 HelloWorld BIN 包
将 com.vendor.helloworld.bin 上传到板端可访问路径,建议放到:
文件上传方式可参考《DebugKits工具使用指南》中的“数据上传与下载”章节。上传后需要确认板端路径和文件名与安装命令保持一致。
安装 HelloWorld BIN 包
如果当前是非签名调试包,可先在串口执行关闭验签命令;已签名应用可跳过此步骤。
在串口执行安装命令:
如果需要覆盖安装并清理应用沙箱历史数据,可在命令末尾增加 rmdata:
验证 HelloWorld JS Demo
安装完成后,按以下项目验证:
- 串口安装命令返回成功。
- 设备应用列表中出现 Hello World。
- 点击应用后可以进入首页。
- 首页显示 HelloWorld 或多语言资源中配置的 Hello World 文本。
如果安装失败,优先检查 BIN 文件是否上传到 /user/jsapp/com.vendor.helloworld.bin、签名模式是否与应用包匹配,以及设备存储空间是否足够。
工程代码的文件结构与代码走读
本章结合 samples/js_samples/helloworld 示例说明 JS 应用工程的代码组织方式。开发者可以先通过 Demo 了解完整工程,再继续阅读通用的文件组织、页面配置、生命周期、语法和国际化规则。
JS Demo开发示例
本节以 samples/js_samples/helloworld 目录下的 HelloWorld 示例为参考,说明 JS 应用工程创建后,如何补充一个可运行的 JS Demo。该示例是一个完整的 JS 应用工程,包含工程级构建配置、entry 模块配置、页面源码和资源文件。示例通过 config.json 配置入口 Ability,通过 hml、css、js 文件实现页面显示,并通过 i18n 资源完成中英文字符串适配。
示例目录
HelloWorld 示例工程目录如下:
helloworld/
├── build-profile.json5
├── code-linter.json5
├── hvigorfile.ts
├── oh-package.json5
├── hvigor/
│ └── hvigor-config.json5
└── entry/
├── build-profile.json5
├── hvigorfile.ts
├── oh-package.json5
└── src/main/
├── config.json
├── js/MainAbility/
│ ├── app.js
│ ├── i18n/
│ │ ├── en-US.json
│ │ └── zh-CN.json
│ └── pages/index/
│ ├── index.css
│ ├── index.hml
│ └── index.js
└── resources/
├── base/element/string.json
├── base/media/icon.png
├── base/media/icon_small.png
├── en_US/element/string.json
└── zh_CN/element/string.json
其中,根目录的 build-profile.json5、hvigorfile.ts、oh-package.json5 和 hvigor/hvigor-config.json5 用于描述工程构建信息;entry 目录是应用入口模块;entry/src/main/config.json 用于声明应用包名、设备类型、Ability 和 JS 页面入口;app.js 用于处理应用生命周期;pages/index 目录用于实现首页页面;i18n 和 resources 目录用于配置页面文本、应用名称和图标等资源。
工程配置
HelloWorld 示例根目录的 build-profile.json5 声明工程产品、构建模式和模块路径。其中,modules 字段将 entry 模块映射到 ./entry:
{
"app": {
"signingConfigs": [],
"products": [
{
"name": "default",
"signingConfig": "default",
"compatibleSdkVersion": "5.0.0(12)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true
}
}
}
],
"buildModeSet": [
{
"name": "debug"
},
{
"name": "release"
}
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}
根目录的 hvigorfile.ts 引用 Hvigor 内置应用构建任务:
import { legacyAppTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: legacyAppTasks,
plugins:[]
}
entry/build-profile.json5 声明模块 API 类型和构建目标:
配置入口Ability
在 entry/src/main/config.json 中配置应用基础信息、设备类型和入口 Ability。HelloWorld 示例中,deviceType 配置为 liteWearable,入口 Ability 名称为 .MainAbility,JS 页面入口为 pages/index/index。
{
"app": {
"bundleName": "com.vendor.helloworld",
"vendor": "example",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"deviceType": [
"liteWearable"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [
{
"name": ".MainAbility",
"srcLanguage": "js",
"srcPath": "MainAbility",
"icon": "$media:icon",
"description": "$string:MainAbility_desc",
"label": "$string:MainAbility_label",
"type": "page"
}
],
"js": [
{
"pages": [
"pages/index/index"
],
"name": ".MainAbility"
}
]
}
}
app.js 可用于监听应用创建和销毁事件,示例如下:
export default {
onCreate() {
console.info('Application onCreate');
},
onDestroy() {
console.info('Application onDestroy');
}
};
实现页面
JS 页面通常由同名的 hml、css、js 文件组成。HelloWorld 示例在 pages/index 下实现首页。
index.hml 用于描述页面结构:
index.css 用于配置页面布局和文本样式:
.container {
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
flex-direction:column;
}
.title {
width: 200px;
font-size: 30px;
text-align: center;
}
index.js 用于声明页面数据并在 onInit 生命周期中初始化显示内容:
import app from '@system.app';
export default {
data: {
title: ''
},
onInit() {
this.title = this.$t('strings.world');
},
}
页面运行后,index.hml 会读取 strings.hello 和 title 的值,组合显示 “您好 世界” 或 “Hello World”。
配置多语言资源
页面中通过 $t 读取 i18n 目录下的字符串资源。中文资源文件 js/MainAbility/i18n/zh-CN.json 示例:
应用标签、描述等系统资源在 resources/*/element/string.json 中配置。基础资源示例如下:
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "MainAbility_desc",
"value": "description"
},
{
"name": "MainAbility_label",
"value": "helloworld"
}
]
}
config.json 中的 $string:MainAbility_label、$string:MainAbility_desc 和 $media:icon 会分别关联到资源目录中的字符串和图片资源。
运行验证
- 可直接使用 DevEco Studio 打开 samples/js_samples/helloworld 完整工程进行编译和预览。
- 如果是在新建工程中合入示例,需参考 HelloWorld 根目录的工程配置文件,并将
entry模块内容合入新工程对应目录。 - 确认
config.json中bundleName、deviceType、Ability 名称和pages路径符合当前工程配置。 - 使用 DevEco Studio 执行编译和预览。
- 预览或安装运行后,首页应显示 HelloWorld 文本;切换系统语言时,页面文本应读取对应
i18n资源。
说明: 如果当前工程已存在同名 Ability 或首页路径,请按工程实际目录调整
srcPath、name和pages配置,避免入口配置和页面目录不一致。
文件组织
JS 应用的 JS 模块(应用工程内的 entry/src/main/js/module)典型目录结构如下:
├── app.js
├── pages
│ ├── index
│ │ ├── index.hml
│ │ ├── index.css
│ │ └── index.js
│ └── detail(可选)
│ ├── detail.hml
│ ├── detail.css
│ └── detail.js
├── common(可选)
│ ├── xxx.png
│ ├── style.css
│ └── utils.js
└── i18n(可选)
├── zh-CN.json
└── en-CN.json
目录结构中文件分类如下:
- .hml结尾的HML模板文件,此文件用来描述当前页面的文件布局结构。
- .css结尾的CSS样式文件,此文件用于描述页面样式。
- .js结尾的JS文件,此文件用于处理页面和用户的交互。
各个文件夹的作用:
- pages目录用于存放所有组件页面。
- common目录用于存放公共资源文件,如:媒体资源和JS文件。
- i18n目录用于配置不同语言场景资源内容,如应用文本词条、图片路径等资源。
须知:
- i18n是开发保留文件夹,不可重命名。
- 在使用DevEco Studio进行应用开发时,目录结构中的可选文件夹需要开发者根据实际情况自行创建。
应用资源可通过绝对路径或相对路径的方式进行访问,本开发框架中绝对路径以“/”开头,相对路径以“./”或“../”。具体访问规则如下:
- 引用代码文件,推荐使用相对路径,如:../common/utils.js。
- 引用资源文件,推荐使用绝对路径,如:/common/xxx.png。
- 公共代码文件和资源文件建议放在common下,通过以上两条规则进行访问。
- CSS样式文件中通过url()函数创建<url>数据类型,如:url(/common/xxx.png)。
说明: 当代码文件A需要引用代码文件B时:
- 如果代码文件A和文件B位于同一目录,则代码文件B引用资源文件时可使用相对路径,也可使用绝对路径。
- 如果代码文件A和文件B位于不同目录,则代码文件B引用资源文件时必须使用绝对路径。因为Webpack打包时,代码文件B的目录会发生变化。
说明: 以下是JS应用工程可用的图片类型,当编译安装包时,会由IDE转换为海思压缩图片格式。
表 1 支持的图片格式
格式 |
支持的文件类型 |
|---|---|
BMP |
.bmp |
JPEG |
.jpg |
PNG |
.png |
音频资源文件可跟随应用一起打包编译,通过相对路径的方式进行访问;也可以预置在系统目录,使用绝对路径的方式进行访问,具体使用规则如下:
-
跟随应用打包的音频资源文件必须放置在resources下(默认文件夹或新增自定义子目录),如:resources/base/media/xxx.mp3。
相对路径引用时,设置播放器的srcInner属性,如:player.srcInner = "resources/base/media/xxx.mp3" 。
-
预置在系统目录,如:/user/music/xxx.mp3。
绝对路径引用时,设置播放器的src属性,如:player.src = "/user/music/xxx.mp3" 。
js标签配置
js标签中包含实例名称、页面路由信息如表1所示。
表 1 js标签配置
标签 |
类型 |
默认值 |
必填 |
说明 |
|---|---|---|---|---|
name |
string |
default |
是 |
标识JS实例的名字。 |
pages |
Array |
- |
是 |
路由信息,请参见“pages”内容。 |
说明: name、pages 标签配置需在“配置文件”(config.json)中的“js”标签中完成设置。
定义每个页面的路由信息,每个页面由页面路径和页面名组成,页面的文件名即页面名。如:
说明:
- 应用首页固定为“pages/index/index”。
- 页面文件名不能使用组件名称,如:text.hml、button.hml等。
{
"app": {
"bundleName": "com.example.player",
"version": {
"code": 1,
"name": "1.0"
},
"vendor": "example"
}
"module": {
...
"js": [
{
"name": "default",
"pages": [
"pages/index/index",
"pages/detail/detail"
]
}
],
"abilities": [
{
...
}
]
}
}
app.js
每个应用可以在app.js中自定义“生命周期”的实现逻辑,以下示例仅在生命周期函数中打印对应日志: