Updated Design: Runtime Editor Split (markdown)

Nick O'Leary 2018-08-22 17:41:54 +01:00
parent 56d2ed3f70
commit ceb6cb2861
1 changed files with 67 additions and 44 deletions

@ -10,10 +10,6 @@ The plan is to break them up into their own discrete packages to provide some mo
- [Scaled](#scaled)
- [Repurposed Editor](#repurposed-editor)
- [Packaging](#packaging)
- [node-red-core-runtime](#node-red-core-runtime)
- [node-red-core-nodes](#node-red-core-nodes)
- [node-red-core-editor](#node-red-core-editor)
- [node-red](#node-red)
- [Code structure](#code-structure)
@ -78,51 +74,78 @@ The Node-RED editor is used for another system entirely that shares the same nod
## Packaging
At the top level, we'll have N npm packages (names tbc)
_The following reflects the current state of the [`repackage`](https://github.com/node-red/node-red/tree/repackage) branch where this is all being done._
- `@node-red/runtime` - the core runtime of Node-RED
- `@node-red/core-nodes` - the default set of nodes in the palette
- `@node-red/editor` - the editor component
- `@node-red/editor-api` - This provides an Express application that can be used to serve the Node-RED
editor
- `@node-red/editor-client` - This provides all of the client-side resources of the Node-RED editor application.
- `@node-red/nodes` - This provides all of the core Node-RED nodes.
- `@node-red/registry` - This provides the node registry, responsible for discovering and managing the node
modules available to the Node-RED runtime.
- `@node-red/runtime` - This provides the core flow engine of Node-RED. It is the main entry point for
the runtime.
- `@node-red/util` - This provides common utilities shared by the Node-RED components, including logging and i18n.
- `node-red` - the existing package that pulls the above packages together and delivers *exactly* the same experience as it does today
### @node-red/runtime
### @node-red/core-nodes
Moving the core nodes into their own repository poses some challenges in how they get loaded.
#### Current core node load mechanism
1. In the current code, the runtime starts at the path identified by `settings.coreNodesDir` and scans for js/html file pairs. `coreNodesDir` defaults to the `nodes` directory of the node-red module. It also walks up the tree from this directory looking for `node_modules` directories to scan.
2. The scan of the core nodes happens before the scan for node modules - so the core nodes are guaranteed to appear first in the palette.
3. The files are loaded as part of the `node-red` module namespace and there are various hardcoded shortcuts taken with the `node-red` namespace.
4. A single message catalog is registered that covers all core nodes - rather than one-per node-set as is the requirement for nodes loaded from modules.
#### Changes needed
1. have a mechanism to prioritise loading of `@node-red/core-nodes` to ensure node ordering
2. handle the migration case where `node-red` disappears from the list of nodes - if the auto-reinstall option is enabled (such as in IBM Cloud), we really don't want this to trigger a re-install as we know the nodes are being provided elsewhere
3. Either:
1. split up the message catalog to match the current file name scheme required of modules
2. allow a node module to declare a single message catalog that is loaded for all nodes in the module
4. Many nodes expect their message catalog namespace to be `node-red`. Need to either handle this as a special case, or update all the nodes to the correct catalog. Even then, there are 3rd party nodes that will be using `node-red:common.*` messages that must not change.
### @node-red/editor
### node-red
## Code structure
This is an open question as to whether the git repository should also be split into four along the same lines, or if the release build process would create the four modules from the one repo. There are pros/cons to both.
If we stick with a mono-repo, [lerna](https://lernajs.io/) could be used to manage it - needs some more investigation.
_The following reflects the current state of the [`repackage`](https://github.com/node-red/node-red/tree/repackage) branch where this is all being done._
All of the modules are maintained in a single monorepo. We do *not* plan to use Lerna or another toolkit for managing the monorepo. Instead we are using a structure inspired by [PouchDB](https://gist.github.com/nolanlawson/457cdb309c9ec5b39f0d420266a9faa4).
All of the modules live under:
```
packages
\- node_modules
|- node-red
| |- package.json
| \- ...
\- @node-red
|- editor-api
| |- package.json
| \- ...
|- editor-client
| |- package.json
| \- ...
|- nodes
| |- package.json
| \- ...
|- registry
| |- package.json
| \- ...
|- runtime
| |- package.json
| \- ...
\- util
|- package.json
\- ...
```
Each module has a package.json as normal, with its dependencies listed. A top-level package.json contains all non-node-red dependencies of the modules - this is the one that gets `npm install`ed at development time.
This directory structure means that when a node-red module `requires` another node-red module, it can be resolved on the node path.
A new test script is added, `scripts/verify-package-dependencies.js` that checks that the top level package.json is in sync with the individual module dependencies and that their version numbers agree.
#### Test material
The test material still lives under the `test` directory, albeit under a new `unit` sub-directory and the existing `grunt test` task continues to work.
A new test utility function has been added to help the tests to load individual module files. Whereas previously they would need lots of `"../../../../"` type paths to find their file, that was very brittle when files got moved. There is now a test module added under `test/node_modules/nr-test-utils`. This provides common utilities for the tests (distinct from `node-red-node-test-helper`). For example, the _spec file for `@node-red/registry/lib/localfilesystem` uses the following to load the file under test:
```
var NR_TEST_UTILS = require("nr-test-utils");
var localfilesystem = NR_TEST_UTILS.require("@node-red/registry/lib/localfilesystem");
```
Similarly, if a test needs to know the full path to a particular file, `.resolve` can be used:
```
const defaultIcon = NR_TEST_UTILS.resolve("@node-red/editor-client/src/images/icons/arrow-in.png");
```
## Discussion