From cba6397966a0fd5a9fa71f6ea6b3e88fde19aebf Mon Sep 17 00:00:00 2001 From: Florian Gail Date: Sun, 12 Jul 2026 11:26:58 +0200 Subject: [PATCH] Colocate node icons per node and copy them during build Align build.js with the node-red-example template: add copyIcons() to transfer each node's src/nodes//icons into dist/nodes//icons, drop the unused plugin/theme stubs. Move the icons out of the central icons/ directory into their nodes, ship src/resources instead. --- build.js | 185 ++++++++++-------- .../nodes/sacn-in/icons}/sacn-in.svg | 0 .../nodes/sacn-out/icons}/sacn-out.svg | 0 .../icons}/scene-controller.svg | 0 package.json | 3 +- resources/.gitkeep | 0 src/nodes/sacn-in/icons/sacn-in.svg | 7 + src/nodes/sacn-out/icons/sacn-out.svg | 7 + .../icons/scene-controller.svg | 10 + 9 files changed, 129 insertions(+), 83 deletions(-) rename {icons => dist/nodes/sacn-in/icons}/sacn-in.svg (100%) rename {icons => dist/nodes/sacn-out/icons}/sacn-out.svg (100%) rename {icons => dist/nodes/scene-controller/icons}/scene-controller.svg (100%) create mode 100644 resources/.gitkeep create mode 100644 src/nodes/sacn-in/icons/sacn-in.svg create mode 100644 src/nodes/sacn-out/icons/sacn-out.svg create mode 100644 src/nodes/scene-controller/icons/scene-controller.svg diff --git a/build.js b/build.js index b11e3fc..8d5a854 100644 --- a/build.js +++ b/build.js @@ -1,33 +1,57 @@ -const { cwd } = require("process"); +const { cwd } = require("node:process"); const ts = require("typescript"); const { - cp, readdirSync, - exists, existsSync, readFileSync, - writeFile, writeFileSync, mkdirSync, realpathSync, + copyFileSync, } = require("node:fs"); -const sourcePath = cwd() + "/src"; -const targetPath = cwd() + "/dist"; + +// directory containing the sources for nodes; defaults to `src/nodes` within the current working directory +const nodesSourceDir = cwd() + "/src/nodes"; +// directory the generated files should be saved to; defaults to `dist/nodes` within the current working directory +const nodesTargetDir = cwd() + "/dist/nodes"; +// path to the typescript project configuration for building the nodes const buildTsConfig = JSON.parse(readFileSync("build.tsconfig.json").toString()); /** - * @param node String - * @param source String - * @param target String + * Creates a directory if it does not exist + * @param {string} dir directory path to create + */ +function makeDir(dir) { + // bypass everything in case the directory already exists + if (!existsSync(dir)) { + const parentDir = realpathSync(`${dir}../`); + + // check whether parent directory exists and create it recursively if not + if (!existsSync(parentDir)) { + makeDir(parentDir); + } + + // finally create the directory + mkdirSync(dir); + } +} + +/** + * Builds the form for editing a node using the Node-RED Editor. + * + * @param {string} node name of the node the form belongs to + * @param {string} sourcePath path of the directory containing the node's source files + * @param {string} targetPath path of the directory the node's generated files should be saved to */ -function buildNodeForm(node, source, target) { +function buildForm(node, sourcePath, targetPath) { /** * @type {string[]} */ const html = []; - const form = readFileSync(`${source}/form.html`).toString(); - const docs = existsSync(`${source}/docs.html`) ? readFileSync(`${source}/docs.html`).toString() : undefined; + const form = readFileSync(`${sourcePath}/form.html`).toString(); + const docs = existsSync(`${sourcePath}/docs.html`) ? readFileSync(`${sourcePath}/docs.html`).toString() : undefined; + // parse `form.html` and wrap it to the corresponding script-tag const formLines = form.split("\n"); html.push(`"); + // parse `docs.html` and wrap it to the corresponding script-tag if (docs) { const docsLines = docs.split("\n"); html.push(`"); } - const initTS = readFileSync(`${source}/init.ts`).toString(); + // read and transpile the node's TypeScript + const initTS = readFileSync(`${sourcePath}/init.ts`).toString(); let initJS = ts .transpileModule(initTS, buildTsConfig) .outputText.replace(/export \{(?:[^\}]+)?\};/gim, "") .replace(/RED\.nodes\.registerType\("([^\"]+)"/i, `RED.nodes.registerType("${node}"`); + // inject the node's init logic into the node's HTML const initJSLines = initJS.split("\n"); html.push('