Bahasa DSL
DSL nuforge adalah bahasa deklaratif kecil untuk mendeskripsikan halaman. Sebuah program adalah daftar global dan komponen; nuforge mem-parsing-nya menjadi AST reaktif. Halaman ini menelusuri seluruh sintaksnya.
Global
Gunakan val di tingkat teratas untuk mendeklarasikan nilai bersama. Nilai tersebut dapat menampung ekspresi apa pun yang diizinkan, termasuk objek:
val brand = "nuforge";
val theme = { primary: "#0066DE" };
Komponen
Sebuah komponen memiliki props dengan nilai default di dalam tanda kurung, state lokal yang dideklarasikan dengan val di dalam kurung kurawal, dan template setelah =>:
component App(title = "Untitled") {
val count = 0;
val items = ["a", "b"];
} => (
<div>
<h1>{title}</h1>
</div>
)
Blok props, blok state, dan template masing-masing bersifat opsional, tetapi sebuah komponen selalu mendeklarasikan template-nya setelah panah =>.
Teks dan ekspresi
Di dalam template, kurung kurawal menampung ekspresi. Sebuah literal string seperti {"a static string"} me-render teks statis, sedangkan {expr} mengevaluasi ekspresi dinamis seperti {count}. Template literal didukung — tulis di dalam backtick di dalam sebuah ekspresi:
<p>{`Hello, ${title}`}</p>
Atribut
Atribut menerima ekspresi di dalam kurung kurawal. Gunakan literal string untuk nilai konstan, atau ekspresi apa pun untuk nilai dinamis:
<div class={"page"} id={someId} data-count={count} />
Anda menulis nama atribut HTML — class dan for, bukan className / htmlFor. DSL mendeskripsikan markup, jadi ia tetap netral terhadap framework (HTML dan Vue juga memakai class). Adapter React memetakan class → className dan for → htmlFor saat render, dan ekspor kode melakukan hal yang sama — jadi class={"page"} menjadi className="page" pada React yang dihasilkan.
Inline styles
Tag <style> (atau <script>) mempertahankan isinya sebagai teks mentah, jadi Anda bisa menulis CSS asli — pakai string backtick untuk aturan multi-baris dan combinator:
<style>{`
.card { padding: 1rem; border-radius: 8px; }
.card > .title { font-weight: 700; }
`}</style>
Untuk sebagian besar styling, utamakan utility class (class={"..."}); pakai <style> saat butuh aturan CSS sungguhan. Untuk membatasi style hanya ke kanvas editor, gunakan prop srcDoc / baseCss pada IframeCanvas (lihat SDK Editor).
Direktif
Direktif adalah atribut khusus yang mengontrol rendering:
@if={cond}me-render elemen secara kondisional.@each={item in list}atau@each={(item, index) in list}mengulang elemen untuk setiap entri.@classList={{ active: count > 0 }}mengalihkan kelas berdasarkan kondisi.
<li @each={(item, index) in items} @classList={{ first: index == 0 }}>{item}</li>
Two-way binding
Binding value:={...} menjaga input tetap terkontrol dan menulis suntingan pengguna kembali ke state:
<input value:={name} />
Event
Penangan event adalah arrow function. Mereka dapat menulis ke state secara langsung:
<button onClick={() => count = count + 1}>{count}</button>
Komposisi
Sebuah tag yang namanya diawali huruf kapital adalah instance komponen. Berikan props sebagai atribut:
<Card title={"Hi"} />
Externals
Identifier yang diawali $ merujuk ke nilai yang disediakan host. Gunakan $state untuk state eksternal, $func(...) untuk memanggil fungsi host, dan <$Component/> untuk me-render komponen eksternal:
<$Component label={$state} onPick={() => $func("pick")} />
Lihat halaman externals untuk cara mendaftarkan ini dari host.
Apa yang diizinkan
Demi keamanan, parser hanya menerima sekumpulan node ekspresi yang dikenal: literal, identifier, akses member, array, objek, operator binary / logical / unary, ekspresi kondisional (ternary), pemanggilan fungsi, arrow function (untuk event), dan template literal.
Parser MENOLAK apa pun di luar allow-list tersebut, termasuk:
new,function,this,typeof, dandelete- operator strict-equality — tulis
==/!=, yang saat diekspor dikompilasi menjadi===/!== - increment dan decrement
++/-- - comma sequence dan tagged template
- akses ke
constructor,__proto__, atauprototype
Lihat halaman security untuk jaminan lengkap di balik aturan-aturan ini.
Menulis: validasi & code editor
Parser.diagnose(source) memvalidasi DSL tanpa melempar error — ia mengembalikan daftar diagnostik terstruktur (kosong jika valid), tiap item berisi pesan, sebuah code, dan rentang offset sumber plus baris/kolom:
import { Parser } from '@nuforge/parser';
Parser.diagnose(`component App() {} => (<div>{new Date()}</div>)`);
// [{ severity: 'error', code: 'forbidden-syntax',
// message: 'Syntax "NewExpression" is not allowed',
// from, to, start: { line, column }, end }]
Komponen @nuforge/react-code-editor (CodeEditor) dibangun di atas ini: ia menyediakan autocomplete DSL nuforge (keyword, directive, tag HTML, serta nama component/state/prop/global dan $external dari program Anda) dan squiggle error langsung yang ditenagai diagnose.