当动态附加 Babel 时,动态附加的 JSX 不会被 Babel Standalone 转译
Dynamically appended JSX isn't transpiled by Babel Standalone when Babel is appended dynamically
当 Babel Standalone 作为 SCRIPT 标签的 SRC 属性提供时,Babel Standalone 可以处理动态附加的 JSX 代码。当使用 JavaScript 附加到 DOM 时,它不起作用。对于 React 库而言,情况并非如此,当动态附加 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>
babel-standalone 侦听 DOMContentLoaded
事件的触发,这导致它将任何 JSX 脚本块的转译版本附加到 HEAD
。在DOM 加载结束时,如果HEAD
没有SCRIPT
,则再次触发DOMContentLoaded
事件;下面是一个可以解决问题的代码块。
注意:这是针对 babel-standalone 的错误修复;如果正在使用的任何其他库也响应 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>
当 Babel Standalone 作为 SCRIPT 标签的 SRC 属性提供时,Babel Standalone 可以处理动态附加的 JSX 代码。当使用 JavaScript 附加到 DOM 时,它不起作用。对于 React 库而言,情况并非如此,当动态附加 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>
babel-standalone 侦听 DOMContentLoaded
事件的触发,这导致它将任何 JSX 脚本块的转译版本附加到 HEAD
。在DOM 加载结束时,如果HEAD
没有SCRIPT
,则再次触发DOMContentLoaded
事件;下面是一个可以解决问题的代码块。
注意:这是针对 babel-standalone 的错误修复;如果正在使用的任何其他库也响应 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>