forked from ppfun/pixelplanet
add quotes to markdown parser and expand test page
This commit is contained in:
parent
6c0148bf14
commit
554c67229f
3
.babelrc
3
.babelrc
|
@ -19,10 +19,11 @@
|
||||||
"@babel/plugin-proposal-numeric-separator",
|
"@babel/plugin-proposal-numeric-separator",
|
||||||
"@babel/plugin-proposal-throw-expressions",
|
"@babel/plugin-proposal-throw-expressions",
|
||||||
["@babel/plugin-proposal-class-properties", { "loose": true }],
|
["@babel/plugin-proposal-class-properties", { "loose": true }],
|
||||||
|
["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
|
||||||
"@babel/proposal-object-rest-spread",
|
"@babel/proposal-object-rest-spread",
|
||||||
"@babel/transform-react-constant-elements",
|
"@babel/transform-react-constant-elements",
|
||||||
"@babel/transform-react-inline-elements",
|
"@babel/transform-react-inline-elements",
|
||||||
"transform-react-remove-prop-types",
|
"transform-react-remove-prop-types",
|
||||||
"transform-react-pure-class-to-function",
|
"transform-react-pure-class-to-function"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,22 +15,36 @@ export default class MarkdownParser {
|
||||||
this.parseLinks = opt && opt.parseLinks || false;
|
this.parseLinks = opt && opt.parseLinks || false;
|
||||||
this.tabWidth = opt && opt.tabWidth || 4;
|
this.tabWidth = opt && opt.tabWidth || 4;
|
||||||
this.newlineBreaksArticles = opt && opt.newlineBreaksArticles || true;
|
this.newlineBreaksArticles = opt && opt.newlineBreaksArticles || true;
|
||||||
|
this.keepQuoteArrows = opt && opt.keepQuoteArrows || true;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseText(text: string, level = 0, start = 0) {
|
parse(text: string) {
|
||||||
|
return this.parseText(text, 0, 0, '')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
parseText(text, headingLevel, start, quoteLevel) {
|
||||||
let mdArray = [];
|
let mdArray = [];
|
||||||
let iter = start;
|
let iter = start;
|
||||||
while (iter < text.length) {
|
while (iter < text.length) {
|
||||||
const [aMdArray, newIter] = this.parseArticle(text, iter, level);
|
const [aMdArray, newIter, breaking] = this.parseSection(
|
||||||
|
text, iter, headingLevel, quoteLevel,
|
||||||
|
);
|
||||||
iter = newIter;
|
iter = newIter;
|
||||||
mdArray = mdArray.concat(aMdArray);
|
mdArray = mdArray.concat(aMdArray);
|
||||||
|
if (breaking) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
// either heading hit or article end
|
// either heading hit or article end
|
||||||
if (text[iter] === '#') {
|
const chr = text[iter];
|
||||||
|
if (chr === '#') {
|
||||||
let subLvl = 0;
|
let subLvl = 0;
|
||||||
for (;iter + subLvl <= text.length && text[iter + subLvl] === '#'; subLvl += 1) {}
|
for (;
|
||||||
if (subLvl <= level || level === 6) {
|
iter + subLvl <= text.length && text[iter + subLvl] === '#';
|
||||||
|
subLvl += 1
|
||||||
|
) {}
|
||||||
|
if (subLvl <= headingLevel || headingLevel === 6) {
|
||||||
// end of article
|
// end of article
|
||||||
// encountered title with same level or lower
|
// encountered title with same headingLevel or lower
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// child article
|
// child article
|
||||||
|
@ -39,11 +53,18 @@ export default class MarkdownParser {
|
||||||
const title = text.slice(iter + subLvl, lineEnd).trimLeft();
|
const title = text.slice(iter + subLvl, lineEnd).trimLeft();
|
||||||
subLvl = Math.min(subLvl, 6);
|
subLvl = Math.min(subLvl, 6);
|
||||||
const [subMdArray, newIter] = this.parseText(
|
const [subMdArray, newIter] = this.parseText(
|
||||||
text, subLvl, lineEnd + 1,
|
text, subLvl, lineEnd + 1, quoteLevel,
|
||||||
);
|
);
|
||||||
mdArray.push(['a', subLvl, title, subMdArray]);
|
mdArray.push(['a', subLvl, title, subMdArray]);
|
||||||
iter = newIter;
|
iter = newIter;
|
||||||
}
|
}
|
||||||
|
} else if (chr === '>' || chr === '<') {
|
||||||
|
// child quote
|
||||||
|
const [subMdArray, newIter] = this.parseText(
|
||||||
|
text, 0, iter - quoteLevel.length, quoteLevel + chr,
|
||||||
|
);
|
||||||
|
mdArray.push([chr, subMdArray]);
|
||||||
|
iter = newIter;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -52,12 +73,10 @@ export default class MarkdownParser {
|
||||||
return [mdArray, iter];
|
return [mdArray, iter];
|
||||||
}
|
}
|
||||||
|
|
||||||
stoppingCondition(text: string, iter: number) {
|
static stoppingCondition(text: string, iter: number) {
|
||||||
const chr = text[iter];
|
const chr = text[iter];
|
||||||
if (chr === '\n'
|
if (chr === '\n'
|
||||||
|| chr === '#'
|
|| chr === '#'
|
||||||
|| (chr === '`' && text[iter + 1] === '`' && text[iter + 2] === '`'
|
|
||||||
|| (chr === '-' && text[iter + 1] === ' '))
|
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -68,54 +87,149 @@ export default class MarkdownParser {
|
||||||
* parses Articles (contains paragraphs, code-blocks, numeration, etc.)
|
* parses Articles (contains paragraphs, code-blocks, numeration, etc.)
|
||||||
* @param text string of text
|
* @param text string of text
|
||||||
* @param start number of position in text where to start
|
* @param start number of position in text where to start
|
||||||
* @param level the number of heading levels we are in
|
* @param headingLevel the number of heading headingLevels we are in
|
||||||
* @param indent ndentation that should be considered
|
* @param indent ndentation that should be considered
|
||||||
* returns when encountering heading of <= level (iter is at # position)
|
* returns when encountering heading of <= headingLevel (iter is at # position)
|
||||||
* or heading-cancel with three spaces (iter is past newlines)
|
* or heading-cancel with three spaces (iter is past newlines)
|
||||||
* or ident is smaller than given
|
* or ident is smaller than given
|
||||||
*/
|
*/
|
||||||
parseArticle(text: string, start: number, level = 0, indent = 0) {
|
parseSection(
|
||||||
|
text: string,
|
||||||
|
start: number,
|
||||||
|
headingLevel = 0,
|
||||||
|
quoteLevel = '',
|
||||||
|
indent = 0,
|
||||||
|
) {
|
||||||
let iter = start;
|
let iter = start;
|
||||||
|
/*
|
||||||
|
* breaking is currently only used when
|
||||||
|
* end of quote block is reached
|
||||||
|
*/
|
||||||
|
let breaking = false;
|
||||||
const mdArray = [];
|
const mdArray = [];
|
||||||
let paraStart = iter;
|
let paraStart = iter;
|
||||||
|
let lineNr = 0;
|
||||||
|
|
||||||
|
const addParagraph = (start, end) => {
|
||||||
|
let paraText = text.slice(start, end);
|
||||||
|
if (!this.keepQuoteArrows && quoteLevel) {
|
||||||
|
paraText = paraText.split('\n')
|
||||||
|
.map((t) => t.trim().slice(quoteLevel.length))
|
||||||
|
.join('\n');
|
||||||
|
}
|
||||||
|
mdArray.push(['p', paraText]);
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (iter >= text.length) {
|
if (iter >= text.length) {
|
||||||
if (paraStart < text.length) {
|
if (paraStart < text.length) {
|
||||||
mdArray.push(['p', text.slice(paraStart)]);
|
addParagraph(paraStart, text.length);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// beginning of line
|
|
||||||
const paraLineStart = iter;
|
|
||||||
if (indent && this.getIndent(text, paraLineStart) <= indent) {
|
|
||||||
// smaller indent occured
|
|
||||||
|
|
||||||
|
const paraLineStart = iter;
|
||||||
|
lineNr += 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* break when in or out of quote levels
|
||||||
|
*/
|
||||||
|
if (!indent || lineNr > 1) {
|
||||||
|
if (text.startsWith(quoteLevel, iter)) {
|
||||||
|
iter += quoteLevel.length;
|
||||||
|
const chr = text[iter];
|
||||||
|
if (chr === '>' || chr === '<') {
|
||||||
|
if (iter - 1 > paraStart) {
|
||||||
|
addParagraph(paraStart, iter - quoteLevel.length - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// quote ended aka less deep quotelevel
|
||||||
|
if (iter - 1 > paraStart) {
|
||||||
|
addParagraph(paraStart, iter - 1);
|
||||||
|
}
|
||||||
|
breaking = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iter += quoteLevel.length;
|
||||||
}
|
}
|
||||||
iter = this.skipSpaces(text, iter);
|
|
||||||
if (stoppingCondition(text, iter)) {
|
/*
|
||||||
const chr = text[iter];
|
* act on indent
|
||||||
|
*/
|
||||||
|
let curIndent;
|
||||||
|
[curIndent, iter] = this.getIndent(text, iter);
|
||||||
|
if (curIndent < indent && lineNr > 1) {
|
||||||
|
if (paraLineStart - 1 > paraStart) {
|
||||||
|
addParagraph(paraStart, paraLineStart - 1);
|
||||||
|
}
|
||||||
|
iter = paraLineStart;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chr = text[iter];
|
||||||
|
|
||||||
|
if (chr === '-') {
|
||||||
|
if (paraLineStart - 1 > paraStart) {
|
||||||
|
addParagraph(paraStart, paraLineStart - 1);
|
||||||
|
}
|
||||||
|
let childMdArray;
|
||||||
|
[childMdArray, iter, breaking] = this.parseSection(
|
||||||
|
text,
|
||||||
|
iter + 1,
|
||||||
|
headingLevel,
|
||||||
|
quoteLevel,
|
||||||
|
curIndent + 1,
|
||||||
|
);
|
||||||
|
childMdArray = ['-', childMdArray];
|
||||||
|
// lists are encapsuled by 'ul'
|
||||||
|
if (!mdArray.length || mdArray[mdArray.length - 1][0] !== 'ul') {
|
||||||
|
mdArray.push(['ul', [childMdArray]]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mdArray[mdArray.length - 1][1].push(childMdArray);
|
||||||
|
}
|
||||||
|
if (breaking) {
|
||||||
|
return [mdArray, iter, breaking];
|
||||||
|
}
|
||||||
|
paraStart = iter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* code block
|
||||||
|
*/
|
||||||
|
if (chr === '`' && text[iter + 1] === '`' && text[iter + 2] === '`') {
|
||||||
|
if (paraLineStart - 1 > paraStart) {
|
||||||
|
addParagraph(paraStart, paraLineStart - 1);
|
||||||
|
}
|
||||||
|
const [cbArray, newIter] = this.parseCodeBlock(text, iter + 3);
|
||||||
|
mdArray.push(cbArray);
|
||||||
|
iter = newIter;
|
||||||
|
paraStart = iter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* other stopping conditions */
|
||||||
|
if (!indent && MarkdownParser.stoppingCondition(text, iter)) {
|
||||||
// encountered something - save paragraph
|
// encountered something - save paragraph
|
||||||
if (paraLineStart - 1 > paraStart) {
|
if (paraLineStart - 1 > paraStart) {
|
||||||
mdArray.push(['p', text.slice(paraStart, paraLineStart - 1)]);
|
addParagraph(paraStart, paraLineStart - 1);
|
||||||
}
|
}
|
||||||
|
const chr = text[iter];
|
||||||
if (chr === '\n') {
|
if (chr === '\n') {
|
||||||
iter = this.skipSpaces(text, iter + 1);
|
iter = this.skipSpaces(text, iter + 1);
|
||||||
if (text[iter] === '\n') {
|
if (text[iter] === '\n') {
|
||||||
if (level > 0 && this.newlineBreaksArticles) {
|
if (headingLevel && this.newlineBreaksArticles) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
iter += 1;
|
iter += 1;
|
||||||
}
|
}
|
||||||
} else if (chr === '-') {
|
|
||||||
const [cbArray, newIter] = this.parseList(text, paraLineStart);
|
|
||||||
} else if (chr === '#') {
|
} else if (chr === '#') {
|
||||||
break;
|
break;
|
||||||
} else if (chr === '`') {
|
|
||||||
// code block
|
|
||||||
const [cbArray, newIter] = this.parseCodeBlock(text, iter + 3);
|
|
||||||
mdArray.push(cbArray);
|
|
||||||
iter = newIter;
|
|
||||||
}
|
}
|
||||||
paraStart = iter;
|
paraStart = iter;
|
||||||
continue;
|
continue;
|
||||||
|
@ -125,7 +239,7 @@ export default class MarkdownParser {
|
||||||
iter += 1;
|
iter += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [mdArray, iter];
|
return [mdArray, iter, breaking];
|
||||||
}
|
}
|
||||||
|
|
||||||
parseList(text: string, start: number) {
|
parseList(text: string, start: number) {
|
||||||
|
@ -153,7 +267,7 @@ export default class MarkdownParser {
|
||||||
}
|
}
|
||||||
iter += 1;
|
iter += 1;
|
||||||
}
|
}
|
||||||
return getIndent;
|
return [indent, iter];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -161,7 +275,7 @@ export default class MarkdownParser {
|
||||||
* start is first character after the initializing ```
|
* start is first character after the initializing ```
|
||||||
* we just parse till the ending occures
|
* we just parse till the ending occures
|
||||||
*/
|
*/
|
||||||
parseCodeBlock(text: string, start: number) {
|
parseCodeBlock(text, start) {
|
||||||
const cbStart = this.skipSpaces(text, start, true);
|
const cbStart = this.skipSpaces(text, start, true);
|
||||||
let iter = cbStart;
|
let iter = cbStart;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -173,7 +287,7 @@ export default class MarkdownParser {
|
||||||
&& text[iter + 1] === '`'
|
&& text[iter + 1] === '`'
|
||||||
&& text[iter + 2] === '`'
|
&& text[iter + 2] === '`'
|
||||||
) {
|
) {
|
||||||
const nextIter = this.skipSpaces(text, iter + 3, true);
|
const nextIter = iter + 3;
|
||||||
return [['cb', text.slice(cbStart, iter)], nextIter];
|
return [['cb', text.slice(cbStart, iter)], nextIter];
|
||||||
}
|
}
|
||||||
for (;iter < text.length && text[iter] !== '\n'; iter += 1) {}
|
for (;iter < text.length && text[iter] !== '\n'; iter += 1) {}
|
92
utils/markdown-test/Markdown.jsx
Normal file
92
utils/markdown-test/Markdown.jsx
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Renders Markdown that got parsed by core/MarkdownParser
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const Markdown = ({ mdArray }) => {
|
||||||
|
return mdArray.map((part) => {
|
||||||
|
const type = part[0];
|
||||||
|
switch (type) {
|
||||||
|
/* Heading */
|
||||||
|
case 'a': {
|
||||||
|
const level = Number(part[1]);
|
||||||
|
const heading = part[2];
|
||||||
|
const children = part[3];
|
||||||
|
let headingElem = [];
|
||||||
|
switch (level) {
|
||||||
|
case 1:
|
||||||
|
headingElem = <h1>{heading}</h1>;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
headingElem = <h2>{heading}</h2>;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
headingElem = <h3>{heading}</h3>;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
headingElem = <h4>{heading}</h4>;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
headingElem,
|
||||||
|
<section>
|
||||||
|
<Markdown mdArray={children} />
|
||||||
|
</section>
|
||||||
|
];
|
||||||
|
}
|
||||||
|
/* Paragraph */
|
||||||
|
case 'p': {
|
||||||
|
const text = part[1];
|
||||||
|
return (
|
||||||
|
<p className="post-para">
|
||||||
|
{text}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/* Code Block */
|
||||||
|
case 'cb': {
|
||||||
|
/*
|
||||||
|
* using pe instead of code because pre
|
||||||
|
* keeps linebreaks
|
||||||
|
*/
|
||||||
|
const content = part[1];
|
||||||
|
return <pre>{content}</pre>;
|
||||||
|
}
|
||||||
|
case '>':
|
||||||
|
case '<': {
|
||||||
|
const children = part[1];
|
||||||
|
return (
|
||||||
|
<blockquote
|
||||||
|
className={(type === '>') ? 'gt' : 'rt'}
|
||||||
|
>
|
||||||
|
<Markdown mdArray={children} />
|
||||||
|
</blockquote>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case 'ul': {
|
||||||
|
const children = part[1];
|
||||||
|
return (
|
||||||
|
<ul>
|
||||||
|
<Markdown mdArray={children} />
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case '-': {
|
||||||
|
const children = part[1];
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
<Markdown mdArray={children} />
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return <p>{part[1]}</p>;
|
||||||
|
}
|
||||||
|
})};
|
||||||
|
|
||||||
|
const MarkdownArticle = ({ mdArray }) => (
|
||||||
|
<article>
|
||||||
|
<Markdown mdArray={mdArray} />
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default React.memo(MarkdownArticle);
|
25
utils/markdown-test/index.css
Normal file
25
utils/markdown-test/index.css
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
article {
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-para {
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: thin;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gt {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rt {
|
||||||
|
color: red;
|
||||||
|
}
|
|
@ -3,11 +3,10 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>Markdown Parser Test</title>
|
<title>Markdown Parser Test</title>
|
||||||
<meta name="description" content="Testing Markdown Parser">
|
<meta name="description" content="Testing Markdown Parser">
|
||||||
<meta name="author" content="hf">
|
<meta name="author" content="hf">
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import MarkdownParser from '../../src/core/Markdown';
|
|
||||||
import { Parser } from 'commonmark';
|
import { Parser } from 'commonmark';
|
||||||
|
|
||||||
const reader = new Parser({smart: true});
|
import MarkdownParser from '../../src/core/MarkdownParser';
|
||||||
|
|
||||||
|
import Markdown from './Markdown';
|
||||||
|
|
||||||
|
const reader = new Parser({ smart: true });
|
||||||
const a = new MarkdownParser();
|
const a = new MarkdownParser();
|
||||||
|
|
||||||
function parseText(text, setDuration, setCmDuration) {
|
function parseText(text, setDuration, setCmDuration, setMd) {
|
||||||
let startt = Date.now();
|
let startt = Date.now();
|
||||||
const [arr] = a.parseText(text);
|
const arr = a.parse(text);
|
||||||
setDuration(Date.now() - startt);
|
setDuration(Date.now() - startt);
|
||||||
startt = Date.now();
|
startt = Date.now();
|
||||||
const parsed = reader.parse(input.value);
|
reader.parse(text);
|
||||||
setCmDuration(Date.now() - startt);
|
setCmDuration(Date.now() - startt);
|
||||||
return JSON.stringify(arr, null, 2);
|
setMd(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [text, setText] = useState('');
|
const [md, setMd] = useState([]);
|
||||||
const [duration, setDuration] = useState('');
|
const [duration, setDuration] = useState('');
|
||||||
const [cmDuration, setCmDuration] = useState('');
|
const [cmDuration, setCmDuration] = useState('');
|
||||||
|
|
||||||
|
@ -27,19 +29,23 @@ const App = () => {
|
||||||
<textarea
|
<textarea
|
||||||
cols="100"
|
cols="100"
|
||||||
rows="30"
|
rows="30"
|
||||||
onChange={(evt) => setText(evt.target.value)}
|
onChange={(evt) => {
|
||||||
|
parseText(evt.target.value, setDuration, setCmDuration, setMd);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<p>Parse-time: {duration}ms / commonmark: {cmDuration}</p>
|
<p>Parse-time: {duration}ms / commonmark: {cmDuration}</p>
|
||||||
|
<Markdown mdArray={md} />
|
||||||
<textarea
|
<textarea
|
||||||
cols="100"
|
cols="100"
|
||||||
rows="30"
|
rows="30"
|
||||||
value={parseText(text, setDuration, setCmDuration)}
|
readOnly
|
||||||
|
value={JSON.stringify(md, null, 2)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
ReactDOM.render(App, document.getElementById('reactroot'));
|
ReactDOM.render(<App />, document.getElementById('reactroot'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ var babelPlugins = [
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'script',
|
name: 'script',
|
||||||
target: 'web',
|
target: 'web',
|
||||||
mode: 'production',
|
mode: 'development',
|
||||||
|
|
||||||
entry: [ path.resolve(__dirname, './mdtest.js') ],
|
entry: [ path.resolve(__dirname, './mdtest.js') ],
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user