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

@j20org/jsx-transform

v0.1.1

Published

j20 框架的 JSX 编译器 —— 一个 Babel 插件,把 JSX 编译成 j20 运行时的细粒度响应式调用(`jsx` / `jsxs` / `template` / `Fragment`)。

Downloads

57

Readme

@j20org/jsx-transform

j20 框架的 JSX 编译器 —— 一个 Babel 插件,把 JSX 编译成 j20 运行时的细粒度响应式调用(jsx / jsxs / template / Fragment)。

编译目标与 SolidJS 的 dom-expressions 风格一致:

  • 静态 DOM 标签与静态属性被提升为 template() 常量,运行时通过 cloneNode 复用,零 diff。
  • 动态属性编译为 getter,运行时按属性粒度建立 effect,互不影响。
  • 响应式子表达式被包装成 thunk(() => expr),由运行时追踪。
const App = () => <div>{$hello}</div>

会编译为类似下面的代码(运行时函数从 importSource 自动导入):

const __tmpl1 = _template(`<div>`)
const App = () => _jsx(__tmpl1(), undefined, () => () => $hello)

安装

npm i @j20org/jsx-transform

配置

interface Config {
  /** 是否自动从 importSource 注入 jsx/jsxs/template/Fragment 导入,默认 true */
  autoImport?: boolean
  /** 运行时函数的导入来源,例如 "j20" */
  importSource: string
}

默认值:

{ autoImport: true, importSource: "j20" }

使用

作为 Babel 插件

需要配合 @babel/plugin-syntax-jsx 解析 JSX 语法(本插件只做转换,不负责解析)。

// babel.config.js
import { j20JsxTransform } from "@j20org/jsx-transform"

export default {
  plugins: [
    "@babel/plugin-syntax-jsx",
    [j20JsxTransform, { importSource: "j20" }],
  ],
}

作为 Rollup 插件

通过 /rollup 子路径导出:

import { j20JsxTransformRollup } from "@j20org/jsx-transform/rollup"

interface Options {
  include?: FilterPattern
  exclude?: FilterPattern
  sourcemap?: boolean // 默认 true
  config?: Config
}

j20JsxTransformRollup({
  include: "src/**/*.{js,jsx,ts,tsx}",
  config: { importSource: "j20" },
})

通常你不需要直接使用本包。j20 的官方脚手架通过 @j20org/vite-plugin 已经把 JSX 转换、Signal 编译等串联好,参见 j20。

导出

| 路径 | 导出 | 说明 | | --- | --- | --- | | @j20org/jsx-transform | j20JsxTransform, Config | Babel 插件 | | @j20org/jsx-transform/rollup | j20JsxTransformRollup, Options | Rollup 插件 |

行内组件(render prop)

行内组件(render prop)是匿名函数,没有名字,signal-compiler 无法自动识别为组件。因此 jsx-transform 会在满足以下全部条件时,在函数节点上附加 /* @signal-component */ 块注释标记,signal-compiler 检测到标记后按组件编译(参数解构 → computed):

  1. 属性名大写开头(如 Insert={...});
  2. 属性值是无名函数(箭头函数或无 id 的函数表达式);
  3. 解构参数中含有 $ 绑定(如 ({ value: $value }) => ...)。
<TodoItem Insert={({ value: $value }) => {
  let $msg = "msg";
  return <div>{$value}{$msg}</div>;
}} />

编译为(配合 signal-compiler 的第二 pass):

// jsx-transform 输出:
get Insert() {
  return /* @signal-component */({ value: $value }) => {
    let $msg = "msg";
    return _jsxs(__tmpl1(), undefined, () => [() => $value, () => $msg]);
  };
}

// signal-compiler 输出:
get Insert() {
  return /* @signal-component */__$0 => {
    const $value = _computed(() => __$0.value["value"]);
    let $msg = _signal("msg");
    return _jsxs(__tmpl1(), undefined, () => [() => $value.value, () => $msg.value]);
  };
}

标记必须是块注释(不能用行注释——行内组件常在 return 位置,行注释会触发 ASI 损坏代码),且 jsx-transform 必须先于 signal-compiler 执行(独立 Babel pass)。

License

MIT @anuoua