Skip to content

10_Engineering/02 - 项目结构

1. 项目目录结构

1.1 标准项目结构

MyApplication/                        # 项目根目录
├── entry/                            # 主模块(Entry 模块,必须存在)
│   ├── src/
│   │   ├── main/
│   │   │   ├── ets/                  # ArkTS 源代码
│   │   │   │   ├── entryability/     # EntryAbility 入口
│   │   │   │   │   └── EntryAbility.ets
│   │   │   │   ├── pages/            # 页面目录
│   │   │   │   │   ├── Index.ets     # 首页(启动页)
│   │   │   │   │   └── detail/
│   │   │   │   │       └── DetailPage.ets
│   │   │   │   ├── components/       # 自定义组件
│   │   │   │   │   └── Header.ets
│   │   │   │   ├── model/            # 数据模型
│   │   │   │   │   └── User.ets
│   │   │   │   └── utils/            # 工具类
│   │   │   │       └── Format.ets
│   │   │   ├── resources/            # 资源目录
│   │   │   │   ├── base/             # 默认资源
│   │   │   │   │   ├── element/      # 字符串、颜色
│   │   │   │   │   │   └── string.json
│   │   │   │   │   ├── media/        # 图片
│   │   │   │   │   │   └── icon.png
│   │   │   │   │   └── profile/      # 配置文件
│   │   │   │   │       └── main_pages.json
│   │   │   │   ├── rawfile/          # 原始文件
│   │   │   │   │   └── data.json
│   │   │   │   └── zh_CN/            # 中文资源
│   │   │   │       └── element/
│   │   │   │           └── string.json
│   │   │   └── module.json5        # 模块配置
│   │   ├── ohosTest/                 # 测试代码
│   │   │   └── ets/
│   │   │       └── test/
│   │   │           └── List.test.ets
│   │   └── test/                     # 本地单元测试
│   ├── hvigorfile.ts                 # 模块构建脚本
│   └── build-profile.json5           # 模块构建配置
├── hvigor/                           # 构建配置目录
│   └── hvigorfile.ts                 # 项目级构建脚本
├── build-profile.json5               # 项目构建配置
├ hvigorw                             # Hvigor 包装器
├── hvigorw.bat
├── hvigorconfig.json                 # Hvigor 全局配置
└── oh-package.json5                  # 项目依赖

1.2 模块类型目录对比

模块类型根目录名用途module.json5 type
Entryentry/主应用模块,可独立安装运行entry
HARlibrary/静态共享包,编译时链接har
HSPhspmodule/动态共享包,运行时加载shared

2. entry/pages 目录详解

2.1 pages 目录结构

entry/src/main/ets/pages/
├── Index.ets                 # 应用入口页(由 main_pages.json5 指定)
├── login/
│   ├── LoginPage.ets         # 登录页
│   └── LoginViewModel.ets   # 登录页的 ViewModel
├── home/
│   ├── HomePage.ets          # 首页
│   └── components/
│       ├── TabBar.ets
│       └── Banner.ets
├── detail/
│   ├── DetailPage.ets        # 详情页
│   └── DetailViewModel.ets
└── mine/
    ├── MinePage.ets          # 个人页
    └── MineViewModel.ets

2.2 页面配置 main_pages.json5

json5
// entry/src/main/resources/base/profile/main_pages.json5
{
  "src": [
    "pages/Index",
    "pages/login/LoginPage",
    "pages/home/HomePage",
    "pages/detail/DetailPage",
    "pages/mine/MinePage"
  ]
}

⚠️ 关键:所有路由到的页面必须在此声明,否则 router.pushUrl 会失败。

3. resources 资源目录详解

3.1 资源分类

资源类型目录格式访问方式
字符串element/string.jsonJSON@string/string_name
颜色element/color.jsonJSON@color/color_name
字符串值string.jsonJSON@string/string_name
布局layout/XML@layout/layout_name
媒体media/PNG/JPG/GIF@media/image_name
菜单menu/JSON@menu/menu_name
原始文件rawfile/任意resource.getRawFd()

3.2 多语言资源

resources/
├── base/              # 默认语言(中文)
│   └── element/
│       └── string.json
├── en_US/             # 英文
│   └── element/
│       └── string.json
└── ja_JP/             # 日文
    └── element/
        └── string.json
json5
// base/element/string.json
{
  "string": [
    { "name": "app_name", "value": "我的应用" },
    { "name": "hello", "value": "你好,世界" }
  ]
}

// en_US/element/string.json
{
  "string": [
    { "name": "app_name", "value": "My App" },
    { "name": "hello", "value": "Hello, World" }
  ]
}

3.3 资源访问方式

typescript
// ArkTS 中访问资源
import { resource } from '@kit.ArkUI';

// 方式1:在 UI 模板中通过装饰器
@Entry
@Component
struct Index {
  build() {
    Column() {
      Text($r('app.string.hello'))  // 通过 $r 访问
        .fontSize(20)
      Text($r('app.string.app_name'))
    }
  }
}

// 方式2:通过 resourceManager API
import { resourceManager } from '@kit.AbilityKit';

const manager = getContext(this).resourceManager;
const str = await manager.getStringByName('hello');

4. module.json5 模块配置

4.1 module.json5 完整结构

