105 lines
2.6 KiB
TypeScript
Raw Normal View History

2020-06-14 16:18:50 +08:00
/* eslint-disable no-console */
// eslint-disable-next-line import/no-unresolved
2020-06-13 11:23:47 +08:00
import * as monaco 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';
import babelPluginJSx from '../../babel-plugin-jsx/src';
import './index.css';
// or import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
// if shipping only a subset of the features & languages is desired
2020-06-14 16:18:50 +08:00
createApp(
() => h('h1', null, 'Vue JSX Explorer'),
).mount('#header');
// @ts-ignore
2020-06-13 11:23:47 +08:00
if (module.hot) {
// @ts-ignore
2020-06-13 11:23:47 +08:00
module.hot.accept('../../babel-plugin-jsx/src', () => {
compile();
});
}
const sharedEditorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
2020-06-13 11:23:47 +08:00
theme: 'vs-dark',
fontSize: 14,
wordWrap: 'on',
scrollBeyondLastLine: false,
renderWhitespace: 'selection',
contextmenu: false,
minimap: {
enabled: false,
},
};
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
allowJs: true,
allowNonTsExtensions: true,
lib: [],
jsx: monaco.languages.typescript.JsxEmit.React,
target: monaco.languages.typescript.ScriptTarget.Latest,
typeRoots: ['node_modules/@types'],
});
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-06-13 11:23:47 +08:00
language: 'javascript',
tabSize: 2,
...sharedEditorOptions,
});
const output = monaco.editor.create(document.getElementById('output')!, {
2020-06-13 11:23:47 +08:00
value: '',
language: 'javascript',
readOnly: true,
tabSize: 2,
...sharedEditorOptions,
});
const compile = () => {
const src = editor.getValue();
localStorage.setItem('state', src);
window.location.hash = encodeURIComponent(src);
2020-06-14 16:18:50 +08:00
console.clear();
2020-06-13 11:23:47 +08:00
transform(src, {
babelrc: false,
2020-06-14 16:18:50 +08:00
plugins: [[babelPluginJSx, { transformOn: true }]],
ast: true,
}, (err, result = {}) => {
const res = result!;
2020-06-13 11:23:47 +08:00
if (!err) {
console.log('AST', res.ast!);
output.setValue(res.code!);
2020-06-13 11:23:47 +08:00
} else {
output.setValue(err.message!);
2020-06-13 11:23:47 +08:00
}
});
};
// handle resize
window.addEventListener('resize', () => {
editor.layout();
output.layout();
});
compile();
// update compile output when input changes
editor.onDidChangeModelContent(debounce(compile));
function debounce<T extends (...args: any[]) => any>(
fn: T,
delay: number = 300
): T {
let prevTimer: number | null = null
return ((...args: any[]) => {
2020-06-13 11:23:47 +08:00
if (prevTimer) {
clearTimeout(prevTimer)
2020-06-13 11:23:47 +08:00
}
prevTimer = window.setTimeout(() => {
fn(...args)
prevTimer = null
}, delay)
}) as any
2020-06-13 11:23:47 +08:00
}