docs(core): createNodesV2 in plugin docs (#29346)
Update the project graph plugin recipe to use createNodesV2
This commit is contained in:
parent
48cd50a550
commit
012d4e95a1
@ -96,7 +96,7 @@ export function registerProjectTargets(
|
||||
}
|
||||
```
|
||||
|
||||
For guidance on implementing a similar function in the v2 API, see the documentation on [createNodes](/extending-nx/recipes/project-graph-plugins#example-extending-projects-adding-targets).
|
||||
For guidance on implementing a similar function in the v2 API, see the documentation on [createNodes](/extending-nx/recipes/project-graph-plugins#example-extending-projects-adding-inferred-targets).
|
||||
|
||||
### Multiple Matches
|
||||
|
||||
|
||||
@ -1,15 +1,5 @@
|
||||
# Extending the Project Graph of Nx
|
||||
|
||||
{% callout type="info" title="Looking for `processProjectGraph`?" %}
|
||||
|
||||
Prior to Nx 16.7, a plugin could use `processProjectGraph`, `projectFilePatterns`, and `registerProjectTargets` to modify the project graph. This interface is still supported, but it is deprecated. We recommend using the new interface described below. For documentation on the v1 plugin api, see [here](/deprecated/v1-nx-plugin-api)
|
||||
|
||||
{% /callout %}
|
||||
|
||||
{% callout type="caution" title="Experimental" %}
|
||||
This API is experimental and might change.
|
||||
{% /callout %}
|
||||
|
||||
The Project Graph is the representation of the source code in your repo. Projects can have files associated with them. Projects can have dependencies on each other.
|
||||
|
||||
One of the best features of Nx the ability to construct the project graph automatically by analyzing your source code. Currently, this works best within the JavaScript ecosystem, but it can be extended to other languages and technologies using plugins.
|
||||
@ -34,7 +24,7 @@ You can register a plugin by adding it to the plugins array in `nx.json`:
|
||||
|
||||
## Adding New Nodes to the Project Graph
|
||||
|
||||
You can add nodes to the project graph with [`createNodes`](/nx-api/devkit/documents/CreateNodes). This is the API that Nx uses under the hood to identify Nx projects coming from a `project.json` file or a `package.json` that's listed in a package manager's workspaces section.
|
||||
You can add nodes to the project graph with [`createNodesV2`](/nx-api/devkit/documents/CreateNodesV2). This is the API that Nx uses under the hood to identify Nx projects coming from a `project.json` file or a `package.json` that's listed in a package manager's workspaces section.
|
||||
|
||||
### Identifying Projects
|
||||
|
||||
@ -56,19 +46,39 @@ Note: This is a shallow merge, so if you have a target with the same name in bot
|
||||
A simplified version of Nx's built-in `project.json` plugin is shown below, which adds a new project to the project graph for each `project.json` file it finds. This should be exported from the entry point of your plugin, which is listed in `nx.json`
|
||||
|
||||
```typescript {% fileName="/my-plugin/index.ts" %}
|
||||
export const createNodes: CreateNodes = [
|
||||
'**/project.json',
|
||||
(projectConfigurationFile: string, opts, context: CreateNodesContext) => {
|
||||
const projectConfiguration = readJsonFile(projectConfigurationFile);
|
||||
const root = dirname(projectConfigurationFile);
|
||||
import { createNodesFromFiles, readJsonFile } from '@nx/devkit';
|
||||
import { dirname } from 'path';
|
||||
|
||||
return {
|
||||
projects: {
|
||||
[root]: projectConfiguration,
|
||||
},
|
||||
};
|
||||
export interface MyPluginOptions {}
|
||||
|
||||
export const createNodesV2: CreateNodesV2<MyPluginOptions> = [
|
||||
'**/project.json',
|
||||
async (configFiles, options, context) => {
|
||||
return await createNodesFromFiles(
|
||||
(configFile, options, context) =>
|
||||
createNodesInternal(configFile, options, context),
|
||||
configFiles,
|
||||
options,
|
||||
context
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
async function createNodesInternal(
|
||||
configFilePath: string,
|
||||
options: MyPluginOptions,
|
||||
context: CreateNodesContextV2
|
||||
) {
|
||||
const projectConfiguration = readJsonFile(configFilePath);
|
||||
const root = dirname(configFilePath);
|
||||
|
||||
// Project configuration to be merged into the rest of the Nx configuration
|
||||
return {
|
||||
projects: {
|
||||
[root]: projectConfiguration,
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
{% callout type="warning" title="Dynamic target configurations can't be migrated" %}
|
||||
@ -80,43 +90,63 @@ If you create targets for a project within a plugin's code, the Nx migration gen
|
||||
|
||||
{% /callout %}
|
||||
|
||||
#### Example (extending projects / adding targets)
|
||||
#### Example (extending projects / adding inferred targets)
|
||||
|
||||
When writing a plugin to add support for some tooling, it may need to add a target to an existing project. For example, our @nx/jest plugin adds a target to the project for running Jest tests. This is done by checking for the presence of a jest configuration file, and if it is present, adding a target to the project.
|
||||
|
||||
Most of Nx's first party plugins are written to add a target to a given project based on the configuration files present for that project. The below example shows how a plugin could add a target to a project based on the presence of a `tsconfig.json` file.
|
||||
|
||||
```typescript {% fileName="/my-plugin/index.ts" %}
|
||||
export const createNodes: CreateNodes = [
|
||||
import { createNodesFromFiles, readJsonFile } from '@nx/devkit';
|
||||
import { dirname } from 'path';
|
||||
|
||||
export interface MyPluginOptions {}
|
||||
|
||||
export const createNodesV2: CreateNodesV2<MyPluginOptions> = [
|
||||
'**/tsconfig.json',
|
||||
(fileName: string, opts, context: CreateNodesContext) => {
|
||||
const root = dirname(fileName);
|
||||
async (configFiles, options, context) => {
|
||||
return await createNodesFromFiles(
|
||||
(configFile, options, context) =>
|
||||
createNodesInternal(configFile, options, context),
|
||||
configFiles,
|
||||
options,
|
||||
context
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
const isProject =
|
||||
existsSync(join(root, 'project.json')) ||
|
||||
existsSync(join(root, 'package.json'));
|
||||
if (!isProject) {
|
||||
return {};
|
||||
}
|
||||
async function createNodesInternal(
|
||||
configFilePath: string,
|
||||
options: MyPluginOptions,
|
||||
context: CreateNodesContextV2
|
||||
) {
|
||||
const projectConfiguration = readJsonFile(configFilePath);
|
||||
const projectRoot = dirname(configFilePath);
|
||||
|
||||
return {
|
||||
projects: {
|
||||
[root]: {
|
||||
targets: {
|
||||
build: {
|
||||
command: `tsc -p ${fileName}`,
|
||||
},
|
||||
const isProject =
|
||||
existsSync(join(projectRoot, 'project.json')) ||
|
||||
existsSync(join(projectRoot, 'package.json'));
|
||||
if (!isProject) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
projects: {
|
||||
[projectRoot]: {
|
||||
targets: {
|
||||
build: {
|
||||
command: `tsc -p ${fileName}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
By checking for the presence of a `project.json` or `package.json` file, the plugin can be more confident that the project it is modifying is an existing Nx project.
|
||||
|
||||
When extending an existing project, its important to consider how Nx will merge the returned project configurations. In general, plugins are run in the order they are listed in `nx.json`, abd then Nx's built-in plugins are run last. Plugins overwrite information that was identified by plugins that run before them if a merge is not possible.
|
||||
When extending an existing project, its important to consider how Nx will merge the returned project configurations. In general, plugins are run in the order they are listed in `nx.json`, and then Nx's built-in plugins are run last. Plugins overwrite information that was identified by plugins that run before them if a merge is not possible.
|
||||
|
||||
Nx considers two identified projects to be the same if and only if they have the same root. If two projects are identified with the same name, but different roots, there will be an error.
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user