@ecopages/ecopages-jsx

中文文档
0.7.1发布于 2026/11/13MITTypeScriptES Module构建来源已验证近 30 天下载 3390

JSX integration plugin for Ecopages

原始使用文档
文档目录10 节
  1. Installation
  2. Usage
  3. What This Integration Owns
  4. Route Extensions
  5. Development HMR
  6. Radiant Support
  7. Hydration Semantics: RadiantElement vs. RadiantController
  8. Registered Radiant scripts ( ssr: true )
  9. MDX Support
  10. Mixed Rendering

@ecopages/ecopages-jsx

Integration plugin for @ecopages/jsx templates in Ecopages. Use it when Ecopages JSX should own .tsx routes, Radiant-backed web components, or MDX compiled against the @ecopages/jsx runtime.

Installation

bun add @ecopages/ecopages-jsx @ecopages/jsx @ecopages/radiant

@ecopages/jsx and @ecopages/radiant are required peer dependencies for this package.

Usage

Register the ecopagesJsxPlugin in your eco.config.ts.

import { defineConfig } from '@ecopages/core/config';
import { ecopagesJsxPlugin } from '@ecopages/ecopages-jsx';

export default defineConfig({ integrations: [ecopagesJsxPlugin()] });

What This Integration Owns

  • .tsx route files by default. Use extensions to change the JSX route suffix list.
  • Optional Radiant SSR/runtime wiring through the public @ecopages/radiant entrypoints.
  • Optional .mdx routes compiled against the @ecopages/jsx runtime.

Route Extensions

Use extensions when JSX routes should use a custom suffix instead of the default .tsx.

ecopagesJsxPlugin({
    extensions: ['.page.tsx'],
});

Development HMR

In development, editing a registered Ecopages JSX page refreshes the current page through the navigation runtime. The shared Layout stays mounted where the router can preserve it; elements marked with data-eco-persist retain their DOM state. Declared client scripts continue to use script HMR.

Radiant Support

Radiant support is enabled by default. When radiant: true, the plugin keeps the ownership split explicit:

  • Ecopages JSX owns page-level JSX SSR and container hydration.
  • Radiant SSR is activated on the server through @ecopages/radiant/server/render-component.
  • Core installs Radiant's complete light-DOM surface at Integration setup, before any Page renders or defines an element, so production emit can import Radiant element modules. Lit's repairs run after that complete surface. The JSX Integration does not install DOM globals as an import side effect or on first render.
  • Radiant host hydration is activated on the client through an explicit head bootstrap that imports @ecopages/radiant/client/install-hydrator before intrinsic custom-element modules load.

That means server-rendered RadiantElement hosts hydrate in place only when both the SSR markers and the explicit client hydrator are present. Without the client hydrator, Radiant intentionally falls back to a fresh client render on first connect.

Hydration Semantics: RadiantElement vs. RadiantController

  • RadiantElement (DOM Preservation): Custom elements extending RadiantElement support true in-place hydration. When @ecopages/radiant/client/install-hydrator executes before elements connect, existing light-DOM SSR nodes are preserved, retaining DOM node identity, form input state, active focus, and media playback.
  • RadiantController (Activation / Template Re-mount): Controllers attached via [data-controller] activate when startControllers(document) is called. Activation executes the controller's render() method and mounts its template fresh into the host container, replacing server-rendered child nodes. Reactive properties and signal bindings remain fully interactive, but individual child DOM nodes are reconstructed.
  • Guidance: Use RadiantElement when in-place preservation of SSR nodes (e.g., focused inputs, media elements, or CSS transitions) is required. Use RadiantController for Stimulus-style progressive enhancement on arbitrary markup where child DOM reconstruction is acceptable.
ecopagesJsxPlugin({
    radiant: true,
});

Set radiant: false when your JSX pages do not need Radiant SSR or the Radiant browser runtime on a given app.

The plugin bootstrap is intentionally explicit rather than depending on custom-element modules to install the Radiant hydrator opportunistically.

For server-side custom-element examples, prefer explicit SSR modes over the older boolean-only contract.

new MyElement().renderHostToString({ mode: 'plain' });
new MyElement().renderHostToString({ mode: 'hydrate' });

