WLED 的 Web UI 修改后页面没变化怎么办?重新生成 html_.h 与 js_.h
【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED
你改了wled00/data/里的 HTML、JS 或 CSS,重新烧录或刷新浏览器后,WLED 的 Web 界面却和修改前一模一样。这个现象的根源是:固件并不是直接加载wled00/data/里的源文件,而是加载由构建脚本生成的 C 头文件(wled00/html_*.h、wled00/js_*.h),这些头文件在编译时被内嵌进固件。只要头文件没有重新生成、固件没有重新编译烧录,设备上展示的就还是旧页面。
这篇文章针对这条排障路径:重新生成头文件 → 验证生成结果 → 重新编译固件 → 仍然没变化时的清理手段。适用前提是你在 WLED 源码仓库目录内工作,环境为 Node 20+(package.json 中engines要求"node": ">=20.0.0")并安装了 npm 与 PlatformIO。
页面为什么“没变化”:先确认 UI 的构建链路
WLED 的 Web UI 构建流程在 docs/web.instructions.md 和 tools/cdata.js 中有明确说明:
wled00/data/是 Web UI 源码目录(index.htm主界面、index.js、settings*.htm各设置页、*.css等)。- 该目录下的文件由
tools/cdata.js处理(内联、压缩、GZIP),输出为wled00/html_*.h和wled00/js_*.h,package.json 中对应的命令是npm run build(实际执行node tools/cdata.js)。 - tools/cdata.js 第 29 行列出了全部输出文件:
wled00/html_ui.h、html_pixart.h、html_cpal.h、html_edit.h、html_pxmagic.h、html_pixelforge.h、html_settings.h、html_other.h、js_iro.h、js_omggif.h。
因此页面没变化通常对应三种情况,按出现频率排序:
- 只改了源文件,没重新生成头文件(或生成脚本因时间戳判断跳过了重建);
- 头文件已重新生成,但固件没有重新编译烧录;
- 生成头文件本身被手工编辑过,而下次重建时它会被脚本覆盖。
docs/web.instructions.md 和 AGENTS.md 都给出同一条硬性规则:Never edit generated headers directly—— 不要直接修改wled00/html_*.h或wled00/js_*.h,所有改动都要落在wled00/data/的源文件上。如果你之前是改的头文件,那部分改动在下次npm run build后会被丢弃,页面自然“回到原样”。
准备条件
在仓库根目录执行一次依赖安装(首次或node_modules不可用时必做):
npm cinpm ci会按 package-lock.json 安装clean-css、html-minifier-terser、web-resource-inliner等构建依赖。AGENTS.md 明确要求:pio run之前必须先跑npm ci && npm run build,因为固件编译依赖这些由 Web UI 构建生成的 C 头文件。
重新生成 html_.h 与 js_.h
修改完wled00/data/下的源文件后,执行:
npm run build执行时注意脚本的输出。tools/cdata.js 内置了一个“是否已构建”检查(isAlreadyBuilt,见 tools/cdata.js):如果wled00/data/里没有任何文件比已生成的头文件更新,脚本会直接打印Web UI is already built并退出,不做任何重建。这就是“明明改了源文件,build 却没生效”的常见原因——比如文件时间戳没有更新、或从别处复制文件时时间戳落后于头文件。
遇到这种情况,用 AGENTS.md “Recovery / Troubleshooting”一节给出的强制重建命令(-- -f会把-f传给脚本,脚本第 249 行对--force/-f都接受):
npm run build -- -f真正执行重建时,脚本会逐文件打印(以下为脚本内console.info的实际输出格式,字节数只是示意):
Reading wled00/data/index.htm Minified and compressed wled00/data/index.htm from 123456 to 45678 bytes Writing wled00/html_ui.h看到对应输出文件的Writing ...行,说明该头文件已被重写。
验证生成结果
两个层次的验证:
- 生成产物:确认
wled00/下的html_*.h、js_*.h已被更新(修改时间变为本次构建时间)。单个页面头文件(如html_ui.h)头部会包含本次构建的 UNIX 时间戳宏,tools/cdata.js 生成的模板为#define WEB_BUILD_TIME <时间戳>,注释标明它的用途是 cache busting(浏览器缓存失效)。 - 测试套件:AGENTS.md 说明 Web UI 构建有对应的 Node 内置测试,测试文件是
tools/cdata-test.js:
npm test # 或只跑这一个文件 node --test tools/cdata-test.js测试通过说明构建脚本与生成逻辑本身没有异常。注意NODE_ENV=test时 tools/cdata.js 会跳过实际构建动作,测试只验证函数逻辑,不会替你重写头文件。
重新编译并烧录固件,改动才会出现在设备上
头文件是固件源码的一部分(wled00/wled_server.cpp 直接#include "html_ui.h"、#include "html_settings.h"),所以只重新生成头文件、不重编固件,设备上的页面不会有任何变化。按 AGENTS.md 的顺序执行:
npm ci && npm run build pio run -e esp32devesp32dev是最常用的 ESP32 编译环境;ESP8266 目标对应pio run -e nodemcuv2。编译成功后把新固件烧录到设备,再打开设备 Web 界面核对改动是否出现。
另外,wled00/wled_server.cpp 中服务端 ETag 的格式为%u-%02x-%04x,第一个字段就是WEB_BUILD_TIME。这意味着每次重新生成头文件后WEB_BUILD_TIME都会变化,固件重烧后服务端返回的 ETag 随之变化,客户端会按新内容处理,不需要额外手动清缓存。
仍然没变化时的清理步骤
以下命令都来自 AGENTS.md 的 “Recovery / Troubleshooting” 一节。前两条会删除文件,先说明副作用再执行:
清理并重建 Web UI 头文件。rm -f wled00/html_*.h wled00/js_*.h只删除仓库中由脚本生成的头文件(它们本就会被重新生成),随后重新构建:
rm -f wled00/html_*.h wled00/js_*.h && npm run build重装 Node 依赖。rm -rf node_modules会删除整个依赖目录(仅限项目内),随后用npm ci按 lockfile 重装:
rm -rf node_modules && npm ci清理 PlatformIO 构建产物。如果你怀疑固件编译用了陈旧的中间产物:
pio run --target clean之后再按上面的顺序重新npm ci && npm run build、pio run -e esp32dev并烧录。
可选:用 watch 模式避免再次踩坑
如果会连续多次修改wled00/data/下的文件,可以改用 package.json 中的dev脚本:
npm run dev它通过 nodemon 监听tools/与wled00/data/下的js,html,htm,css,png,jpg,gif,ico文件,任一文件变化就自动重跑node tools/cdata.js(tools/cdata.js 头部注释同样说明了这个用法)。这样每次保存都会重新生成头文件,避免“忘了 build”或时间戳判断跳过重建的问题。
边界与限制
wled00/html_*.h、wled00/js_*.h是自动生成的,任何时候都不要手工编辑或提交其中的改动,改动一律落在wled00/data/(见 docs/web.instructions.md、AGENTS.md)。npm run build的跳过逻辑基于文件修改时间:源文件时间戳不新于头文件时只会打印Web UI is already built,需要-f强制重建。- 固件必须重新编译并烧录后,界面上的变化才会生效——UI 是内嵌在固件里的,不存在“只更新网页文件”这一路径。
【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考