# React + Babel 项目规范 用HTML+React+Babel做原型时必须遵守的技术规范。不遵守会炸。 ## Pinned Script Tags(必须用这些版本) 在HTML的``里放这三个script tag,用**固定版本+integrity hash**: ```html ``` **不要**用`react@18`或`react@latest`这种unpinned版本——会出现版本漂移/缓存问题。 **不要**省略`integrity`——CDN一旦被劫持或篡改,这是防线。 ## 文件结构 ``` 项目名/ ├── index.html # 主HTML ├── components.jsx # 组件文件(type="text/babel"加载) ├── data.js # 数据文件 └── styles.css # 额外CSS(可选) ``` HTML里加载方式: ```html ``` **不要**用`type="module"`——会和Babel冲突。 ## 三条不可违反的规矩 ### 规矩1:styles 对象必须用唯一命名 **错误**(多组件时必炸): ```jsx // components.jsx const styles = { button: {...}, card: {...} }; // pages.jsx ← 同名覆盖! const styles = { container: {...}, header: {...} }; ``` **正确**:每个组件文件的styles用唯一前缀。 ```jsx // terminal.jsx const terminalStyles = { screen: {...}, line: {...} }; // sidebar.jsx const sidebarStyles = { container: {...}, item: {...} }; ``` **或者用inline styles**(小组件推荐): ```jsx
...
``` 这条是**非协商**的。每次写`const styles = {...}`都必须replace成specific命名,否则多组件加载时全栈报错。 ### 规矩2:Scope 不共享,需手动export **关键认知**:每个` ``` **注意**:浏览器直接调Anthropic API会遇到CORS问题。如果用户给你的预览环境不支持CORS bypass,这条路不通。这时候用选项A mock,或者告诉用户需要一个proxy后端。 ### 选项 C:用 agent 侧的 LLM 能力生成 mock 数据 如果只是本地演示用,可以在当前 agent 会话里临时调用该 agent 的 LLM 能力(或用户装的 multi-model 类 skill)先生成 mock 响应数据,再硬编码写进 HTML。这样 HTML 运行时完全不依赖任何 API。 ## 典型 HTML 起手模板 拷贝这个模板作为React原型的骨架: ```html Your Prototype Name
``` ## 常见报错及解决 **`styles is not defined` 或 `Cannot read property 'button' of undefined`** → 你在一个文件里定义了`const styles`,另一个文件覆盖了。给每个改成specific命名。 **`Terminal is not defined`** → 跨文件引用时scope不通。在定义Terminal的文件末尾加`Object.assign(window, {Terminal})`。 **整个页面白屏,控制台没错误** → 多半是JSX语法错误但Babel没报在控制台。把`babel.min.js`临时换成`babel.js`非压缩版,错误信息更清晰。 **ReactDOM.createRoot is not a function** → 版本不对。确认用了react-dom@18.3.1(而不是17或其他)。 **`Objects are not valid as a React child`** → 你渲染了一个对象而不是JSX/字符串。通常是`{someObj}`写成了`{someObj.name}`。 ## 大项目怎么拆文件 **>1000行的单文件**难维护。分拆思路: ``` 项目/ ├── index.html ├── src/ │ ├── primitives.jsx # 基础元素:Button、Card、Badge... │ ├── components.jsx # 业务组件:UserCard、PostList... │ ├── pages/ │ │ ├── home.jsx # 首页 │ │ ├── detail.jsx # 详情页 │ │ └── settings.jsx # 设置页 │ ├── router.jsx # 简单路由(React state切换) │ └── app.jsx # 入口组件 └── data.js # mock data ``` HTML里按顺序加载: ```html ``` **每个文件末尾**都要`Object.assign(window, {...})`导出要共享的东西。