The legacy hydrate: true option remains compatible, but mode is the current SSR contract. Registered intrinsic tags that contain a dash are SSR candidates, and framework-specific host rendering should be adapted through the server custom-element render hook instead of hardcoding framework branches into JSX page code.

The integration loads Radiant host serialization through the public @ecopages/radiant/server/radiant-element-ssr export after Core installs the shared server DOM at Integration setup. Applications do not need a separate Radiant SSR side-effect import.

Registered Radiant scripts (ssr: true)

Declare custom-element registration once in dependencies.scripts. Ecopages JSX preloads entries marked ssr: true on the server before render so hosts can SSR without a redundant import './my-element.script.ts' in the component file. Preload deduplication and invalidation state belongs to the app's AppRuntime, so separate apps keep separate preload history.

export const ThemeToggle = eco.component({
    dependencies: {
        scripts: [{ src: './theme-toggle.script.ts', ssr: true, lazy: { 'on:idle': true } }],
    },
    render: () => <theme-toggle />,
});

Keep import type when you only need props from the script module. Do not add ssr: true to browser-only scripts that touch window or document without guards.

MDX Support

Add an mdx object to treat .mdx files as JSX routes compiled against the @ecopages/jsx runtime. Omit the property to disable MDX. Put remarkPlugins, rehypePlugins, and recmaPlugins next to compilerOptions, not inside it.

import { defineConfig } from '@ecopages/core/config';
import { ecopagesJsxPlugin } from '@ecopages/ecopages-jsx';

export default defineConfig({
    integrations: [
        ecopagesJsxPlugin({
            mdx: {
                extensions: ['.mdx', '.md'],
            },
        }),
    ],
});

Mixed Rendering

Ecopages JSX can own the outer page shell or just a nested foreign subtree. When another integration reaches a JSX-owned foreign child, Ecopages hands that foreign subtree back to the JSX renderer so it can serialize the correct output before the outer renderer resumes.

Important:

  • Cross-integration shell stacks should use EcoEmbed from @ecopages/ecopages-jsx/eco-embed (or the matching integration adapter). Plain opaque objects fail fast at core foreign-subtree queue boundaries; they are not coerced with String(object). Pass already-serialized HTML when EcoEmbed is not needed.
  • Components that may render foreign children must declare those children in config.dependencies.components.
  • Ecopages validates mixed-renderer ownership from declared dependencies during render preparation. It does not treat rendered HTML alone as the source of truth.
  • Route-level dependency resolvers can supply Components at request time; Ecopages JSX includes those resolved roots when deciding whether a Foreign Subtree needs handoff.
  • Ecopages JSX keeps raw-markup preservation inside the JSX renderer.
  • JSX renderers use the required core AssetProcessingService to process declared component dependencies.

版本与发布记录

@ecopages/ecopages-jsx 共发布 114 个版本,首次发布于 2026/04/15;过去 12 个月发布了 114 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.7.1latest2026/11/13今天
0.7.02026/11/094 天前
0.6.12026/10/3014 天前
0.6.02026/10/2915 天前
0.5.02026/10/2420 天前
0.4.02026/10/2222 天前

其他发布通道:alpha → 0.2.0-alpha.55,beta → 0.2.0-beta.43,rc → 0.2.0-rc.14。

关于 @ecopages/ecopages-jsx 的常见问题

@ecopages/ecopages-jsx 是什么?

JSX integration plugin for Ecopages

如何安装 @ecopages/ecopages-jsx?

在项目目录运行 npm install @ecopages/ecopages-jsx,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@ecopages/jsx(^0.8.2)、@ecopages/core(0.7.1)、@ecopages/radiant(^0.8.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@ecopages/ecopages-jsx 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@ecopages/ecopages-jsx 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@ecopages/ecopages-jsx 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^24.22.0 || >=26.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@ecopages/ecopages-jsx 可以商用吗?

@ecopages/ecopages-jsx 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@ecopages/ecopages-jsx 的下载量有多少?

根据 npm 官方下载统计,@ecopages/ecopages-jsx 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,390 次,日均约 113 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@ecopages/ecopages-jsx 还在维护吗?

最新版本 0.7.1 发布于 2026/11/13(今天);至今共发布 114 个版本,其中过去 12 个月发布了 114 个;首次发布于 2026/04/15。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。