React项目通过CDN引入brain.js时遭遇'brain is not defined'错误的求助
React项目通过CDN引入brain.js时遭遇'brain is not defined'错误的求助
我来帮你分析并解决这个问题——你现在遇到的是ESLint代码检查报错和浏览器运行时变量未定义的双重问题,咱们一步步拆解:
你的问题重现
你的App.js代码和触发的报错如下:
你的代码
import { useEffect } from 'react'; import logo from './logo.svg'; import './App.css'; function App() { useEffect(() => { test(); // ... }, []) function test() { const script = document.createElement('script'); script.src = "https://unpkg.com/brain.js"; script.async = true; console.log("script"); document.body.appendChild(script); var net = new brain.recurrent.LSTM() net.train([ 'doe, a deer, a female deer', 'ray, a drop of golden sun', 'me, a name I call myself', ], { iterations: 1500, log: details => console.log(details), errorThresh: 0.011 }); var output = net.run('doe') // ', a deer, a female deer' const myOutput = document.querySelector('#myOutput'); myOutput.innerHTML = output; console.log(output) } return ( <div id="myOutput"></div> ); } export default App;
触发的报错
- ESLint检查报错
ERROR in [eslint] src\App.js Line 9:27: 'brain' is not defined no-undef
- 浏览器控制台运行时错误
同样会提示brain is not defined,因为脚本还没加载完成就执行了依赖代码。
为什么会出现这些错误?
- ESLint报错的原因:ESLint的代码检查机制默认不知道你要通过CDN引入的全局
brain变量,所以触发了no-undef(未定义变量)的规则报错。 - 运行时错误的原因:你给script标签设置了
async = true,这意味着brain.js是异步加载的,但你在创建脚本后立刻就执行了new brain.recurrent.LSTM()——这时候brain.js还没加载完,全局里根本没有brain这个对象,自然会报错。
两种解决方案(推荐第二种)
方案一:修复CDN引入的异步问题 + 解决ESLint报错
如果一定要用CDN的方式,需要做两个调整:
- 等脚本加载完成再执行代码:给script标签加
onload事件,把依赖brain的代码放进这个事件回调里; - 告诉ESLint
brain是全局变量:在代码开头声明全局变量,或者在ESLint配置里添加全局变量。
修改后的代码示例:
/* global brain */ // 声明brain为全局变量,解决ESLint的no-undef报错 import { useEffect } from 'react'; import './App.css'; function App() { useEffect(() => { test(); }, []) function test() { const script = document.createElement('script'); script.src = "https://unpkg.com/brain.js"; script.async = true; // 👇 关键:等brain.js加载完成后,再执行依赖它的代码 script.onload = () => { const net = new brain.recurrent.LSTM() net.train([ 'doe, a deer, a female deer', 'ray, a drop of golden sun', 'me, a name I call myself', ], { iterations: 1500, log: details => console.log(details), errorThresh: 0.011 }); const output = net.run('doe') // 预期输出:', a deer, a female deer' const myOutput = document.querySelector('#myOutput'); myOutput.innerHTML = output; console.log(output) } document.body.appendChild(script); } return ( <div id="myOutput"></div> ); } export default App;
如果不想在每个文件都加/* global brain */,可以在项目的.eslintrc.js(或.eslintrc.json)里全局配置:
module.exports = { // ...其他已有的配置 globals: { brain: 'readonly' // 声明brain为只读全局变量 } }
方案二:直接通过npm安装brain.js(更推荐)
对于React这类基于npm的前端项目,直接安装依赖包是更标准的做法,完全不用处理全局变量和异步加载的问题:
- 先在项目里安装brain.js
npm install brain.js # 或者用yarn:yarn add brain.js
- 在组件里直接导入使用
修改后的App.js代码:
import { useEffect } from 'react'; import './App.css'; import brain from 'brain.js'; // 直接导入brain.js,不用CDN function App() { useEffect(() => { test(); }, []) function test() { const net = new brain.recurrent.LSTM() net.train([ 'doe, a deer, a female deer', 'ray, a drop of golden sun', 'me, a name I call myself', ], { iterations: 1500, log: details => console.log(details), errorThresh: 0.011 }); const output = net.run('doe') // 预期输出:', a deer, a female deer' const myOutput = document.querySelector('#myOutput'); myOutput.innerHTML = output; console.log(output) } return ( <div id="myOutput"></div> ); } export default App;
这种方式完全符合React项目的依赖管理规范,也不会再出现任何变量未定义的问题。
备注:内容来源于stack exchange,提问作者redoc01
相关产品推荐
相关产品推荐

