The whole repository it is an opinionated monorepository:
- pnpm workspaces to manage monorepo:
- Fast, disk-efficient, strict node_modules isolation
- Supply-chain hardened: dependency build scripts denied by default (
strictDepBuildsallowBuildsinpnpm-workspace.yaml)
- Schema validation to guarantee runtime type checking
- ESLint (flat config) as linter + formatter with 4 plugins:
- No dealing with complicated setup
- StandardJS as code style (via
@stylistic) - SonarLint rules for code quality
- Perfectionist for import ordering
- Vitest as test suite
- Faster
- Quite easy to setup
- tsup as build layer on top of tsc
- Transpile to ESM + CJS
- Quite easy to setup
- Naming has some rules:
- All packages are published with scope
@coremarine - The library is called typically as
<manufacturer>-<protocol>or something like that - The NodeRED component is called the same as the library with
-noderedending - Example:
@coremarine/nmea-parserand@coremarine/nmea-parser-nodered
- All packages are published with scope
- Create well-tested and battle tested TypeScript library.
- Create a NodeRED wrapper / compoment which uses that library.
Always you have to create a custom branch and make pull requests to dev branch. Once the branch is merged, you should remove it.
New packages will be publish when a pull request into main branch is accepted.
- Copy the
libraryfolder insidetemplatesand paste as a new folder insidepackages->packages/<your-library> - Look for the keyword
TODO:in your IDE / Editor inside that folder, this is a hint to places you need to setup. - Setup pnpm package -> Modify library
package.json(packages/<your-library>/package.json)nameto@coremarine/<your-library>descriptionhomepagekeywords
- Setup pnpm workspaces -> Add scripts in global / monorepo
package.json:lintformatbuildtesttest:coverage
- Setup CI/CD (Github Actions)
- Copy
library.ymlfile insidetemplatesand paste as a new yml file<your-library>.ymlinside.github/workflowsfolder - Change all TODO:
- Copy
- Document your library -> Modify
README.md(packages/<your-library>/README.md) - Start with your library by coding in
srcand testing intests - Link your new library in the global / monorepo README
The reference implementation is packages/nmea-parser-nodered —
copy patterns from it. The node is authored in TypeScript, bundled to CJS with tsup
(node-red loads via require), split into a node-red-free src/lib.ts (unit-testable) + a thin
src/parser.ts adapter, and tested with node:test (no node-red-node-test-helper — it is
incompatible with node-red 5).
- Copy the
noderedfolder insidetemplatesas a new folder ending in-noderedinsidepackages->packages/<your-library>-nodered. - Look for the keyword
TODO:throughout that folder — each marks something to set up. package.json: setname(@coremarine/<your-library>-nodered),description,homepage,keywords,node-red.nodes.cma-<your-component>(->dist/parser.js), anddependencies.@coremarine/<your-library>: workspace:^.- Add proxy scripts to the monorepo
package.json:<your-library>:nodered:build,<your-library>:nodered:test,<your-library>:nodered:dev,<your-library>:nodered:examples,<your-library>:nodered:ci:local. - CI/CD: copy
templates/nodered.ymlto.github/workflows/<your-library>-nodered.ymland replace everyTODO:(incl. the "Build monorepo deps" step — build the wrapped library and any private deps it bundles). - Code in
src/(start fromlib.ts+parser.ts), test intests/(node:test:*.unit.test.ts- the real-node-red
*.integration.test.ts). Keep only the msg handlers your parser supports.
- the real-node-red
- See it live (no docker):
pnpm run <your-library>:nodered:dev-> http://localhost:1880 (edits a tracked scratch flowtests/dev.flows.json). Author the shipped example flows the same way withpnpm run <your-library>:nodered:examples— the flow-library requires anexamples/dir; it is shipped viafilesand shows under Node-RED's Import → Examples. Examples live inexamples/, neverdist/. - Document
README.md, then link the new component in the monorepo README.