# Builds the React web UI via npm at CMake build time, into ${CMAKE_BINARY_DIR}/webui/dist. find_program(NPM_EXECUTABLE npm) if(NOT NPM_EXECUTABLE) message(WARNING "npm not found — skipping web UI build (set BUILD_WEBUI=OFF to silence)") return() endif() set(WEBUI_SRC "${CMAKE_SOURCE_DIR}/webui") set(WEBUI_DIST "${CMAKE_BINARY_DIR}/webui/dist") # Install dependencies once (when node_modules is absent). add_custom_command( OUTPUT "${WEBUI_SRC}/node_modules/.package-lock.json" COMMAND ${NPM_EXECUTABLE} ci --no-audit --no-fund WORKING_DIRECTORY "${WEBUI_SRC}" COMMENT "webui: npm ci" VERBATIM) # Everything the bundle is built from. Without these as DEPENDS the output # already exists after the first build, so editing a page or component would # never rebuild the UI and the server would keep serving a stale bundle. file(GLOB_RECURSE WEBUI_SOURCES CONFIGURE_DEPENDS "${WEBUI_SRC}/src/*" "${WEBUI_SRC}/index.html" "${WEBUI_SRC}/package.json" "${WEBUI_SRC}/package-lock.json" "${WEBUI_SRC}/vite.config.ts" "${WEBUI_SRC}/tsconfig*.json") # Build the UI into the CMake build tree (outDir override). add_custom_command( OUTPUT "${WEBUI_DIST}/index.html" COMMAND ${NPM_EXECUTABLE} run build -- --outDir "${WEBUI_DIST}" --emptyOutDir WORKING_DIRECTORY "${WEBUI_SRC}" DEPENDS "${WEBUI_SRC}/node_modules/.package-lock.json" ${WEBUI_SOURCES} COMMENT "webui: npm run build -> ${WEBUI_DIST}" VERBATIM) add_custom_target(webui ALL DEPENDS "${WEBUI_DIST}/index.html")