如何使脚本类型既是 text/babel 又是module?

IT技术 javascript reactjs babeljs
2021-04-26 05:56:18

它工作得很好,因为我没有包含 JSX,但是当我用 替换脚本类型时text/babel,它不起作用,因为module无法加载。browser.js巴别编译器。

这里... JSX 仅在我替换脚本类型时有效,text/babel但问题是module无法加载,因为脚本不是module。知道如何让它与 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>
4个回答

2021 年 7 月更新

根据mh sattarian回答,您现在不需要data-plugins="transform-es2015-modules-umd"使用本机 es6 module的导入/导出等。相反,您只需添加data-type="module"

原答案

以防万一有人来这里寻找答案

babel Standalone 支持数据插件和数据预设

<script data-plugins="transform-es2015-modules-umd" type="text/babel">

在这里查看更多 Babel 独立版

文档中所述,它已添加到:v7.10.0

如果您想使用浏览器对 ES module的本机支持,您通常需要type="module"在脚本标签上设置一个属性。

使用@babel/standalone,data-type="module"改为设置一个属性,如下所示:

<script type="text/babel" data-type="module">

我认为问题是是否可以同时使用具有两种或多种类型的脚本标记(例如类似type="module, txt/babel")。据我所知,答案是否定的。

JonDotsoy 的回答有助于减少React.createElement一遍又一遍的打字,但即使有这样一个“可变快捷方式”,在使用带有嵌套元素的较大模板时,它也不像 JSX 那样舒服,因为h('div', {}, 'hello!!')...在这种情况下很难维护。

唯一的办法,我发现巴贝尔,而无需使用任何的构建工具这是... ...一个相当肮脏的黑客使用结合本地浏览器module支持和浏览器的JSX eval,不应该用于生产的应用程序:

索引.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.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")
);

应用程序/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;

应用程序/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;

您可能更喜欢使用别名createElement这种方式对发动机来说更快。例如使用he

const { createElement: h } = React;

const App = () => {
   return h('div', {}, 'hello!!'); 
}

否则,可以使用@babel/standalonemodule,请在此处查看更多信息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>