mirror of
https://github.com/vuejs/babel-plugin-jsx.git
synced 2025-07-03 10:33:24 +08:00
feat: jsx-explorer (#11)
This commit is contained in:
2
packages/jsx-explorer/README.md
Normal file
2
packages/jsx-explorer/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# JSX Explorer
|
||||
|
7
packages/jsx-explorer/index.html
Normal file
7
packages/jsx-explorer/index.html
Normal 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>
|
24
packages/jsx-explorer/package.json
Normal file
24
packages/jsx-explorer/package.json
Normal 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"
|
||||
}
|
||||
}
|
92
packages/jsx-explorer/src/index.css
Normal file
92
packages/jsx-explorer/src/index.css
Normal 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);
|
||||
}
|
88
packages/jsx-explorer/src/index.js
Normal file
88
packages/jsx-explorer/src/index.js
Normal 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);
|
||||
});
|
||||
}
|
47
packages/jsx-explorer/webpack.config.js
Normal file
47
packages/jsx-explorer/webpack.config.js
Normal 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',
|
||||
},
|
||||
};
|
Reference in New Issue
Block a user