在 babel-standalone 中使用 ES 模块
Using ES Modules with babel-standalone
引用 babel 文档 https://babeljs.io/docs/en/babel-standalone#usage :
"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"
虽然出于某种原因,当包含我的主 index.js 文件(使用 import 导入其他 js / jsx 文件)时,babel 似乎正在将我的导入语句转换为 require 语句,因为我得到了 ReferenceError:要求未定义。
我发现解决这个问题的唯一方法是使用 transform-modules-umd 插件并将我所有的 js 文件作为脚本包含在内。不确定这是 data-type="module" 不起作用的错误还是我遗漏了什么。
这些是我在 index.html
中的脚本标签
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="index.js" type="text/babel" data-type="module"></script>
感谢您的帮助
Amareis 在 babel 的 github 页面上回答了我的问题:https://github.com/babel/babel/discussions/12059
问题是 babel 不会转译通过 ES 模块导入的模块,它们必须明确地作为脚本包含,并将“类型”设置为“text/babel”。所以在 index.js 脚本中通过 ES 模块导入的 JSX 文件是在 index.js 被 babel 转译后导入的,而不是它自己转译。
还有一个建议是为了开发目的使用服务工作者获取和执行我的脚本。 babel-standalone 获取后转换它们
为了(我的)未来参考,这里有一个完整的工作示例。
您只需将下面的代码放入网络浏览器中的 index.html 和 运行 中,您将拥有一个使用 JSX 的 React 应用程序。
来源:https://codesandbox.io/s/dikoh?file=/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Static Template</title>
</head>
<body>
<div id="main"></div>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel" data-presets="react" data-type="module">
import {
ChakraProvider,
Box,
Text
} from "https://cdn.skypack.dev/@chakra-ui/react";
import React, { useRef } from "https://cdn.skypack.dev/react";
import ReactDOM from "https://cdn.skypack.dev/react-dom";
const MyText = ({ color, ...props }) => {
return <Text fontWeight="bold" as="span" {...props} />;
};
function Foo() {
return (
<div>
Foo
</div>
);
}
function App() {
return (
<Box>
Hello <MyText>Skypack</MyText>
<Foo/>
</Box>
);
}
ReactDOM.render(
<ChakraProvider>
<App />
</ChakraProvider>,
document.getElementById("main")
);
</script>
</body>
</html>
引用 babel 文档 https://babeljs.io/docs/en/babel-standalone#usage :
"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"
虽然出于某种原因,当包含我的主 index.js 文件(使用 import 导入其他 js / jsx 文件)时,babel 似乎正在将我的导入语句转换为 require 语句,因为我得到了 ReferenceError:要求未定义。
我发现解决这个问题的唯一方法是使用 transform-modules-umd 插件并将我所有的 js 文件作为脚本包含在内。不确定这是 data-type="module" 不起作用的错误还是我遗漏了什么。
这些是我在 index.html
中的脚本标签<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="index.js" type="text/babel" data-type="module"></script>
感谢您的帮助
Amareis 在 babel 的 github 页面上回答了我的问题:https://github.com/babel/babel/discussions/12059
问题是 babel 不会转译通过 ES 模块导入的模块,它们必须明确地作为脚本包含,并将“类型”设置为“text/babel”。所以在 index.js 脚本中通过 ES 模块导入的 JSX 文件是在 index.js 被 babel 转译后导入的,而不是它自己转译。
还有一个建议是为了开发目的使用服务工作者获取和执行我的脚本。 babel-standalone 获取后转换它们
为了(我的)未来参考,这里有一个完整的工作示例。
您只需将下面的代码放入网络浏览器中的 index.html 和 运行 中,您将拥有一个使用 JSX 的 React 应用程序。
来源:https://codesandbox.io/s/dikoh?file=/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Static Template</title>
</head>
<body>
<div id="main"></div>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel" data-presets="react" data-type="module">
import {
ChakraProvider,
Box,
Text
} from "https://cdn.skypack.dev/@chakra-ui/react";
import React, { useRef } from "https://cdn.skypack.dev/react";
import ReactDOM from "https://cdn.skypack.dev/react-dom";
const MyText = ({ color, ...props }) => {
return <Text fontWeight="bold" as="span" {...props} />;
};
function Foo() {
return (
<div>
Foo
</div>
);
}
function App() {
return (
<Box>
Hello <MyText>Skypack</MyText>
<Foo/>
</Box>
);
}
ReactDOM.render(
<ChakraProvider>
<App />
</ChakraProvider>,
document.getElementById("main")
);
</script>
</body>
</html>