Created Design: Flow Linter (markdown)

Kunihiko Toumura 2018-12-21 11:58:23 +09:00
parent 1fc805d18f
commit f34e91ff1c
1 changed files with 115 additions and 0 deletions

115
Design:-Flow-Linter.md Normal file

@ -0,0 +1,115 @@
# Purpose
Node-RED makes it easy to program by wiring nodes together. But sometimes, because of its less restrictive nature, programmer may write flows that are hard to understand. For example:
- Function node that has no name or description. The reader need to read internal JavaScript code to understand what the node do,
- Excessive amount of nodes in a single flow.
And, some subtle differences in programming style cause readability low.
- Size of flow on Flow Editor
- Grid size
- JavaScript coding style in function nodes.
The flow linter provides a framework that automatically checks whether a flow is compliant with rules and conventions.
# Use cases
- To use the consistent coding rules in a team, the tool checks a flow before submit to a repository.
- To prevent bugs, the tool checks a flow when the programmer requests it, or continuously checks as a background task of Flow Editor.
- Editor displays suggestions to user: 'This HTTP-in node doesn't have corresponding HTTP-out node.', 'These nodes in this flow must preserve message properties set by HTTP-in', etc.
- To prevent move/edit/delete node accidentally, some node position or property change can be restricted by rules.
# Requirements / ideas
- There are various rules/conventions, and each organization/community/etc. has different policies on it. Because of this, the rules has to be pluggable and customizable.
- Linter is used in both batch-style (e.g. command-line interface) and on-the-fly-style (e.g. integrated in Editor). The core service of linter can be used in both usages.
- Rule configuration can be exported as JSON format and can be included in flow.json so that developers can distribute flow templates with their own restrictions.
- Use compatible format with other linter/tester tools for result output.
# User interface
## Command-line interface (batch-style)
![External CLI](https://github.com/node-red-hitachi/node-red/wiki/images/linter/external-cli.png)
## Integrated in Editor (in Sidebar, batch-style)
![Sidebar](https://github.com/node-red-hitachi/node-red/wiki/images/linter/sidebar.png)
# Architecture
![Functional diagram](https://github.com/node-red-hitachi/node-red/wiki/images/linter/func-diagram.png)
## Flow manipulation API
The flow manipulation API provides a highlevel interface to handle flow.json file.
Programmers need not to know about the format of flow.json and structure of flow object.
## pluggable rules
Developer can create their own rules by writing plug-in module.
Following code shows example of plug-in, that checks existance of name of function node.
```javascript
function check (afs, conf, cxt) {
const funcs = [...afs] // extract all nodes
.filter(e => e.type==='function') // filter out unrelated nodes
.map(e => {
return {id:e.id, name:e.name}; // extract their node id and name
});
const verified = funcs
.filter(e=> e.name === undefined || e.name === "") // check existance of name
.map(e=> {
return {rule:"no-func-name", id:e.id, result:conf}; // generate result
});
return verified;
}
module.exports = {
check: check
};
```
- Flow-check code in plug-in is used on both CLI (runs on node.js) and Editor (runs on browser). To use same code in both node.js and browser, there are tools for generate codes for both:
- [Browserify](http://browserify.org/): get all dependent npm modules and put in one script file.
- [Babel](https://babeljs.io/): convert modern JavaScript (ES2015+) code to (traditional) JavaScript code that can be executed on various browsers.
## Configuration
Linter reads configuration files in following order:
1. Default configuration: nrlint.js in Node-RED install directory
2. Project-specific configuration: $HOME/.node-red/project/projectname/nrlint.js
3. Per-user configuration: $HOME/.node-red/nrlint.js
4. Command-line argument: nrlint --config nrlint.js / node-red --lintconfig nrlint.js
If there is a conflict between them, latter definition overrides former one.
- File format:
```javascript
module.exports = {
"plugins": [
"func-style"
],
"rules": {
"func-style/no-func-name": "warn",
"func-style/eslint": { semi: 2 }
}
}
```
## Report format
- should be similar format with other linting tools (e.g. ESlint, JShint, ...)
## Other Consideration
- When validation is invoked in Editor, validation codes should be executed in editor. API call to server-side is expencive, and it is need to add extra adminAPI in the core.
# Implementation plan
## First step
- Implement CLI version
- Considering future extention, e.g. use from Flow Editor, on-the-fly checking, etc.
## Next steps
- Implement Editor-integrated version (in Sidebar, batch-style)
- Rule configuration UI
- Make rules be exported as JSON format and can be included in flow.json so that developers can distribute flow templates with their own restrictions.
- On-the-fly checking in Editor
![On the fly](https://github.com/node-red-hitachi/node-red/wiki/images/linter/on-the-fly.png)
# Related works
- [Design: Flow Manipulation API](https://github.com/node-red/node-red/wiki/Design%3A-Flow-Manipulation-API)