feat(core): change the signature of createNodes to return a project root map instead of project name map (#20102)
This commit is contained in:
parent
c7d0d21761
commit
08a4891494
@ -1,6 +1,6 @@
|
|||||||
# Type alias: CreateNodesFunction<T\>
|
# Type alias: CreateNodesFunction<T\>
|
||||||
|
|
||||||
Ƭ **CreateNodesFunction**<`T`\>: (`projectConfigurationFile`: `string`, `options`: `T` \| `undefined`, `context`: [`CreateNodesContext`](../../devkit/documents/CreateNodesContext)) => { `externalNodes?`: `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\> ; `projects?`: `Record`<`string`, [`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration)\> }
|
Ƭ **CreateNodesFunction**<`T`\>: (`projectConfigurationFile`: `string`, `options`: `T` \| `undefined`, `context`: [`CreateNodesContext`](../../devkit/documents/CreateNodesContext)) => { `externalNodes?`: `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\> ; `projects?`: `Record`<`string`, `Optional`<[`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration), `"root"`\>\> }
|
||||||
|
|
||||||
#### Type parameters
|
#### Type parameters
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ Used for creating nodes for the [ProjectGraph](../../devkit/documents/ProjectGra
|
|||||||
|
|
||||||
`Object`
|
`Object`
|
||||||
|
|
||||||
| Name | Type |
|
| Name | Type | Description |
|
||||||
| :--------------- | :------------------------------------------------------------------------------------------------- |
|
| :--------------- | :---------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- |
|
||||||
| `externalNodes?` | `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\> |
|
| `externalNodes?` | `Record`<`string`, [`ProjectGraphExternalNode`](../../devkit/documents/ProjectGraphExternalNode)\> | A map of external node name -> external node. External nodes do not have a root, so the key is their name. |
|
||||||
| `projects?` | `Record`<`string`, [`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration)\> |
|
| `projects?` | `Record`<`string`, `Optional`<[`ProjectConfiguration`](../../devkit/documents/ProjectConfiguration), `"root"`\>\> | A map of project root -> project configuration |
|
||||||
|
|||||||
@ -60,15 +60,11 @@ export const createNodes: CreateNodes = [
|
|||||||
'**/project.json',
|
'**/project.json',
|
||||||
(projectConfigurationFile: string, opts, context: CreateNodesContext) => {
|
(projectConfigurationFile: string, opts, context: CreateNodesContext) => {
|
||||||
const projectConfiguration = readJson(projectConfigurationFile);
|
const projectConfiguration = readJson(projectConfigurationFile);
|
||||||
const projectRoot = dirname(projectConfigurationFile);
|
const root = dirname(projectConfigurationFile);
|
||||||
const projectName = projectConfiguration.name;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
projects: {
|
projects: {
|
||||||
[projectName]: {
|
[root]: projectConfiguration,
|
||||||
...projectConfiguration,
|
|
||||||
root: projectRoot,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -244,12 +240,10 @@ export const createNodes: CreateNodes<MyPluginOptions> = [
|
|||||||
'**/project.json',
|
'**/project.json',
|
||||||
(fileName, opts, ctx) => {
|
(fileName, opts, ctx) => {
|
||||||
const root = dirname(fileName);
|
const root = dirname(fileName);
|
||||||
const name = basename(fileName);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
projects: {
|
projects: {
|
||||||
[name]: {
|
[root]: {
|
||||||
root,
|
|
||||||
tags: opts.tagName ? [opts.tagName] : [],
|
tags: opts.tagName ? [opts.tagName] : [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -37,8 +37,9 @@ export const createNodes: CreateNodes<PluginOptions> = [
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
projects: {
|
projects: {
|
||||||
[name]: {
|
[root]: {
|
||||||
root,
|
root,
|
||||||
|
name,
|
||||||
targets: {
|
targets: {
|
||||||
build: {
|
build: {
|
||||||
executor: "nx:run-commands",
|
executor: "nx:run-commands",
|
||||||
|
|||||||
@ -40,7 +40,7 @@ describe('nx package.json workspaces plugin', () => {
|
|||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"projects": {
|
"projects": {
|
||||||
"root": {
|
".": {
|
||||||
"name": "root",
|
"name": "root",
|
||||||
"projectType": "library",
|
"projectType": "library",
|
||||||
"root": ".",
|
"root": ".",
|
||||||
@ -68,7 +68,7 @@ describe('nx package.json workspaces plugin', () => {
|
|||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"projects": {
|
"projects": {
|
||||||
"lib-a": {
|
"packages/lib-a": {
|
||||||
"name": "lib-a",
|
"name": "lib-a",
|
||||||
"projectType": "library",
|
"projectType": "library",
|
||||||
"root": "packages/lib-a",
|
"root": "packages/lib-a",
|
||||||
@ -96,7 +96,7 @@ describe('nx package.json workspaces plugin', () => {
|
|||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"projects": {
|
"projects": {
|
||||||
"lib-b": {
|
"packages/lib-b": {
|
||||||
"implicitDependencies": [
|
"implicitDependencies": [
|
||||||
"lib-a",
|
"lib-a",
|
||||||
],
|
],
|
||||||
|
|||||||
@ -30,13 +30,14 @@ export function getNxPackageJsonWorkspacesPlugin(root: string): NxPluginV2 {
|
|||||||
|
|
||||||
export function createNodeFromPackageJson(pkgJsonPath: string, root: string) {
|
export function createNodeFromPackageJson(pkgJsonPath: string, root: string) {
|
||||||
const json: PackageJson = readJsonFile(join(root, pkgJsonPath));
|
const json: PackageJson = readJsonFile(join(root, pkgJsonPath));
|
||||||
return {
|
const project = buildProjectConfigurationFromPackageJson(
|
||||||
projects: {
|
|
||||||
[json.name]: buildProjectConfigurationFromPackageJson(
|
|
||||||
json,
|
json,
|
||||||
pkgJsonPath,
|
pkgJsonPath,
|
||||||
readNxJson(root)
|
readNxJson(root)
|
||||||
),
|
);
|
||||||
|
return {
|
||||||
|
projects: {
|
||||||
|
[project.root]: project,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,30 +56,42 @@ function readAngularJson(angularCliWorkspaceRoot: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function toNewFormat(w: any): ProjectsConfigurations {
|
export function toNewFormat(w: any): ProjectsConfigurations {
|
||||||
Object.values(w.projects || {}).forEach((projectConfig: any) => {
|
if (!w.projects) {
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
for (const name in w.projects ?? {}) {
|
||||||
|
const projectConfig = w.projects[name];
|
||||||
if (projectConfig.architect) {
|
if (projectConfig.architect) {
|
||||||
renamePropertyWithStableKeys(projectConfig, 'architect', 'targets');
|
renamePropertyWithStableKeys(projectConfig, 'architect', 'targets');
|
||||||
}
|
}
|
||||||
if (projectConfig.schematics) {
|
if (projectConfig.schematics) {
|
||||||
renamePropertyWithStableKeys(projectConfig, 'schematics', 'generators');
|
renamePropertyWithStableKeys(projectConfig, 'schematics', 'generators');
|
||||||
}
|
}
|
||||||
|
if (!projectConfig.name) {
|
||||||
|
projectConfig.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
Object.values(projectConfig.targets || {}).forEach((target: any) => {
|
Object.values(projectConfig.targets || {}).forEach((target: any) => {
|
||||||
if (target.builder !== undefined) {
|
if (target.builder !== undefined) {
|
||||||
renamePropertyWithStableKeys(target, 'builder', 'executor');
|
renamePropertyWithStableKeys(target, 'builder', 'executor');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
if (w.schematics) {
|
if (w.schematics) {
|
||||||
renamePropertyWithStableKeys(w, 'schematics', 'generators');
|
renamePropertyWithStableKeys(w, 'schematics', 'generators');
|
||||||
}
|
}
|
||||||
if (w.version !== 2) {
|
if (w.version !== 2) {
|
||||||
w.version = 2;
|
w.version = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toOldFormat(w: any) {
|
export function toOldFormat(w: any) {
|
||||||
Object.values(w.projects || {}).forEach((projectConfig: any) => {
|
if (w.projects) {
|
||||||
|
for (const name in w.projects) {
|
||||||
|
const projectConfig = w.projects[name];
|
||||||
if (typeof projectConfig === 'string') {
|
if (typeof projectConfig === 'string') {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"'project.json' files are incompatible with version 1 workspace schemas."
|
"'project.json' files are incompatible with version 1 workspace schemas."
|
||||||
@ -97,7 +109,8 @@ export function toOldFormat(w: any) {
|
|||||||
renamePropertyWithStableKeys(target, 'executor', 'builder');
|
renamePropertyWithStableKeys(target, 'executor', 'builder');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (w.generators) {
|
if (w.generators) {
|
||||||
renamePropertyWithStableKeys(w, 'generators', 'schematics');
|
renamePropertyWithStableKeys(w, 'generators', 'schematics');
|
||||||
|
|||||||
@ -39,7 +39,7 @@ describe('nx project.json plugin', () => {
|
|||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"projects": {
|
"projects": {
|
||||||
"root": {
|
".": {
|
||||||
"name": "root",
|
"name": "root",
|
||||||
"root": ".",
|
"root": ".",
|
||||||
"targets": {
|
"targets": {
|
||||||
@ -53,7 +53,7 @@ describe('nx project.json plugin', () => {
|
|||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"projects": {
|
"projects": {
|
||||||
"lib-a": {
|
"packages/lib-a": {
|
||||||
"name": "lib-a",
|
"name": "lib-a",
|
||||||
"root": "packages/lib-a",
|
"root": "packages/lib-a",
|
||||||
"targets": {
|
"targets": {
|
||||||
|
|||||||
@ -9,13 +9,14 @@ export const CreateProjectJsonProjectsPlugin: NxPluginV2 = {
|
|||||||
name: 'nx-core-build-project-json-nodes',
|
name: 'nx-core-build-project-json-nodes',
|
||||||
createNodes: [
|
createNodes: [
|
||||||
'{project.json,**/project.json}',
|
'{project.json,**/project.json}',
|
||||||
(file, _, context) => {
|
(file, _, { workspaceRoot }) => {
|
||||||
const root = context.workspaceRoot;
|
const json = readJsonFile<ProjectConfiguration>(
|
||||||
const json = readJsonFile<ProjectConfiguration>(join(root, file));
|
join(workspaceRoot, file)
|
||||||
|
);
|
||||||
const project = buildProjectFromProjectJson(json, file);
|
const project = buildProjectFromProjectJson(json, file);
|
||||||
return {
|
return {
|
||||||
projects: {
|
projects: {
|
||||||
[project.name]: project,
|
[project.root]: project,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -114,11 +114,19 @@ export function buildProjectsConfigurationsFromProjectPathsAndPlugins(
|
|||||||
workspaceRoot: root,
|
workspaceRoot: root,
|
||||||
});
|
});
|
||||||
for (const node in projectNodes) {
|
for (const node in projectNodes) {
|
||||||
projectNodes[node].name ??= node;
|
mergeProjectConfigurationIntoRootMap(projectRootMap, {
|
||||||
mergeProjectConfigurationIntoRootMap(
|
// If root is specified in config, that will overwrite this.
|
||||||
projectRootMap,
|
// Specifying it here though allows plugins to return something like
|
||||||
projectNodes[node]
|
// {
|
||||||
);
|
// projects: {
|
||||||
|
// [root]: { targets: buildTargetsFromFile(f) }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Otherwise, the root would have to be specified in the config as well
|
||||||
|
// which would be a bit redundant.
|
||||||
|
root: node,
|
||||||
|
...projectNodes[node],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Object.assign(externalNodes, pluginExternalNodes);
|
Object.assign(externalNodes, pluginExternalNodes);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,6 @@ import {
|
|||||||
} from '../adapter/angular-json';
|
} from '../adapter/angular-json';
|
||||||
import { getNxPackageJsonWorkspacesPlugin } from '../../plugins/package-json-workspaces';
|
import { getNxPackageJsonWorkspacesPlugin } from '../../plugins/package-json-workspaces';
|
||||||
import { CreateProjectJsonProjectsPlugin } from '../plugins/project-json/build-nodes/project-json';
|
import { CreateProjectJsonProjectsPlugin } from '../plugins/project-json/build-nodes/project-json';
|
||||||
import { FileMapCache } from '../project-graph/nx-deps-cache';
|
|
||||||
import { CreatePackageJsonProjectsNextToProjectJson } from '../plugins/project-json/build-nodes/package-json-next-to-project-json';
|
import { CreatePackageJsonProjectsNextToProjectJson } from '../plugins/project-json/build-nodes/package-json-next-to-project-json';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,7 +59,14 @@ export type CreateNodesFunction<T = unknown> = (
|
|||||||
options: T | undefined,
|
options: T | undefined,
|
||||||
context: CreateNodesContext
|
context: CreateNodesContext
|
||||||
) => {
|
) => {
|
||||||
projects?: Record<string, ProjectConfiguration>;
|
/**
|
||||||
|
* A map of project root -> project configuration
|
||||||
|
*/
|
||||||
|
projects?: Record<string, Optional<ProjectConfiguration, 'root'>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of external node name -> external node. External nodes do not have a root, so the key is their name.
|
||||||
|
*/
|
||||||
externalNodes?: Record<string, ProjectGraphExternalNode>;
|
externalNodes?: Record<string, ProjectGraphExternalNode>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -311,12 +317,12 @@ function ensurePluginIsV2(plugin: NxPlugin): NxPluginV2 {
|
|||||||
createNodes: [
|
createNodes: [
|
||||||
`*/**/${combineGlobPatterns(plugin.projectFilePatterns)}`,
|
`*/**/${combineGlobPatterns(plugin.projectFilePatterns)}`,
|
||||||
(configFilePath) => {
|
(configFilePath) => {
|
||||||
const name = toProjectName(configFilePath);
|
const root = dirname(configFilePath);
|
||||||
return {
|
return {
|
||||||
projects: {
|
projects: {
|
||||||
[name]: {
|
[root]: {
|
||||||
name,
|
name: toProjectName(configFilePath),
|
||||||
root: dirname(configFilePath),
|
root,
|
||||||
targets: plugin.registerProjectTargets?.(configFilePath),
|
targets: plugin.registerProjectTargets?.(configFilePath),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -535,3 +541,5 @@ function getDefaultPluginsSync(root: string): LoadedNxPlugin[] {
|
|||||||
plugin: p,
|
plugin: p,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
||||||
|
|||||||
@ -88,11 +88,10 @@ export const createNodes: CreateNodes<EslintPluginOptions> = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
options = normalizeOptions(options);
|
options = normalizeOptions(options);
|
||||||
const projectName = basename(projectRoot);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
projects: {
|
projects: {
|
||||||
[projectName]: {
|
[projectRoot]: {
|
||||||
root: projectRoot,
|
root: projectRoot,
|
||||||
projectType: 'library',
|
projectType: 'library',
|
||||||
targets: buildEslintTargets(
|
targets: buildEslintTargets(
|
||||||
|
|||||||
@ -31,11 +31,10 @@ export const createNodes: CreateNodes<<%= className %>PluginOptions> = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
options = normalizeOptions(options);
|
options = normalizeOptions(options);
|
||||||
const projectName = basename(projectRoot);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
projects: {
|
projects: {
|
||||||
[projectName]: {
|
[projectRoot]: {
|
||||||
root: projectRoot,
|
root: projectRoot,
|
||||||
projectType: 'library',
|
projectType: 'library',
|
||||||
targets: build<%= className %>Targets(
|
targets: build<%= className %>Targets(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user