Ekspor Kode

Paket @nuforge/codegen mengubah sebuah program menjadi komponen React mandiri yang bersih — tanpa nuforge saat runtime. Hasilnya adalah .tsx biasa yang bisa Anda taruh di proyek React mana pun.

import { toReact } from '@nuforge/codegen';

const tsx = toReact(nu.state.program); // a .tsx component string

Apa yang dipetakan

  • Sebuah komponen menjadi function Name(props: Props) { ... }, ditambah sebuah interface Props yang dihasilkan dari props-nya.
  • Sebuah state val menjadi const [x, setX] = useState(init); penugasan x = ... menjadi setX(...).
  • @if={c} menjadi {c && (<jsx/>)}.
  • @each={(item, i) in list} menjadi {list.map((item, i) => <jsx key={i} />)}.
  • class dan @classList menjadi className={[...].filter(Boolean).join(' ')}.
  • Sebuah binding dua arah menjadi value={x} onChange={(e) => setX(e.target.value)}.
  • == dan != menjadi === dan !==.

Contoh

DSL masukan:

component App() {
  val name = "nuforge";
} => (
  <div>
    <input value:={name} />
    <strong>{name}</strong>
  </div>
)

Output yang dihasilkan:

import { useState } from 'react';

export function App() {
  const [name, setName] = useState("nuforge");

  return (
    <div>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <strong>{name}</strong>
    </div>
  );
}

Ini menggerakkan fitur "ekspor ke kode nyata": sebuah builder no-code dapat memberikan pengguna komponen nyata yang native ke framework alih-alih mengunci mereka ke runtime proprietary. Ini adalah pembeda utama — output tidak bergantung pada nuforge setelah diekspor.

Next.js: 'use client' hanya saat perlu

Output mengikuti konvensi App Router. toReact menambahkan direktif 'use client' hanya saat modul memang butuh client — komponen dengan state, event handler, atau two-way binding. Halaman presentasional murni tetap menjadi React Server Component (tanpa direktif, tanpa impor useState):

// halaman statis → Server Component
export function Card(props: CardProps) {
  const { title = 'Card' } = props;
  return <h3 className="card">{title}</h3>;
}
// punya state → modul client
'use client';
import { useState } from 'react';

export function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

Gunakan toReact(program, { useClient: true }) untuk memaksa direktif, atau imports: false untuk menyisipkan ke modul yang sudah ada.

Komponen eksternal & import

Jika halaman Anda memakai komponen dari paket lain — mis. <$Motion/> eksternal yang didukung motion/react, atau komponen ikon — petakan namanya agar hasil export tetap mandiri. Hanya nama yang benar-benar dipakai (dan bukan komponen lokal) yang diimpor, dikelompokkan per modul:

const tsx = toReact(program, {
  componentImports: {
    Motion: { from: 'motion/react', named: 'motion' }, // import { motion as Motion } from 'motion/react'
    Icon: 'lucide-react', // import { Icon } from 'lucide-react'
    Chart: { from: './chart', default: true }, // import Chart from './chart'
  },
});
'use client';
import { motion as Motion } from 'motion/react';

export function App() {
  return (
    <Motion animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4 }}>
      Hello
    </Motion>
  );
}

Inilah yang menjaga halaman ber-animasi (Motion / wrapper GSAP / komponen design-system) tetap utuh setelah diekspor.

Target lain: HTML dan Vue

Ekspor tidak terbatas pada React.

toHtml(frame.view) me-render pohon View yang sudah dievaluasi menjadi string HTML statis — tanpa JavaScript, tanpa runtime nuforge. Cocok untuk export statis, template email, dan preview. Event handler dan komponen eksternal (React host) dihilangkan.

import { Nu } from '@nuforge/core';
import { toHtml } from '@nuforge/codegen';

const nu = Nu.fromSource(SOURCE);
const frame = nu.createFrame({ component: { name: 'App' } });
const html = toHtml(frame.view); // string HTML statis

toVue(program, opts?) menghasilkan Vue 3 Single-File Component: val menjadi ref, @if/@each menjadi v-if/v-for, two-way binding menjadi v-model, dan event menjadi @event.

import { toVue } from '@nuforge/codegen';

const sfc = toVue(program, { component: 'App' });
<script setup lang="ts">
import { ref } from 'vue';

const name = ref("nuforge");
</script>

<template>
  <input v-model="name" />
  <strong>{{ name }}</strong>
</template>

Destructure reactive props pada SFC yang dihasilkan membutuhkan Vue 3.5+.

Langkah berikutnya

  • Rendering React — render pohon View reaktif dari sebuah Frame secara langsung dengan React.
  • Editor SDK — bangun pengalaman penyuntingan visual di sekitar sebuah program.