-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
71 lines (58 loc) · 1.77 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import './style.css'
import { WebContainer } from '@webcontainer/api';
import { files } from './files';
/** @type {import('@webcontainer/api').WebContainer} */
let webcontainerInstance;
window.addEventListener('load', async () => {
textareaEl.value = files['index.js'].file.contents;
textareaEl.addEventListener('input', (e) => {
writeIndexJS(e.currentTarget.value);
});
// Call only once
webcontainerInstance = await WebContainer.boot();
await webcontainerInstance.mount(files);
const exitCode = await installDependencies();
if (exitCode !== 0) {
throw new Error('Installation failed');
};
startDevServer();
});
async function installDependencies() {
// Install dependencies
const installProcess = await webcontainerInstance.spawn('npm', ['install']);
installProcess.output.pipeTo(new WritableStream({
write(data) {
console.log(data);
}
}))
// Wait for install command to exit
return installProcess.exit;
}
async function startDevServer() {
// Run `npm run start` to start the Express app
await webcontainerInstance.spawn('npm', ['run', 'start']);
// Wait for `server-ready` event
webcontainerInstance.on('server-ready', (port, url) => {
iframeEl.src = url;
});
}
/**
* @param {string} content
*/
async function writeIndexJS(content) {
await webcontainerInstance.fs.writeFile('/index.js', content);
}
document.querySelector('#app').innerHTML = `
<div class="container">
<div class="editor">
<textarea>I am a textarea</textarea>
</div>
<div class="preview">
<iframe src="loading.html"></iframe>
</div>
</div>
`
/** @type {HTMLIFrameElement | null} */
const iframeEl = document.querySelector('iframe');
/** @type {HTMLTextAreaElement | null} */
const textareaEl = document.querySelector('textarea');