
我最近用 Cursor 配合 Node.js 给自己搭了一套健康数据仪表盘不夸张地说整个过程几乎没有手写过成段代码。从数据录入、存储到图表可视化前后加起来大概一个下午。这篇文章就把完整流程拆开讲讲我是怎么选型、怎么写提示词、怎么避坑的。不管你是开发新手还是想给家庭健康数据找个归宿的普通用户这套思路都能直接抄作业。项目本身其实不复杂网页上填体重、睡眠、步数、饮水、运动时长这些数据后端用 Node.js 存到本地 JSON 文件前端用 Chart.js 画图最后在浏览器里看到近 30 天的趋势曲线。真正有意思的地方在于这套东西不是靠我自己一行行写出来的而是我用自然语言告诉 Cursor 想要什么让它把代码生成出来我再负责验证、修改和打磨。这就是所谓的“零代码”——更准确地说是“零门槛写代码”。1. 项目概述先想清楚这个仪表盘要解决什么1.1 为什么是 Cursor Node.js先说 Cursor。它就是基于 VS Code 改造的 AI 编辑器相当于你把一个能理解上下文、能写代码、能改 bug 的助手直接塞进了编辑器里。它的厉害之处不是单纯的代码补全而是你可以选中一段代码让它解释也可以直接在对话框里描述需求让它生成一个完整的文件甚至可以同时修改多个文件。对写“工具类”小项目来说Cursor 的生成质量足够高至少能覆盖掉 80% 的重复劳动。Node.js 的角色则是后台服务。很多人会问健康数据仪表盘不是纯前端也能做吗用 localStorage 存数据、用 Chart.js 画图不也能跑确实能跑但问题在于数据存在浏览器里换个设备就没了而且无法做数据导入导出、无法定时备份、也无法后续接手机端。Node.js 在这里承担两件事一是提供 HTTP 服务二是把数据落盘到本地文件。对于个人量级的数据完全不需要上数据库一个 JSON 文件就足够但这套架构已经有了“前后端分离”的影子以后想换成 SQLite 或者 MySQL 都顺理成章。1.2 “零代码”的真实边界“零代码”这三个字很容易被误解好像什么都不用懂就能做出完整应用。实际用下来我认为更准确的说法是“零手写代码”。你依然需要具备几项软技能能把自己的需求拆成功能点能看懂代码大致在做什么能识别报错信息并丢回给 AI 修改。这些能力门槛不高但不可或缺。比如在这个项目里我需要知道数据大概长什么样体重是浮点数步数是整数睡眠时长可以用小时数日期是字符串。我也需要知道后端和前端如何通信前端用 fetch 发请求后端接收 JSON 格式的数据。这些概念在跟 Cursor 对话的过程中会反复用到。换句话说用 Cursor 的“零代码”开发本质上是把“写代码”换成了“提需求 验证结果”。想清楚这一点你就知道为什么选 Node.js 而不是一个纯网页工具了——这套结构能让你在完全不精通编程的情况下也拥有一个可以用数据做点事的个人系统。2. 开工前的准备装好 Node.js 与 Cursor2.1 安装 Node.js这一步尽量稳一点很多人在 Node.js 安装上翻车不是版本选错就是环境变量没配上。我建议直接去官网 nodejs.org 下载 LTS 版本别下 Current。Current 版本功能新但个别依赖包可能还没跟上会出现一些莫名其妙的兼容问题。LTS 的意思就是长期维护版本稳定性优先对咱们这种小工具项目来说稳定比什么都重要。安装的时候一路 Next 就行需要注意一点安装向导里有一项是 “Add to PATH”这个一定要勾上。如果不勾装完你在命令行里敲 node -v 会提示找不到命令。装完之后打开终端验证一下node -v npm -v正常情况下会输出版本号比如 v20.11.0 和 10.2.4。如果提示找不到命令大概率是 PATH 没生效重启终端或者重启电脑基本能解决。还有一个常见问题热搜词里有“node.js 18 the requested module node:util does not provide an export named”这类报错往往是因为本机装了多版本 Node代码运行时用到了低版本不具备的新 API。建议后续凡是跑 Node 项目都用 nvm 或者 fnm 这类版本管理工具锁定版本避免全局环境越用越乱。2.2 Cursor 安装与中文界面设置Cursor 的安装很简单去官网 cursor.com 下载对应系统的安装包Windows 直接 exe 双击macOS 把 app 拖进 Applications 即可。第一次打开会让你选择信任工作区接着就是登录账号有一个免费额度可以先用着。很多人关心怎么设置中文其实 Cursor 本身是 VS Code 的分支界面语言设置和 VS Code 一样按快捷键 CtrlShiftX 打开扩展面板搜索 “Chinese”找到简体中文语言包点 Install 安装然后按 CtrlShiftP 打开命令面板输入 “Configure Display Language”选择 “中文(简体)”重启后界面就是中文了。不过说实话用 Cursor 做中文项目界面中不中文没那么重要。更重要的是让 Cursor 用中文回答你。这里有个小技巧在 Cursor 的对话输入框里直接告诉它“请全程用中文回答代码注释也用中文”它就会记住你的偏好。我习惯在第一次对话时就把这个要求提出来后续几乎不会再跑偏。2.3 项目目录怎么规划在开始写代码之前我建议先在本地建好项目目录别让 AI 全自动乱生成。目录结构决定了一个项目能多清晰。我的规划是health-dashboard/ ├── server.js ├── package.json ├── data/ │ └── health.json └── public/ ├── index.html ├── app.js └── style.css为什么要这样分server.js 是后端入口package.json 管理依赖data 目录专门放数据public 目录放前端静态文件。Cursor 在生成代码时如果你已经把目录建好并向它说明每个文件的职责它生成的代码结构会明显更合理不会出现所有代码塞在一个文件里的情况。数据文件 health.json 可以提前创建好内容初始化为一个空数组[]也可以交给程序自动创建但提前创建能少处理一次“文件不存在”的报错。3. 用 Cursor 写代码数据录入与存储是关键3.1 先给 AI 描述清楚需求打开 Cursor直接新建文件 server.js然后打开对话框快捷键 CtrlL 或点击右上角 Chat把我下面的这段提示词丢进去帮我创建一个健康数据仪表盘网站使用 Node.js Express 作为后端。需要实现 1. 提供一个 POST /api/records 接口接收 JSON 格式的健康记录date(日期YYYY-MM-DD)、weight(体重kg)、sleep(睡眠小时数)、steps(步数)、water(饮水杯数)、exercise(运动分钟数)。 2. 提供一个 GET /api/records 接口返回所有记录按日期排列。 3. 数据存储到本地 data/health.json 文件如果文件不存在则自动创建。 4. 提供静态文件服务public 目录下的 index.html、app.js、style.css 可以直接访问。 5. 请生成完整的 server.js 和 package.json并输出命令行安装依赖的命令。 请全程用中文回答代码注释也用中文。这段话看起来简单但里面包含了几个关键约束接口路径、字段名、存储位置、静态服务方式。如果你漏掉这些AI 就会自由发挥生成的接口字段跟前端不匹配后面一联调就是一堆 404。我后来复盘发现提示词里“按日期排列”这句话也很重要否则图表横坐标顺序可能就是乱的。3.2 数据模型与服务端接口Cursor 生成的核心代码大致长这样我稍微解释一下每一段的作用。首先是 server.js 的最关键部分const express require(express); const fs require(fs); const path require(path); const app express(); app.use(express.json()); app.use(express.static(path.join(__dirname, public))); const DATA_FILE path.join(__dirname, data, health.json); // 保证数据文件存在 function ensureDataFile() { if (!fs.existsSync(DATA_FILE)) { fs.writeFileSync(DATA_FILE, []); } } // 读取所有记录 function readRecords() { ensureDataFile(); const raw fs.readFileSync(DATA_FILE, utf8); return JSON.parse(raw); } // 写入记录 function writeRecords(records) { fs.writeFileSync(DATA_FILE, JSON.stringify(records, null, 2)); } app.post(/api/records, (req, res) { const record req.body; const records readRecords(); // 如果同一天已有记录则覆盖否则追加 const index records.findIndex(r r.date record.date); if (index 0) { records[index] record; } else { records.push(record); } writeRecords(records); res.json({ ok: true }); }); app.get(/api/records, (req, res) { const records readRecords(); records.sort((a, b) a.date.localeCompare(b.date)); res.json(records); }); app.listen(3000, () { console.log(server running at http://localhost:3000); });这里有个很贴心的设计同一天重复提交数据时不是追加一条新记录而是覆盖旧记录。比如你早上称了体重 72.5kg晚上数据修正成 72.3kg再次提交不会产生两条数据。这是我实际用下来后向 Cursor 追加的优化你可以在提示词里直接加上“同一天重复提交时覆盖旧数据”省得后面自己改。3.3 数据落盘为什么用 JSON 文件而不是数据库JSON 文件存储最大的优点是简单、透明、可读。数据量小的时候性能完全没问题个人一天 3 条记录一年也就 1000 条读一次文件只要几毫秒。另一个好处是你可以随时打开 data/health.json 手动修改错误数据或者把文件复制一份当备份。相比之下上数据库方案需要额外配置数据库服务、处理连接串、考虑表结构对“零代码”场景来说负担太重。但这种方式也有明显的局限多个进程同时写文件可能会冲突数据量大到几十万条时性能急剧下降。不过对个人健康数据来说这些场景几乎不会遇到。我更想强调的是在起步阶段用最简单的方案完成任务即可等数据量确实上去了再让 Cursor 帮你改成 SQLite无非是改一两个函数的事。架构上你已经把所有数据操作都收敛到了 readRecords 和 writeRecords 这两个函数里替换存储层非常方便。这就是为什么我一直强调代码结构比技术选型本身更重要。3.4 前端录入表单的实现要点前端页面我让 Cursor 生成的是一个简洁的表单加图表面板。核心表单部分每个输入项都用 type 和 min/max 做了基本限制。重点关注日期字段默认值要设为“今天”form idhealthForm label日期 input typedate iddate required/label label体重(kg) input typenumber idweight step0.1 min20 max250/label label睡眠(小时) input typenumber idsleep step0.5 min0 max24/label label步数 input typenumber idsteps min0 max100000/label label饮水(杯) input typenumber idwater min0 max30/label label运动(分钟) input typenumber idexercise min0 max600/label button typesubmit保存/button /form提交逻辑用 fetch 发送到后端成功后刷新图表document.getElementById(healthForm).addEventListener(submit, async (e) { e.preventDefault(); const form new FormData(e.target); const payload Object.fromEntries(form.entries()); await fetch(/api/records, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(payload) }); loadData(); });这里有一个容易踩的坑如果 input 的 name 属性和后端接口的字段名不一致比如前端叫 step后端要 steps数据就会丢失。所以你在让 Cursor 生成前后端时最好在提示词里提前统一字段名。我上面已经把所有字段名写好了直接用就行。4. 数据可视化让健康数据开口说话4.1 图表选型的底层逻辑健康数据有几种典型形态不是所有数据都适合同一种图表。我之前见过很多人拿折线图画步数、拿饼图画体重看着花哨信息表达效率很低。正确的选型逻辑是体重是连续变化量核心看趋势和波动所以用折线图X 轴是日期Y 轴是体重。步数每天一个总量核心是“某天走得多不多”和“最近的整体水平”柱状图最直观。睡眠、饮水、运动时长是三个不同的维度放在同一张雷达图里可以快速看出“今天的生活习惯偏科没有”。我把这个逻辑直接写进提示词“体重用折线图步数用柱状图睡眠/饮水/运动用时雷达图展示”。Cursor 就会自动选择对应的 Chart.js 图表类型不用你研究会怎么配置。值得一提的是Chart.js 本身非常轻量官方 CDN 可以直接用script srchttps://cdn.jsdelivr.net/npm/chart.js4.4.0/dist/chart.umd.min.js/script如果你的网络环境访问 CDN 不稳定也可以把 chart.umd.min.js 下载到 public 目录下用相对路径引用。本地化的方式更稳妥数据文件本来就是本地的完全没有必要依赖外网。4.2 用 Cursor 生成图表初始化代码生成完表单后继续在对话框里追加需求“在 app.js 中创建三个图表折线图、柱状图、雷达图数据来自 GET /api/records 接口。折线图展示体重柱状图展示步数雷达图展示最近七天的睡眠、饮水、运动平均值。”Cursor 生成的图表初始化代码大致是async function loadData() { const res await fetch(/api/records); const records await res.json(); renderLineChart(records); renderBarChart(records); renderRadarChart(records.slice(-7)); } function renderLineChart(records) { const dates records.map(r r.date); const weights records.map(r r.weight); new Chart(document.getElementById(weightChart), { type: line, data: { labels: dates, datasets: [{ label: 体重 (kg), data: weights, borderColor: #4caf50, tension: 0.3 }] }, options: { responsive: true } }); }这里有一点要提醒如果页面里有多个图表反复调用 new Chart 去初始化同一个 canvas 会报错“Canvas is already in use”。解决办法是先把旧的 chart 实例销毁或者在初始化前清空 canvas。最稳妥的做法是把 chart 实例存成全局变量刷新前调用chart.destroy()。我让 Cursor 帮我处理了这个问题你可以直接在提示词里声明“刷新数据时确保图表能正确更新不要重复初始化同一个图表”。4.3 交互细节筛选、刷新与空数据没有交互的仪表盘只是静态报表。我后来又加了两个小功能一是按时间范围筛选比如只看最近 7 天、30 天、90 天二是页面上放一个“刷新数据”按钮。筛选功能本质上只是在前端对 records 做一次 slice 或 filter然后再交给图表重新渲染。这个逻辑不复杂但对日常使用很重要——数据积累几个月后整个折线图密密麻麻不筛选根本看不清。空数据状态也值得花心思。刚搭好的时候 health.json 是空数组前端图表没有数据页面看起来就是一块灰色区域。如果你不想让体验突兀可以加一段提示“暂无数据请先添加一条记录”。这个在提示词里顺手加一句就行。另外在录入表单提交成功后最好给用户一个视觉反馈比如弹出一个小提示条否则你填完数据后连“有没有存成功”都不知道。5. 常见问题与排查心得5.1 Node.js 与依赖相关报错这一部分的坑基本都集中在 Node 环境上。先说最典型的一个在旧版 Node 上运行依赖高版本特性的代码会出现类似 “the requested module node:util does not provide an export named” 的报错。这个报错本质上是 API 版本不匹配不是你代码写错了。解决办法很简单把 Node 升级到 LTS 最新版或者通过 nvm 切换到项目指定的版本。还有一个高频问题启动时提示“端口 3000 已被占用”。这通常是你之前没关掉旧的 server 进程或者别的程序占了端口。排查思路是换一个端口比如 3001命令是node server.js然后在 server.js 里把app.listen(3000)改掉或者在 Windows 下用“任务管理器”找到 node 进程结束掉。为了避免这种问题我习惯在 server.js 顶部加一行环境变量端口读取const PORT process.env.PORT || 3000;这样以后想换端口不用改代码启动时PORT3001 node server.js即可。另外提一个热搜词里出现的“node.js v24.21.0 is not yet released or is not available”这种提示通常是在用 nvm 安装时版本号写错了或者该版本尚未发布。解决办法是用nvm ls available查看可安装的版本列表再挑一个 LTS 版本安装。这类报错和环境有关不要一上来就重装 Node先确认自己的版本管理工具有没有问题。5.2 Cursor 使用中的几个坑Cursor 生成代码的质量很高但也不是没有坑。我遇到最多的一个问题它生成的文件和现有目录结构不一致。比如我明明让它把前端文件放到 public 目录它却可能在根目录生成一个 index.html。解决办法很简单把它生成错位置的文件拖到 public 目录或者直接在对话里强调“所有前端文件都必须放在 public 目录下不要生成到根目录”。另一个问题是上下文长度。当你对话轮次太多或者让它修改一个超大文件时它可能会截断代码输出导致代码不完整。遇到这种情况你肉眼很难看出来通常是运行时报语法错误。我的经验是一旦发现输出中断直接让它“继续生成”它会从上次断掉的地方接上。如果反复出现就把大文件拆成小文件让 Cursor 分别生成比如 app.js 细分为 chart.js 和 form.js虽然麻烦一点但稳定性高很多。还有同学会问 Cursor 怎么设置成中文。前面说了扩展面板装中文语言包即可。如果只是想让 AI 返回中文直接在对话里提要求就行。这两个概念要分清界面语言是本地扩展负责的AI 回答语言是模型跟随指令的。5.3 数据与图表异常排查图表不显示是新手最常见的问题。别急着改代码先按下面的顺序排查打开浏览器开发者工具F12切到 Network 标签页重新加载页面看 /api/records 这个请求是不是返回了 200接着看 Console 有没有报错最后看 Response 里返回的数据格式是不是数组字段名和前端代码是否匹配。绝大多数图表问题都出在“数据没拿到”或者“字段名对不上”这两步上跟前端逻辑关系不大。还有一种情况是页面能打开但录入数据提交后提示 404。这大概率是前端请求的路径和后端路由不匹配。前端写的是/api/record后端定义的是/api/records少一个 s 就 404。这种错误非常隐蔽因为 Cursor 生成的两端代码通常是一致的但如果你自己手动改过前端的路径就很容易出这种低级问题。解决方式很直接以后前后端路径要修改时尽量让 Cursor 同时改避免人为不一致。下面是这段时间遇到的几个高频问题的速查表方便以后直接对照问题现象可能原因解决方案页面打不开终端报错 EADDRINUSE端口被占用换端口或结束旧 node 进程提交数据 404前端请求路径与后端路由不匹配检查 /api/records 前后写法图表空白无数据后端返回空数组先手动新增一条记录再刷新页面样式加载失败静态资源路径不对确认前端文件在 public 目录、引用路径正确新数据提交后图表没变化前端没有重新拉取数据在提交回调里调用 loadData()Cursor 生成文件位置不对提示词未指明目录在提示词中明确 public/ 与根目录Node 版本导致 API 缺失运行环境过旧升级到最新 LTS 或使用 nvm 固定版本6. 这块仪表盘的后续扩展方向健康数据仪表盘这个骨架建好之后能扩展的方向非常多。最简单的扩展是增加新的记录字段比如血压、心率、血糖后端只需在写入时校验字段前端加一个输入框图表再多画一个数据集就行。让 Cursor 做这件事基本就是一句话的功夫。再进一步可以把数据导出做成按钮调用接口生成 CSV 文件这样就能导入 Excel 或者第三方统计软件做深度分析。对于想长期记录健康数据的人来说导出能力几乎是必需品否则数据被锁定在一个小工具里时间越久越被动。CSV 导出的实现不复杂但价值很大算是性价比很高的一个功能。如果你有智能手环或者手表还可以考虑把手环 App 里的历史数据导出成 CSV再写一个导入脚本转换进 health.json。这样一来仪表盘的数据源就不局限于手动录入了。这个改造的核心是字段映射和单位换算让 Cursor 帮你处理 Excel 或 CSV 解析效率非常高。手动录入的问题在于容易忘有了自动导入数据完整性会好很多。如果你对数据同步有需求比如手机和电脑都能访问那就可以把 Node.js 服务部署到云服务器或者 NAS 上通过局域网甚至公网访问。这一块涉及部署和简单的鉴权但对已经跑通本地版本的人来说只是再加一层 nginx 反向代理和登录校验的事。还是那句话核心架构已经打好了扩展只是加模块。最后聊一个让我个人觉得特别值的点。这套系统的意义不在于画了几张图而在于它让我开始认真对待每天的数据。以前我只是在微信里收藏跑步记录App 换了就全丢了。现在数据在我自己的文件里结构清晰随时可读想怎么分析都行。用 Cursor 搭这套东西我最大的收获不是省了多少行代码而是把一个从“想要”到“拥有”的完整流程跑通了。以后不管你有什么想法用同样的思路——先说清楚需求再让 Cursor 生成骨架最后自己打磨细节——都能快速落地。这就是零代码时代给我的真实感受门槛降低了但你的判断力、想象力和动手验证的能力才是决定一个项目成败的关键。