2020-06-14 16:18:50 +08:00
|
|
|
/* eslint-disable no-console */
|
|
|
|
// eslint-disable-next-line import/no-unresolved
|
2020-09-05 21:58:07 +08:00
|
|
|
import * as m from 'monaco-editor';
|
2020-06-14 16:18:50 +08:00
|
|
|
import { h, createApp } from 'vue';
|
2020-06-13 11:23:47 +08:00
|
|
|
import { transform } from '@babel/core';
|
2020-09-05 21:58:07 +08:00
|
|
|
import babelPluginJsx from '../../babel-plugin-jsx/src';
|
2020-06-13 11:23:47 +08:00
|
|
|
import './index.css';
|
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
declare global {
|
|
|
|
interface Window {
|
|
|
|
monaco: typeof m
|
|
|
|
init: () => void
|
|
|
|
}
|
2020-06-13 11:23:47 +08:00
|
|
|
}
|
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
window.init = () => {
|
|
|
|
const { monaco } = window;
|
|
|
|
createApp(
|
|
|
|
() => h('h1', null, 'Vue JSX Explorer'),
|
|
|
|
).mount('#header');
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
if (module.hot) {
|
|
|
|
// @ts-ignore
|
|
|
|
module.hot.accept('../../babel-plugin-jsx/src', () => {
|
|
|
|
compile();
|
|
|
|
});
|
|
|
|
}
|
2020-06-13 11:23:47 +08:00
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
const sharedEditorOptions: m.editor.IStandaloneEditorConstructionOptions = {
|
|
|
|
theme: 'vs-dark',
|
|
|
|
fontSize: 14,
|
|
|
|
wordWrap: 'on',
|
|
|
|
scrollBeyondLastLine: false,
|
|
|
|
renderWhitespace: 'selection',
|
|
|
|
contextmenu: false,
|
|
|
|
minimap: {
|
|
|
|
enabled: false,
|
|
|
|
},
|
|
|
|
};
|
2020-06-13 11:23:47 +08:00
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
|
|
|
allowJs: true,
|
|
|
|
allowNonTsExtensions: true,
|
2020-09-06 11:33:12 +08:00
|
|
|
jsx: monaco.languages.typescript.JsxEmit.Preserve,
|
2020-09-05 21:58:07 +08:00
|
|
|
target: monaco.languages.typescript.ScriptTarget.Latest,
|
|
|
|
});
|
2020-06-13 11:23:47 +08:00
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
const editor = monaco.editor.create(document.getElementById('source')!, {
|
|
|
|
value: decodeURIComponent(window.location.hash.slice(1)) || localStorage.getItem('state') || 'const App = () => <div>Hello World</div>',
|
2020-09-06 11:33:12 +08:00
|
|
|
language: 'typescript',
|
2020-09-05 21:58:07 +08:00
|
|
|
tabSize: 2,
|
|
|
|
...sharedEditorOptions,
|
|
|
|
});
|
2020-06-13 11:23:47 +08:00
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
const output = monaco.editor.create(document.getElementById('output')!, {
|
|
|
|
value: '',
|
|
|
|
language: 'javascript',
|
|
|
|
readOnly: true,
|
|
|
|
tabSize: 2,
|
|
|
|
...sharedEditorOptions,
|
2020-06-13 11:23:47 +08:00
|
|
|
});
|
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
const compile = () => {
|
|
|
|
const src = editor.getValue();
|
|
|
|
localStorage.setItem('state', src);
|
|
|
|
window.location.hash = encodeURIComponent(src);
|
|
|
|
console.clear();
|
|
|
|
transform(src, {
|
|
|
|
babelrc: false,
|
|
|
|
plugins: [[babelPluginJsx, { transformOn: true, optimize: true }]],
|
|
|
|
ast: true,
|
|
|
|
}, (err, result = {}) => {
|
|
|
|
const res = result!;
|
|
|
|
if (!err) {
|
|
|
|
console.log('AST', res.ast!);
|
|
|
|
output.setValue(res.code!);
|
|
|
|
} else {
|
|
|
|
output.setValue(err.message!);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
2020-06-13 11:23:47 +08:00
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
// handle resize
|
|
|
|
window.addEventListener('resize', () => {
|
|
|
|
editor.layout();
|
|
|
|
output.layout();
|
|
|
|
});
|
|
|
|
|
|
|
|
compile();
|
2020-06-13 11:23:47 +08:00
|
|
|
|
2020-09-05 21:58:07 +08:00
|
|
|
// update compile output when input changes
|
|
|
|
editor.onDidChangeModelContent(debounce(compile));
|
|
|
|
};
|
2020-06-13 11:23:47 +08:00
|
|
|
|
2020-07-28 21:25:30 +08:00
|
|
|
function debounce<T extends(...args: any[]) => any>(
|
2020-07-09 20:51:47 +08:00
|
|
|
fn: T,
|
2020-07-28 21:25:30 +08:00
|
|
|
delay = 300): T {
|
|
|
|
let prevTimer: number | null = null;
|
2020-07-09 20:51:47 +08:00
|
|
|
return ((...args: any[]) => {
|
2020-06-13 11:23:47 +08:00
|
|
|
if (prevTimer) {
|
2020-07-28 21:25:30 +08:00
|
|
|
clearTimeout(prevTimer);
|
2020-06-13 11:23:47 +08:00
|
|
|
}
|
|
|
|
prevTimer = window.setTimeout(() => {
|
2020-07-28 21:25:30 +08:00
|
|
|
fn(...args);
|
|
|
|
prevTimer = null;
|
|
|
|
}, delay);
|
|
|
|
}) as any;
|
2020-06-13 11:23:47 +08:00
|
|
|
}
|