🔥 Dokumentasi Modular WASM Rebahan

Workflow ini memungkinkan kamu compile C ke WASM langsung dari browser, tanpa glue JS, tanpa bundler, dan langsung preview hasilnya. Cocok untuk edukasi, animasi, atau loader modular.

1. Instalasi di Termux


pkg update
pkg install nodejs git clang python
npm install -g emscripten
# atau clone emsdk:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
  

2. Buat File C Modular

File halo.c berisi fungsi animasi elastis:


float position = -100.0;
float velocity = 0.0;
float target = 0.0;
float damping = 0.90;
float stiffness = 0.10;

void _open() {
    position = -100.0;
    target = 0.0;
    velocity = -0.10;
}

void _close() {
    position = 0.0;
    target = -100.0;
    velocity = -0.10;
}

float _update() {
    float force = stiffness * (target - position);
    velocity += force;
    velocity *= damping;
    position += velocity;
    return position;
}
  

3. Compile ke WASM Tanpa Glue

Gunakan perintah ini di Termux:


emcc halo.c -o halo.wasm --no-entry -s EXPORTED_FUNCTIONS="['_update','_open','_close']"
  

Catatan: Fungsi di C pakai underscore (_update), tapi di JS dipanggil sebagai update().

4. Setup Server Express

Buat file server.js:


const express = require('express');
const { exec } = require('child_process');
const fs = require('fs');
const app = express();
app.use(express.json());
app.use(express.static(__dirname));

app.get('/edit', (req, res) => {
  fs.readFile('halo.c', 'utf8', (err, data) => {
    if (err) return res.status(500).send('Gagal baca file');
    res.send(data);
  });
});

app.post('/edit', (req, res) => {
  fs.writeFile('halo.c', req.body.code, 'utf8', (err) => {
    if (err) return res.status(500).send('Gagal simpan file');
    res.send('Berhasil disimpan');
  });
});

app.post('/compile', (req, res) => {
  exec(`emcc halo.c -o halo.wasm --no-entry -s EXPORTED_FUNCTIONS="['_update','_open','_close']"`, (err, stdout, stderr) => {
    res.json({ success: !err, output: stdout, error: stderr });
  });
});

app.listen(8080, () => console.log('🧠 Server listening on port 8080'));
  

5. Editor HTML + Live Preview

Buat file editor.html:


<h3>Editor halo.c</h3>
<textarea id="editor" rows="20" cols="80" oninput="save()"></textarea><br>
<button onclick="compile()">Compile ke WASM</button>
<pre id="out"></pre>
<iframe src="halo.html">live preview</iframe>

<script>
const ip = '192.168.43.25'; // ganti sesuai IP kamu

fetch(`http://${ip}:8080/edit`)
  .then(res => res.text())
  .then(code => editor.value = code);

function save() {
  fetch(`http://${ip}:8080/edit`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ code: editor.value })
  });
}

function compile() {
  fetch(`http://${ip}:8080/compile`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({})
  })
  .then(res => res.json())
  .then(data => {
    out.textContent = data.success ? '✅ Compile sukses!\n' + data.output : '❌ Gagal compile:\n' + data.error;
    document.querySelector('iframe').src = 'halo.html'; // reload preview
  });
}

setInterval(() => {
  document.querySelector('iframe').src = 'halo.html';
}, 3000);
</script>
  

6. Loader WASM di halo.html

File halo.html untuk preview:


<div id="panel" style="width:100px;height:100px;background:#09f;position:absolute;"></div>
<script>
WebAssembly.instantiateStreaming(fetch('halo.wasm'))
  .then(result => {
    const { update, open, close } = result.instance.exports;
    open();
    function loop() {
      const pos = update();
      panel.style.transform = `translateX(${pos}px)`;
      requestAnimationFrame(loop);
    }
    loop();
  });
</script>
  

🧠 Dibuat oleh Andi — Filosof rebahan modular. Upload ke GitHub dan bagikan ke komunitas!