如何在无打包工具的React项目中通过CDN使用react-ace?
解决方案:在无打包工具的React项目中使用Ace编辑器
选项1:基于原生Ace封装简易React组件
既然已经通过CDN引入了ace.js,可以自行封装轻量React组件来适配React环境,无需依赖react-ace库:
import { useEffect, useRef } from 'react'; const AceEditor = ({ value, onChange, mode = 'javascript', theme = 'monokai' }) => { const editorContainerRef = useRef(null); const aceInstanceRef = useRef(null); useEffect(() => { if (!window.ace) return; // 初始化Ace编辑器 aceInstanceRef.current = window.ace.edit(editorContainerRef.current); const editor = aceInstanceRef.current; // 配置编辑器基础属性 editor.setTheme(`ace/theme/${theme}`); editor.session.setMode(`ace/mode/${mode}`); editor.setValue(value, 1); // 1表示光标定位到内容末尾 // 绑定内容变更事件 const handleContentChange = () => { onChange?.(editor.getValue()); }; editor.on('change', handleContentChange); // 组件卸载时清理资源 return () => { editor.off('change', handleContentChange); editor.destroy(); }; }, []); // 监听外部value变化,同步更新编辑器内容 useEffect(() => { if (aceInstanceRef.current && aceInstanceRef.current.getValue() !== value) { aceInstanceRef.current.setValue(value, 1); } }, [value]); return <div ref={editorContainerRef} style={{ width: '100%', height: '400px' }} />; }; export default AceEditor;
使用示例:
<AceEditor value={yourCodeContent} onChange={(newValue) => setYourCodeContent(newValue)} mode="javascript" theme="monokai" />
注意:若需要特定语法高亮(如SCORM相关的XML、JavaScript),需额外通过CDN引入对应模式文件,例如:
<script src="https://cdn.jsdelivr.net/npm/ace-builds@1.32.3/src-noconflict/mode-javascript.js"></script> <script src="https://cdn.jsdelivr.net/npm/ace-builds@1.32.3/src-noconflict/theme-monokai.js"></script>
选项2:通过CDN引入UMD版react-ace
react-ace提供UMD版本,可直接通过CDN引入使用,无需打包工具:
首先在HTML中依次引入依赖:
<!-- 先引入React和ReactDOM的UMD生产版 --> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <!-- 引入Ace核心库 --> <script src="https://cdn.jsdelivr.net/npm/ace-builds@1.32.3/src-noconflict/ace.js"></script> <!-- 引入react-ace的UMD版 --> <script src="https://cdn.jsdelivr.net/npm/react-ace@10.1.0/build/ace.js"></script>
随后在React代码中调用:
const { AceEditor } = window.reactAce; function YourComponent() { const [code, setCode] = React.useState('// 编辑你的代码'); return ( <AceEditor value={code} onChange={setCode} mode="javascript" theme="monokai" name="scorm-editor" editorProps={{ $blockScrolling: true }} /> ); }
为什么直接const Editor = Ace无效?
你之前的写法不生效,是因为CDN引入的原生Ace暴露的是window.ace(而非window.Ace),它是原生JS编辑器实例,并非符合React规范的组件。React只能渲染函数组件或类组件,无法直接渲染原生JS对象。这和React Router的CDN使用逻辑一致:React Router的UMD版会暴露window.ReactRouterDOM对象,其中包含BrowserRouter等React组件,而非直接将全局变量作为组件使用。
内容的提问来源于stack exchange,提问作者Ennio Annio
相关产品推荐
相关产品推荐

