docs(devkit): initial project graph plugin guide (#5281)
This commit is contained in:
parent
95cdeaed06
commit
a01ea8ce25
@ -937,9 +937,14 @@
|
||||
"file": "shared/monorepo-tags"
|
||||
},
|
||||
{
|
||||
"name": "Dependency Graph",
|
||||
"name": "Project Graph",
|
||||
"id": "dependency-graph",
|
||||
"file": "shared/workspace/structure/dependency-graph"
|
||||
},
|
||||
{
|
||||
"name": "Extending the Project Graph",
|
||||
"id": "project-graph-plugins",
|
||||
"file": "shared/workspace/project-graph-plugins"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -1998,6 +2003,11 @@
|
||||
"name": "Dependency Graph",
|
||||
"id": "dependency-graph",
|
||||
"file": "shared/workspace/structure/dependency-graph"
|
||||
},
|
||||
{
|
||||
"name": "Extending the Project Graph",
|
||||
"id": "project-graph-plugins",
|
||||
"file": "shared/workspace/project-graph-plugins"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -3002,6 +3012,11 @@
|
||||
"name": "Dependency Graph",
|
||||
"id": "dependency-graph",
|
||||
"file": "shared/workspace/structure/dependency-graph"
|
||||
},
|
||||
{
|
||||
"name": "Extending the Project Graph",
|
||||
"id": "project-graph-plugins",
|
||||
"file": "shared/workspace/project-graph-plugins"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
71
docs/shared/workspace/project-graph-plugins.md
Normal file
71
docs/shared/workspace/project-graph-plugins.md
Normal file
@ -0,0 +1,71 @@
|
||||
# Extending the Project Graph of Nx
|
||||
|
||||
> This API is experimental and might change.
|
||||
|
||||
Nx views the workspace as a graph of projects that depend on one another. It's able to infer most projects and dependencies automatically. Currently, this works best within the Javascript ecosystem but it can be extended to other languages and technologies as well.
|
||||
|
||||
## Defining Plugins to be used in a workspace
|
||||
|
||||
In `nx.json`, add an array of plugins:
|
||||
|
||||
```json
|
||||
{
|
||||
...,
|
||||
"plugins": [
|
||||
"awesome-plugin"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
These plugins are used when running targets, linting, and sometimes when generating code.
|
||||
|
||||
## Implementing a Project Graph Processor
|
||||
|
||||
Project Graph Plugins are chained together to produce the final project graph. Each plugin may have a Project Graph Processor which iterates upon the project graph. Plugins should export a function named `processProjectGraph` that handles updating the project graph with new nodes and edges. This function receives two things:
|
||||
|
||||
- A `ProjectGraph`
|
||||
- Nodes in the project graph are the different projects currently in the graph.
|
||||
- Edges in the project graph are dependencies between different projects in the graph.
|
||||
- Some context is also passed into the function to use when processing the project graph. The context contains:
|
||||
- The `workspace` which contains both configuration as well as the different projects.
|
||||
- A `fileMap` which has a map of files by projects
|
||||
|
||||
The `processProjectGraph` function should return an updated `ProjectGraph`. This is most easily done using the `ProjectGraphBuilder` to iteratively add edges and nodes to the graph:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
ProjectGraph,
|
||||
ProjectGraphBuilder,
|
||||
ProjectGraphProcessorContext,
|
||||
DependencyType,
|
||||
} from '@nrwl/devkit';
|
||||
|
||||
export function processProjectGraph(
|
||||
graph: ProjectGraph,
|
||||
context: ProjectGraphProcessorContext
|
||||
): ProjectGraph {
|
||||
const builder = new ProjectGraphBuilder(graph);
|
||||
|
||||
// Add a new node
|
||||
builder.addNode({
|
||||
name: 'new-project',
|
||||
type: 'lib',
|
||||
data: {
|
||||
files: [],
|
||||
},
|
||||
});
|
||||
|
||||
// Add a new edge
|
||||
builder.addDependency(
|
||||
DependencyType.static,
|
||||
'existing-project',
|
||||
'new-project'
|
||||
);
|
||||
|
||||
return builder.getProjectGraph();
|
||||
}
|
||||
```
|
||||
|
||||
## Visualizing the Project Graph
|
||||
|
||||
You can then visualize the project graph as described [here](dependency-graph).
|
||||
@ -4,7 +4,7 @@ To be able to support the monorepo-style development, the tools must know how di
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/cMZ-ReC-jWU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
||||
## How the Dependency Graph is Built
|
||||
## How the Project Graph is Built
|
||||
|
||||
Nx creates a graph of all the dependencies between projects in your workspace using two sources of information:
|
||||
|
||||
|
||||
@ -1,15 +1,24 @@
|
||||
import { TargetConfiguration, Workspace } from '@nrwl/tao/src/shared/workspace';
|
||||
|
||||
/**
|
||||
* Some metadata about a file
|
||||
*/
|
||||
export interface FileData {
|
||||
file: string;
|
||||
hash: string;
|
||||
ext: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of files separated by the project they belong to
|
||||
*/
|
||||
export interface ProjectFileMap {
|
||||
[projectName: string]: FileData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A Graph of projects in the workspace and dependencies between them
|
||||
*/
|
||||
export interface ProjectGraph {
|
||||
nodes: Record<string, ProjectGraphNode>;
|
||||
dependencies: Record<string, ProjectGraphDependency[]>;
|
||||
@ -18,38 +27,86 @@ export interface ProjectGraph {
|
||||
allWorkspaceFiles?: FileData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of dependency between projects
|
||||
*/
|
||||
export enum DependencyType {
|
||||
/**
|
||||
* Static dependencies are tied to the loading of the module
|
||||
*/
|
||||
static = 'static',
|
||||
/**
|
||||
* Dynamic dependencies are brought in by the module at run time
|
||||
*/
|
||||
dynamic = 'dynamic',
|
||||
/**
|
||||
* Implicit dependencies are inferred
|
||||
*/
|
||||
implicit = 'implicit',
|
||||
}
|
||||
|
||||
/**
|
||||
* A node describing a project in a workspace
|
||||
*/
|
||||
export interface ProjectGraphNode<T = any> {
|
||||
type: string;
|
||||
name: string;
|
||||
/**
|
||||
* Additional metadata about a project
|
||||
*/
|
||||
data: T & {
|
||||
/**
|
||||
* The project's root directory
|
||||
*/
|
||||
root?: string;
|
||||
/**
|
||||
* Targets associated to the project
|
||||
*/
|
||||
targets?: { [targetName: string]: TargetConfiguration };
|
||||
/**
|
||||
* Files associated to the project
|
||||
*/
|
||||
files: FileData[];
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A dependency between two projects
|
||||
*/
|
||||
export interface ProjectGraphDependency {
|
||||
type: DependencyType | string;
|
||||
/**
|
||||
* The project being imported by the other
|
||||
*/
|
||||
target: string;
|
||||
/**
|
||||
* The project importing the other
|
||||
*/
|
||||
source: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional information to be used to process a project graph
|
||||
*/
|
||||
export interface ProjectGraphProcessorContext {
|
||||
/**
|
||||
* Workspace information such as projects and configuration
|
||||
*/
|
||||
workspace: Workspace;
|
||||
fileMap: ProjectFileMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that produces an updated ProjectGraph
|
||||
*/
|
||||
export type ProjectGraphProcessor = (
|
||||
currentGraph: ProjectGraph,
|
||||
context: ProjectGraphProcessorContext
|
||||
) => ProjectGraph;
|
||||
|
||||
/**
|
||||
* A plugin for Nx
|
||||
*/
|
||||
export interface NxPlugin {
|
||||
processProjectGraph: ProjectGraphProcessor;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user