问题
It works perfectly because I haven't included JSX, but when I replace the script type with text/babel
, it doesn't work because the module fails to load. browser.js
the Babel compiler.
Here... JSX works only when i replace script type with text/babel
but the problem is module fails to load since the script is not module. Any idea how make it work with JSX?
<div id="root">
</div>
<script type="module">
import './react.min.js';
import './react-dom.min.js';
import './browser.js';
class Hello extends React.Component {
render() {
return React.createElement('div', null, `Hello ${this.props.toWhat}`);
}
}
ReactDOM.render(
React.createElement(Hello, {toWhat: 'World'}, null),
document.getElementById('root')
);
</script>
回答1:
Just in case if some one comes here looking for answer
There is a support for data-plugins and data-presets in babel standalone
<script data-plugins="transform-es2015-modules-umd" type="text/babel">
see more here Babel standalone
回答2:
I think the question was if it is possible to use a script tag with two or more types at the same time (e.g. something like type="module, txt/babel"
). As far as I know the answer is NO.
JonDotsoy's answer helps with reduce typing React.createElement
over and over again but even with such a "variable shortcut" it's not as comfortable as JSX when using larger templates with nested elements because h('div', {}, 'hello!!')...
is difficult to maintain in such cases.
The only way I found to combine native browser module support and in-browser Babel for JSX without using any build tool is this ... a rather dirty hack that uses eval
and should not be used for production apps:
index.html
<body>
<div id="app"></div>
<!-- Scripts ------- -->
<script src="vendor/js/babel.min.js"></script>
<script src="vendor/js/react.development.js"></script>
<script src="vendor/js/react-dom.development.js"></script>
<script src="app/app.js" type="module"></script>
</body>
app/app.js
import ComponentOne from "./ComponentOne.js";
let template = `
<div>
<h1>Heading</h1>
<hr />
<ComponentOne msg="MsgText-ComponentOne" />
</div>
`;
const App = () => {
return (
eval(Babel.transform(template, { presets: ['es2017', 'react'] }).code)
);
};
ReactDOM.render(
React.createElement(App, null),
document.getElementById("app")
);
app/ComponentOne.js
import ComponentTwo from "./ComponentTwo.js";
let template = `
<div>
<h2>This is ComponentOne</h2>
<p key="2">Property "msg" content: {props.msg}</p>
<ComponentTwo msg="MsgText-ComponentTwo" />
</div>
`;
const ComponentOne = (props) => {
return(
eval(Babel.transform(template, { presets: ['es2017', 'react'] }).code)
);
};
export default ComponentOne;
app/ComponentTwo.js
let template = `
<div>
<h2>This is ComponentTwo</h2>
<p key="2">Property "msg" content: {props.msg}</p>
</div>
`;
const ComponentTwo = (props) => {
return(
eval(Babel.transform(template, { presets: ['es2017', 'react'] }).code)
);
};
export default ComponentTwo;
回答3:
you may prefer to use an alias to createElement
. This way is faster for the engine.
For example use h
or e
.
const { createElement: h } = React;
const App = () => {
return h('div', {}, 'hello!!');
}
Otherwise, it is possible to use @babel/standalone
module, please see more on here https://babeljs.io/docs/en/next/babel-standalone.html.
<div id="app"></div>
<!-- Load Babel -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- Your custom script here -->
<script type="text/babel">
const { render } = ReactDOM;
const App = () => {
return <div>hello!!</div>
}
render(<App />, document.getElementById('app'));
</script>
来源:https://stackoverflow.com/questions/54018182/how-to-make-script-type-both-text-babel-and-module