25

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>
ryn
  • 66
  • 6
Shures Nepali
  • 453
  • 1
  • 5
  • 12
  • [Follow this question](https://stackoverflow.com/questions/63883713/using-es-modules-with-babel-standalone/64472452#64472452) it should answer your question – Edgar S. Oct 30 '21 at 04:07

4 Answers4

8

UPDATE July 2021

As per mh sattarian's answer you now don't need data-plugins="transform-es2015-modules-umd" to use native es6 module's import/export etc. Instead you simply add data-type="module"

Original Answer

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

nikhil mehta
  • 972
  • 15
  • 30
6

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">

mh sattarian
  • 2,936
  • 1
  • 11
  • 13
4

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;
Mountain
  • 1,039
  • 2
  • 10
  • 19
1

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>
JonDotsoy
  • 104
  • 1
  • 4