【问题标题】:Dynamically appended JSX isn't transpiled by Babel Standalone when Babel is appended dynamically当 Babel 被动态附加时,动态附加的 JSX 不会被 Babel Standalone 转译
【发布时间】:2018-12-05 17:14:25
【问题描述】:

当 Babel Standalone 作为 SCRIPT 标签的 SRC 属性提供时,Babel Standalone 可以处理动态附加的 JSX 代码。当它使用 JavaScript 附加到 DOM 时,它不起作用。这不适用于 React 库,当 React 库被动态附加时,它们可以与动态附加的 JSX 一起正常工作。

首先,这里是 JSX 文件(react.jsx):

class HelloMessage extends React.Component {
  render() {
    return <h1>Hello</h1>;
  }
}
ReactDOM.render(<HelloMessage/>, document.getElementById('app'));

接下来,这里是使用它的 HTML。请注意,React 库和 JSX 文件是动态添加的;这工作正常。但是,Babel Standalone 仅在将 Babel Standalone 添加为 SCRIPT 元素的 SRC 时转换 JSX,而不是在使用附加 JS/JSX 其余部分的相同 JavaScript 附加它时。通过移除一个 Babel Standalone 调用并取消另一个状态,在两种状态之间切换。我想动态追加 Babel Standalone……有什么问题?

<!doctype html>
<html>
<head>
    <title>Inscrutable Babel Problem</title>
</head>
<body>
    <div>
        <p>Babel works only when added as a src of a SCRIPT element; it fails when the script is appended dynamically. HELLO will display below when it works.</p>
    </div>
    <div id=app></div>
<script>
function loadScript(src, type) {
    var script = document.createElement('script');
    script.src = src;
    if (type) {
        script.type = type;
    }
    script.async = false;
    document.body.appendChild(script);
}
loadScript('https://unpkg.com/react@16/umd/react.production.min.js');
loadScript('https://unpkg.com/react-dom@16/umd/react-dom.production.min.js');

// You'll need to place the REACT.JSX code above in a locally hosted file to reproduce the results: 
loadScript('react.jsx', 'text/babel');

// To toggle: rem the following line and un-rem the corresponding SCRIPT tag below
loadScript('https://unpkg.com/babel-standalone@6/babel.min.js');

</script>

<!-- To toggle: un-rem the the following SCRIPT tag and rem the last loadScript() call in the JavaScript above -->
<!--
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
-->

</body>
</html>

【问题讨论】:

    标签: javascript reactjs jsx babeljs react-dom


    【解决方案1】:

    babel-standalone 监听 DOMContentLoaded 事件触发,这导致它附加任何 JSX 脚本块的转译版本到 HEAD。在DOM加载结束时,如果HEAD没有SCRIPT,则再次触发DOMContentLoaded事件;下面是一个可以解决问题的代码块。

    注意:这是一个专门针对 babel-standalone 的 kludge 修复;如果使用中的任何其他库也响应 DOMContentLoaded,则其代码可能会再次运行,这可能是不可取的。

    document.onreadystatechange = function () {
        if (document.readyState === 'complete') {
            if (document.querySelectorAll('head script').length === 0) {
                window.dispatchEvent(new Event('DOMContentLoaded'));
            }
        }
    }
    

    因此,上面编辑的完整代码是:

    <!doctype html>
    <html>
    <head>
        <title>Inscrutable Babel Problem</title>
        <meta charset="utf-8">
    </head>
    <body>
        <div>
            <p>Babel runs when the DOMContentLoaded event is fired. HELLO will display below when it works.</p>
        </div>
        <div id=app></div>
    <script>
    function loadScript(src, type) {
        var script = document.createElement('script');
        script.src = src;
        if (type) {
                script.type = type;
        }
        script.async = false;
        document.body.appendChild(script);
    }
    loadScript('https://unpkg.com/react@16/umd/react.production.min.js');
    loadScript('https://unpkg.com/react-dom@16/umd/react-dom.production.min.js');
    loadScript('javascript/react.jsx', 'text/babel');
    loadScript('https://unpkg.com/babel-standalone@6/babel.min.js');
    
    // Listen for completion of DOM loading; if no SCRIPT element has been added
    // to the HEAD, fire the DOMContentLoaded event again:
    document.onreadystatechange = function () {
        if (document.readyState === 'complete') {
            if (document.querySelectorAll('head script').length === 0) {
                window.dispatchEvent(new Event('DOMContentLoaded'));
            }
        }
    }
    
    </script>
    </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 2019-09-30
      • 2019-08-25
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      相关资源
      最近更新 更多