npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wdcjs/harmonyos-jsx

v0.1.1

Published

使用 TSX 编写鸿蒙 HarmonyOS 原生应用,纯编译时转换为 ArkTS 声明式语法,零运行时开销

Readme

harmonyos-jsx

使用 TSX 编写鸿蒙 HarmonyOS 原生应用,纯编译时转换为 ArkTS 声明式语法,零运行时开销。

@wdcjs/harmonyos-jsx 不引入任何运行时框架,不创建 Virtual DOM,直接把 TSX 源码编译为等效的原生 ArkTS 代码,保持鸿蒙原生应用的性能表现。

设计理念

  • 纯编译时转换:TSX → 原生 ArkTS,无运行时、无额外依赖
  • 镜像目录结构:tsx/ 目录与 ets/ 目录一一对应,增量编译
  • 原生状态管理:直接使用鸿蒙 @State、@Prop、@Link 等装饰器
  • 链式调用映射:JSX 属性自动映射为 ArkTS 链式方法(.width()、.height()、.onClick())
  • VS Code 优先:推荐使用 VS Code 编写 TSX,对 TSX 有原生一等支持(语法高亮、补全、重构)

快速开始

安装

推荐局部安装到项目 devDependencies(避免全局版本冲突,确保团队版本一致):

pnpm add -D @wdcjs/harmonyos-jsx

局部安装后通过 pnpm exec hsx 调用,或在 package.json 的 scripts 中直接使用。

也可以全局安装(便于在任意目录直接使用 hsx 命令):

pnpm add -g @wdcjs/harmonyos-jsx
hsx --version

配置 npm scripts(自动)

首次运行 hsx dev 或 hsx build 时,会自动检测项目根目录的 package.json,若不存在 dev/build/clean scripts,则自动注入:

{
  "scripts": {
    "dev": "hsx dev",
    "build": "hsx build",
    "clean": "hsx clean"
  }
}

已存在的同名 scripts 不会被覆盖,你可以安全自定义。注入后即可直接通过 pnpm dev / pnpm build / pnpm clean 使用。

使用 VS Code 开发

推荐使用 VS Code 作为主要开发编辑器,VS Code 对 TSX 有原生的语法高亮、自动补全、括号匹配、重构等支持,无需额外插件。

执行初始化命令后会自动在项目根目录生成 .vscode/settings.json,确保 .tsx 文件被正确识别为 TypeScript JSX 格式:

pnpm exec hsx          # 局部安装
# 或
hsx                    # 全局安装

关于 TypeScript:编译器使用 Babel 解析 TSX,不需要安装 typescript 包即可编译和获得基本的语法高亮。VS Code 内置了 TypeScript 语言服务,能读取 tsconfig.json 和 arkts-global.d.ts 声明文件提供完整的类型提示和组件属性补全。如需更严格的类型检查,可执行 pnpm add -D typescript 安装。

首次执行将:

  1. 在项目根目录创建 .vscode/settings.json(自动关联 *.tsx 为 TypeScript JSX)
  2. 在项目根目录的 package.json 中自动注入 dev/build/clean scripts(已存在则不覆盖)
  3. 在 entry/src/main/ets/ 下创建 tsx/ 目录(TSX 源码目录,与 ets 结构镜像)
  4. 生成 tsx/pages/Index.tsx 示例页面
  5. 生成 arkts-global.d.ts(ArkTS 装饰器/组件类型声明)和 tsconfig.json 配置

VS Code 智能提示

通过自动生成的 arkts-global.d.ts 类型声明文件,VS Code 提供以下智能提示能力:

  • 装饰器提示:@Entry、@Component、@State、@Prop、@Link、@Builder 等装饰器悬停时显示文档说明
  • 组件属性补全:输入 <Column 后自动列出可用属性(width、height、alignItems、justifyContent 等)
  • 枚举值提示:输入 alignItems=" 后弹出 "center" | "start" | "end" 等有效值,输入错误值时会标红
  • 属性类型检查:传入类型错误的属性值(如字符串给数字类型)会标红提示
  • 事件补全:输入 on 后自动补全 onClick、onChange、onAppear 等事件
  • 覆盖 40+ 组件:Column、Row、Stack、Flex、List、Text、Button、Image、TextInput、Scroll、Tabs、Swiper 等常用组件均有完整类型定义

这些提示完全由 VS Code 内置的 TypeScript 语言服务驱动,无需安装任何额外插件。

