feat: jsx-explorer (#11)

This commit is contained in:
Amour1688
2020-06-13 11:23:47 +08:00
committed by GitHub
parent fc128fb981
commit 4dda1411b9
7 changed files with 474 additions and 24 deletions

View File

@ -0,0 +1,2 @@
# JSX Explorer

View File

@ -0,0 +1,7 @@
<title>Vue JSX Template Explorer</title>
<div id="header"></div>
<div id="source" class="editor"></div>
<div id="output" class="editor"></div>
<script src="/dist/main.js"></script>

View File

@ -0,0 +1,24 @@
{
"name": "@ant-design-vue/jsx-explorer",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "webpack-dev-server"
},
"dependencies": {
"monaco-editor": "^0.20.0"
},
"devDependencies": {
"@ant-design-vue/babel-plugin-jsx": "^1.0.0-alpha.4",
"@babel/core": "^7.0.0",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.3",
"file-loader": "^6.0.0",
"monaco-editor-webpack-plugin": "^1.9.0",
"style-loader": "^1.2.1",
"url-loader": "^4.1.0",
"webpack": "^4.43.0",
"webpack-dev-server": "^3.11.0",
"worker-plugin": "^4.0.3"
}
}

View File

@ -0,0 +1,92 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
#header {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 60px;
box-sizing: border-box;
background-color: #1e1e1e;
border-bottom: 1px solid #333;
padding: 0.3em 1.6em;
color: #fff;
z-index: 1;
}
h1 {
font-size: 18px;
display: inline-block;
margin-right: 15px;
}
#options-wrapper {
position: absolute;
top: 20px;
right: 10px;
}
#options-wrapper:hover #options {
display: block;
}
#options-label {
cursor: pointer;
text-align: right;
padding-right: 10px;
font-weight: bold;
}
#options {
display: none;
margin-top: 15px;
list-style-type: none;
background-color: #1e1e1e;
border: 1px solid #333;
padding: 15px 30px;
}
#options li {
margin: 8px 0;
}
#header a {
font-weight: 600;
color: rgb(101, 163, 221);
}
#header .label {
font-weight: bold;
}
#header input {
margin-right: 6px;
}
#header label {
color: #999;
}
.editor {
position: absolute;
top: 60px;
bottom: 0;
box-sizing: border-box;
}
#source {
left: 0;
width: 45%;
}
#output {
left: 45%;
width: 55%;
}
.highlight {
background-color: rgba(46, 120, 190, 0.5);
}

View File

@ -0,0 +1,88 @@
import * as monaco from 'monaco-editor';
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
if (module.hot) {
module.hot.accept('../../babel-plugin-jsx/src', () => {
compile();
});
}
const sharedEditorOptions = {
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: localStorage.getItem('state') || 'const App = () => <div>Hello World</div>',
language: 'javascript',
tabSize: 2,
...sharedEditorOptions,
});
const output = monaco.editor.create(document.getElementById('output'), {
value: '',
language: 'javascript',
readOnly: true,
tabSize: 2,
...sharedEditorOptions,
});
const compile = () => {
const src = editor.getValue();
localStorage.setItem('state', src);
transform(src, {
babelrc: false,
plugins: [babelPluginJSx],
}, (err, result) => {
if (!err) {
output.setValue(result.code);
} else {
output.setValue(err.message);
}
});
};
// handle resize
window.addEventListener('resize', () => {
editor.layout();
output.layout();
});
compile();
// update compile output when input changes
editor.onDidChangeModelContent(debounce(compile));
function debounce(fn, delay = 300) {
let prevTimer = null;
return ((...args) => {
if (prevTimer) {
clearTimeout(prevTimer);
}
prevTimer = window.setTimeout(() => {
fn(...args);
prevTimer = null;
}, delay);
});
}

View File

@ -0,0 +1,47 @@
const path = require('path');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'dist/fonts/[name].[hash:7].[ext]',
},
},
{
test: /\.css$/,
use: [
'style-loader', 'css-loader',
],
},
],
},
devServer: {
inline: true,
open: true,
hot: true,
overlay: true,
},
plugins: [
new MonacoWebpackPlugin(),
],
node: {
fs: 'empty',
},
};