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. bro
As mentioned in the docs, it's added in: v7.10.0
.
If you want to use your browser's native support for ES Modules, you'd normally need to set a
type="module"
attribute on your script tag.With @babel/standalone, set a
data-type="module"
attribute instead, like this:
<script type="text/babel" data-type="module">
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;
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
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>