目录结构

项目根目录/
├── .vscode/
│   └── settings.json        # VS Code 配置(自动生成,关联 *.tsx 语法高亮)
├── entry/src/main/ets/
│   ├── tsx/                 # TSX 源码(你编写的代码)
│   │   ├── pages/
│   │   │   └── Index.tsx
│   │   └── components/
│   │       └── MyComponent.tsx
│   ├── pages/               # 编译生成的 ArkTS(勿手动修改)
│   │   └── Index.ets
│   └── components/
│       └── MyComponent.ets
└── package.json

编译产物会镜像 tsx/ 的目录结构输出到对应的 ets/ 位置。

开发流程

  1. 用 VS Code 打开项目根目录
  2. 运行 pnpm dev 启动监听模式
  3. 在 tsx/ 目录下编写 .tsx 文件,保存即自动编译为 .ets
  4. 编译产物可直接被 DevEco Studio 用于预览和真机构建

命令

| 命令 | 说明 | |------|------| | hsx dev | 启动开发模式,监听 tsx/**/*.tsx 文件变化,增量编译 | | hsx build | 一次性编译所有 TSX 文件 | | hsx clean | 清理所有编译生成的 .ets 文件 |

所有命令支持 -r, --root <path> 选项指定项目根目录(默认为当前目录)。

局部安装时通过 pnpm exec 调用:

pnpm exec hsx dev              # 开发模式,监听文件变化
pnpm exec hsx build            # 一次性构建
pnpm exec hsx clean            # 清理编译产物
pnpm exec hsx build -r ./e2e   # 指定子目录作为项目根目录

配置好 scripts 后可直接:

pnpm dev
pnpm build
pnpm clean

TSX 语法

基本组件

@Entry
@Component
class Index {
  @State count: number = 0

  build() {
    return (
      <Column space={10} width="100%" height="100%" alignItems="center" justifyContent="center">
        <Text fontSize={40} fontColor="#333">Count: {this.count}</Text>
        <Button type={ButtonType.Capsule} onClick={() => this.count++}>
          Click +1
        </Button>
      </Column>
    )
  }
}

编译为原生 ArkTS:

@Entry
@Component
struct Index {
  @State count: number = 0

  build() {
    Column({ space: 10 }) {
      Text(`Count: ${this.count}`).fontSize(40).fontColor("#333")
      Button("Click +1", { type: ButtonType.Capsule }).onClick(() => this.count++)
    }.width("100%").height("100%").alignItems("center").justifyContent("center")
  }
}

属性映射规则

JSX 属性按以下优先级映射:

  1. 构造参数:组件的构造函数参数(如 Column 的 space、Button 的 type)放在 ({ ... }) 中
  2. 事件:以 on 开头的属性(onClick、onChange 等)映射为 .onXxx() 链式调用
  3. 文本内容:Text、Button 等组件的子文本作为第一个构造参数(支持模板字符串插值)
  4. 链式属性:其余属性(width、height、fontSize 等)映射为 .xxx() 链式调用
  5. style 对象:style={{ width: 100, height: 50 }} 会展开为多个链式调用

条件渲染

{this.show && <Text>visible</Text>}
{this.on ? <Text>On</Text> : <Text>Off</Text>}

编译为:

if (this.show) {
  Text("visible")
}
if (this.on) {
  Text("On")
} else {
  Text("Off")
}

列表渲染

{this.list.map(item => <Text>{item.name}</Text>)}

编译为:

ForEach(this.list, (item: any) => {
  Text(item.name)
}, (item: any) => item.id ?? item)

自定义组件

PascalCase 开头的组件视为自定义组件,所有属性作为构造参数传入:

<MyCard title="Hello" desc="World" onClick={this.handleClick} />

编译为:

MyCard({ title: "Hello", desc: "World", onClick: this.handleClick })

注意事项

  • 组件类请使用 class 关键字定义(编译器会自动转换为 struct)
  • 所有鸿蒙原生装饰器(@Entry、@Component、@State、@Prop、@Link、@Builder 等)保持原样使用
  • TSX 文件需放在 tsx/ 目录下,编译输出到对应的 ets/ 位置
  • 请勿手动修改编译生成的 .ets 文件,它们会在下次编译时被覆盖
  • 推荐使用 VS Code 开发,初始化时已自动配置 .vscode/settings.json 确保 TSX 语法高亮

开发

pnpm install
pnpm test    # 运行单元测试

License

MIT