
本文详解在不使用构建工具(如 vite、webpack)的前提下,通过 cdn 引入 react 18 和 babel standalone,在静态 html 中成功渲染 jsx 组件的关键步骤与常见误区。
要在纯 HTML 页面中运行 React 组件(即“CDN 模式”),必须满足三个核心条件:正确的全局库加载顺序、JSX 编译支持,以及符合浏览器执行环境的语法规范。你原始代码未渲染的根本原因在于:
- ❌ 错误使用 import 语句(浏览器原生不支持 ES 模块语法,且 CDN 加载的 UMD 版本已挂载为全局 React/ReactDOM);
- ❌ 缺少 Babel Standalone —— 它是将 <h1>Hello World</h1> 这类 JSX 语法实时编译为 React.createElement() 调用的必需桥梁;
- ❌ ReactDOM.render() 在 React 18 中已被弃用(严格来说,它仍可在 legacy 模式下工作,但需注意 API 变更)。
✅ 正确做法如下:
1. 补全必要 CDN 脚本(含 Babel)
在 <head> 中按顺序引入:
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
⚠️ 注意:@babel/standalone 必须在 react-dom 之后引入,否则 type="text/babel" 脚本无法被识别和转译。
2. 使用函数组件 + JSX 语法(无需 import)
直接定义函数组件,并用 <Element /> 形式渲染:
立即学习“前端免费学习笔记(深入)”;
<script type="text/babel">
const Element = () => <h1>Hello World</h1>;
// React 18 推荐写法(推荐):
const root = ReactDOM.createRoot(document.getElementById("react-container"));
root.render(<Element />);
// 或兼容旧版(不推荐):
// ReactDOM.render(<Element />, document.getElementById("react-container"));
</script>3. 确保 DOM 元素存在且可访问
确保 <div id="react-container"></div> 在 <script> 执行前已存在于 DOM 中(放在 <body> 底部或使用 DOMContentLoaded 都可,但当前结构已满足)。
✅ 完整可运行示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>React in HTML</title>
<link rel="stylesheet" href="styles.css">
<!-- 必须按此顺序引入 -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<h1>My Website</h1>
<div id="react-container"></div>
<script type="text/babel">
const App = () => (
<div style={{ padding: '20px', fontFamily: 'sans-serif' }}>
<h1>Hello from React!</h1>
<p>This component is rendered directly in HTML.</p>
</div>
);
const root = ReactDOM.createRoot(document.getElementById("react-container"));
root.render(<App />);
</script>
</body>
</html>? 注意事项
- 本地文件协议限制:直接双击 .html 文件(file:// 协议)可能因浏览器安全策略导致 Babel 无法加载远程模块,务必使用本地服务器(如 npx serve、VS Code Live Server 插件或 Python 的 python -m http.server)。
- 生产环境慎用:CDN + Babel Standalone 仅适用于学习、演示或极简原型,性能与安全性远低于构建工具链(如 Vite)。
- React 18 已移除 ReactDOM.render():虽然 legacy API 在开发版中仍保留,但官方明确要求新项目使用 createRoot —— 这是并发渲染(Concurrent Rendering)的基础。
掌握这一模式,是你理解 React 运行原理的第一步;而迈向工程化开发,则建议尽快迁移到现代构建工具。