json5
// entry/src/main/module.json5
{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "主模块描述",
    "mainElement": "EntryAbility",
    "deviceTypes": ["phone", "tablet"],
    "deliveryWithInstall": true,
    "installationFree": false,

    // 权限声明
    "permissions": [
      {
        "name": "ohos.permission.INTERNET",
        "reason": "需要网络访问",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "always"
        }
      }
    ],

    // 入口能力
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "应用主入口",
        "icon": "$media:icon",
        "label": "$string:app_name",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_bg",
        "exported": true,
        "skills": [
          {
            "entities": ["entity.system.home"],
            "actions": ["action.system.home"]
          }
        ],
        "launchType": "standard"
      }
    ],

    // 应用级配置
    "configuration": {
      "bundleName": "com.example.myapp",
      "apiReleaseType": "release",
      "compileSdkVersion": "12",
      "compatibleSdkVersion": "11",
      "bundleType": "app"
    }
  }
}

4.2 module.json5 vs AndroidManifest.xml

配置项Android (XML)HarmonyOS (JSON5)
模块类型<manifest> type 属性"type": "entry"
权限<uses-permission>permissions 数组
入口<activity> with intent-filterabilities 数组
设备类型<compatible-screens>deviceTypes 数组
网络权限声明即可需说明 reason
配置格式XMLJSON5(支持注释)

5. build-profile.json5 构建配置

5.1 项目级 build-profile.json5

json5
// build-profile.json5
{
  "app": {
    "signingConfigs": [
      {
        "name": "default",
        "type": "HarmonyOS",
        "material": {
          "certpath": "xxx.cer",
          "storeFile": "xxx.p12",
          "signAlg": "SHA256withECDSA",
          "storePwd": "******",
          "keyPwd": "******",
          "keyAlias": "debugKey"
        }
      }
    ],
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "11",
        "runtimeOS": "HarmonyOS",
        "bundleName": "com.example.myapp"
      }
    ],
    "buildModeSet": [
      { "name": "debug" },
      { "name": "release" }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        {
          "name": "default",
          "applyToProducts": ["default"]
        }
      ]
    },
    {
      "name": "common",
      "srcPath": "./common",
      "targets": [
        {
          "name": "default",
          "applyToProducts": ["default"]
        }
      ]
    }
  ]
}

5.2 module-level build-profile.json5

json5
// entry/build-profile.json5
{
  "apiType": "stageMode",
  "compileSdkVersion": "12",
  "compatibleSdkVersion": "11",
  "bundleFormat": "charcoal",
  "buildOption": {
    "arkOptions": {
      "arkFlags": ["--enable-source-map"],
      "compileMode": "esmodule"
    }
  },
  "buildOptionSet": [
    {
      "name": "debug",
      "arkOptions": {
        "sourceMap": true
      }
    },
    {
      "name": "release",
      "arkOptions": {
        "sourceMap": false,
        "obfuscation": {
          "ruleOptions": {
            "enable": true,
            "includes": ["**/*.ets"]
          }
        }
      }
    }
  ]
}

6. oh-package.json5 依赖配置

json5
// oh-package.json5
{
  "name": "myapp",
  "version": "1.0.0",
  "description": "我的 HarmonyOS 应用",
  "main": "",
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {
    "@ohos/axios": "^2.2.0"
  },
  "devDependencies": {
    "@ohos/hypium": "1.0.16",
    "@ohos/hvigor": "4.0.0"
  },
  "overrides": {
    "@ohos/hvigor-ohos-plugin": "4.0.0"
  }
}

7. 面试高频考点

Q1: entry 和 library 模块有什么区别?

回答要点

  • entry 是主模块,有 module.json5,可独立运行
  • library 是静态共享库,无 module.json5,不可独立运行
  • entry 的 type"entry",library 的 type"har"
  • entry 有入口能力(Ability),library 没有

Q2: main_pages.json5 的作用是什么?

回答要点

  • 声明所有页面路由路径
  • 指定应用的启动页
  • 页面必须在此注册,否则 router.pushUrl 会失败
  • 与 Android 的 Intent 配置类似

Q3: build-profile.json5 的 app 和 modules 分别控制什么?

回答要点

  • app:应用级配置(签名、产品、构建模式)
  • modules:模块级配置(每个模块的路径、目标平台)
  • signingConfigs 用于配置签名证书
  • products 定义不同产品变体
  • buildModeSet 定义 debug/release 构建模式

Q4: resources/base 和 resources/zh_CN 的区别?

回答要点

  • base 是默认资源,设备语言不匹配时回退到此
  • zh_CN 等是特定语言的资源,优先于 base
  • 资源查找顺序:设备语言 → 对应语言目录 → base 目录
  • 如果某个字符串在 zh_CN 中缺失,会从 base 自动回退

8. Android 对比

概念AndroidHarmonyOS
主模块app/ moduleentry/ module
资源目录res/resources/
布局文件layout/ XMLresources/base/layout/ XML
字符串资源res/values/strings.xmlresources/base/element/string.json
配置文件AndroidManifest.xmlmodule.json5
构建配置build.gradle.ktsbuild-profile.json5
启动页配置无特定文件main_pages.json5
资源引用@string/name$r('app.string.name')