You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派运行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:31:10