树莓派运行Google Teachable Machine JS代码报错问题排查求助
问题场景
在树莓派上开发基于JavaScript的多分类Google Teachable Machine项目时,直接复制官方示例代码运行,代码如下:
<div>Teachable Machine Image Model</div> <button type="button" onclick="init()">Start</button> <div id="webcam-container"></div> <div id="label-container"></div> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@0.8/dist/teachablemachine-image.min.js"></script> <script type="text/javascript"> // 模型相关API可参考官方说明 // Teachable Machine导出面板提供的模型路径 const URL = "./my_model/"; let model, webcam, labelContainer, maxPredictions; // 加载图像模型、初始化摄像头 async function init() { const modelURL = URL + "model.json"; const metadataURL = URL + "metadata.json"; // 加载模型和元数据 // 如果需要支持本地文件选择加载,可调用tmImage.loadFromFiles() model = await tmImage.load(modelURL, metadataURL); maxPredictions = model.getTotalClasses(); // 初始化摄像头参数 const flip = true; // 是否翻转摄像头画面 webcam = new tmImage.Webcam(200, 200, flip); // 参数依次为宽度、高度、是否翻转 await webcam.setup(); // 申请摄像头权限 await webcam.play(); window.requestAnimationFrame(loop); // 把摄像头画布、分类结果标签挂载到DOM document.getElementById("webcam-container").appendChild(webcam.canvas); labelContainer = document.getElementById("label-container"); for (let i = 0; i < maxPredictions; i++) { labelContainer.appendChild(document.createElement("div")); } } async function loop() { webcam.update(); // 刷新摄像头帧 await predict(); window.requestAnimationFrame(loop); } // 摄像头帧输入模型做推理 async function predict() { // predict方法支持传入图像、视频、canvas类型的DOM元素 const prediction = await model.predict(webcam.canvas); for (let i = 0; i < maxPredictions; i++) { const classPrediction = prediction[i].className + ": " + prediction[i].probability.toFixed(2); labelContainer.childNodes[i].innerHTML = classPrediction; } } </script>
遇到的问题
- 首次运行抛出错误:
jsx. component must have one parent element - 尝试给代码包裹父元素后,又抛出
unexpected token错误 - 先后尝试使用
.js、.jsx作为文件后缀并做对应重构,问题仍未解决 - 受技术栈限制,必须使用JavaScript实现,开发IDE为VS Code
错误原因
两个报错的核心原因是代码类型和文件使用方式不匹配:
你复制的这段是可以直接在浏览器运行的原生HTML+内联JS代码,不是JS模块/JSX组件代码。jsx component must have one parent element是JSX转译器的专属报错,说明你项目的构建工具直接把这段包含HTML标签、<script>标签的内容当作JS/JSX文件解析,解析器无法识别原生HTML的标签语法,自然会抛出语法错误,和修改文件后缀没有关系。
解决方法
根据你的项目场景二选一即可:
方案1:原生静态页运行(最快验证)
把整段代码保存为.html后缀的文件(比如index.html),将训练导出的my_model模型文件夹和该HTML文件放在同一目录下,直接用浏览器打开HTML文件,或者用静态文件服务托管该目录即可正常运行。
如果需要在树莓派上部署,用Nginx或者任意轻量静态文件服务托管目录即可访问,不需要额外配置JSX相关的构建环境。
方案2:集成到现有前端JS项目
如果需要把该功能嵌入已有的React/Vue等前端JS项目,不要直接复制整段HTML+script代码,按以下步骤改造:
- 把两个外部依赖的引入,放到项目入口HTML文件的头部,或者通过npm安装
@tensorflow/tfjs@1.3.1、@teachablemachine/image@0.8两个依赖后,在业务代码中导入使用 - 把代码里的DOM结构(标题、启动按钮、摄像头容器、结果展示容器)写到对应页面的组件模板中
- 把
<script>标签内的JS逻辑抽离,放到组件的生命周期函数、事件处理函数中,移除代码里的HTML标签、<script>包裹等原生HTML专属写法,将按钮的点击事件绑定到init方法即可。
内容的提问来源于stack exchange,提问作者Nick177
相关产品推荐
相关产品推荐

