The Nx Devkit provides utilities for creating custom generators, executors, and plugins to extend the Nx build system for different technologies and use cases.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive workspace and project configuration management for reading, creating, updating, and organizing Nx workspaces and projects.
Core functions for managing individual project configurations within an Nx workspace.
/**
* Add a new project configuration to the workspace
* @param tree - File system tree
* @param projectName - Name of the project
* @param projectConfiguration - Project configuration object
*/
function addProjectConfiguration(
tree: Tree,
projectName: string,
projectConfiguration: ProjectConfiguration
): void;
/**
* Read an existing project configuration
* @param tree - File system tree
* @param projectName - Name of the project
* @returns Project configuration object
*/
function readProjectConfiguration(
tree: Tree,
projectName: string
): ProjectConfiguration;
/**
* Update an existing project configuration
* @param tree - File system tree
* @param projectName - Name of the project
* @param projectConfiguration - Updated project configuration
*/
function updateProjectConfiguration(
tree: Tree,
projectName: string,
projectConfiguration: ProjectConfiguration
): void;
/**
* Remove a project configuration from the workspace
* @param tree - File system tree
* @param projectName - Name of the project to remove
*/
function removeProjectConfiguration(
tree: Tree,
projectName: string
): void;
/**
* Get all projects in the workspace
* @param tree - File system tree
* @returns Map of project names to configurations
*/
function getProjects(tree: Tree): Map<string, ProjectConfiguration>;Usage Examples:
import {
Tree,
addProjectConfiguration,
readProjectConfiguration,
updateProjectConfiguration,
getProjects
} from "@nx/devkit";
export default function myGenerator(tree: Tree, options: { name: string }) {
// Add a new library project
addProjectConfiguration(tree, options.name, {
root: `libs/${options.name}`,
projectType: "library",
sourceRoot: `libs/${options.name}/src`,
targets: {
build: {
executor: "@nx/js:tsc",
outputs: [`{workspaceRoot}/dist/libs/${options.name}`],
options: {
main: `libs/${options.name}/src/index.ts`,
tsConfig: `libs/${options.name}/tsconfig.lib.json`,
},
},
test: {
executor: "@nx/jest:jest",
outputs: [`{workspaceRoot}/coverage/libs/${options.name}`],
options: {
jestConfig: `libs/${options.name}/jest.config.ts`,
},
},
},
});
// Read existing project configuration
const existingProject = readProjectConfiguration(tree, "my-app");
// Update project to add a new target
updateProjectConfiguration(tree, "my-app", {
...existingProject,
targets: {
...existingProject.targets,
lint: {
executor: "@nx/linter:eslint",
options: {
lintFilePatterns: [`${existingProject.root}/**/*.ts`],
},
},
},
});
// Get all projects
const allProjects = getProjects(tree);
console.log(`Workspace has ${allProjects.size} projects`);
}Functions for managing the main Nx workspace configuration (nx.json).
/**
* Read the nx.json configuration
* @param tree - File system tree
* @returns Nx configuration object or null if not found
*/
function readNxJson(tree: Tree): NxJsonConfiguration | null;
/**
* Update the nx.json configuration
* @param tree - File system tree
* @param nxJsonConfiguration - Updated Nx configuration
*/
function updateNxJson(
tree: Tree,
nxJsonConfiguration: NxJsonConfiguration
): void;Usage Examples:
import { Tree, readNxJson, updateNxJson } from "@nx/devkit";
export default function myGenerator(tree: Tree) {
// Read current nx.json
const nxJson = readNxJson(tree);
if (nxJson) {
// Update nx.json to add a new named input
updateNxJson(tree, {
...nxJson,
namedInputs: {
...nxJson.namedInputs,
production: [
"default",
"!{projectRoot}/**/*.spec.ts",
"!{projectRoot}/**/*.test.ts",
],
},
targetDefaults: {
...nxJson.targetDefaults,
build: {
...nxJson.targetDefaults?.build,
inputs: ["production", "^production"],
},
},
});
}
}Functions for managing workspace directory structure and layout preferences.
/**
* Get the current workspace layout configuration
* @param tree - File system tree
* @returns Workspace layout configuration
*/
function getWorkspaceLayout(tree: Tree): {
appsDir: string;
libsDir: string;
standaloneAsDefault: boolean;
};
/**
* Extract layout directory information from a path
* @param directory - Directory path to analyze
* @returns Layout directory information
*/
function extractLayoutDirectory(directory?: string): {
layoutDirectory: string | null;
projectDirectory?: string;
};
/**
* Get workspace layout from configuration
* @returns Default workspace layout object
*/
const workspaceLayout: {
appsDir: string;
libsDir: string;
};Usage Examples:
import { Tree, getWorkspaceLayout, extractLayoutDirectory } from "@nx/devkit";
export default function myGenerator(tree: Tree, options: { directory?: string }) {
// Get workspace layout
const layout = getWorkspaceLayout(tree);
console.log(`Apps directory: ${layout.appsDir}`);
console.log(`Libs directory: ${layout.libsDir}`);
// Extract layout info from user input
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
options.directory
);
const finalDirectory = layoutDirectory
? `${layout.libsDir}/${layoutDirectory}/${projectDirectory}`
: `${layout.libsDir}/${projectDirectory}`;
}interface ProjectConfiguration {
/** Project name (optional, inferred from key in projects map) */
name?: string;
/** Root directory of the project relative to workspace root */
root: string;
/** Source root directory relative to workspace root */
sourceRoot?: string;
/** Type of project */
projectType?: ProjectType;
/** Available targets/tasks for this project */
targets?: Record<string, TargetConfiguration>;
/** Tags for categorizing and selecting projects */
tags?: string[];
/** Projects this project implicitly depends on */
implicitDependencies?: string[];
/** Default generator options */
generators?: Record<string, any>;
/** Named input definitions for targets */
namedInputs?: Record<string, (string | InputDefinition)[]>;
}
type ProjectType = "application" | "library";
interface TargetConfiguration<T = any> {
/** Executor to run for this target */
executor?: string;
/** Default options for the target */
options?: T;
/** Different configurations for the target */
configurations?: Record<string, Partial<T>>;
/** Default configuration to use */
defaultConfiguration?: string;
/** Other targets this target depends on */
dependsOn?: TargetDependencyConfig[];
/** Input files that affect this target */
inputs?: (InputDefinition | string)[];
/** Output files/directories produced by this target */
outputs?: string[];
}
interface TargetDependencyConfig {
/** Target name */
target: string;
/** Projects to run the target on */
projects?: "self" | "dependencies" | string[];
/** Configuration parameters */
params?: "forward" | Record<string, any>;
}interface NxJsonConfiguration<T = "*" | string[]> {
/** Nx configuration version */
version?: number;
/** Implicit dependencies configuration */
implicitDependencies?: ImplicitDependencyEntry<T>;
/** Affected command configuration */
affected?: NxAffectedConfig;
/** Workspace layout preferences */
workspaceLayout?: {
appsDir?: string;
libsDir?: string;
};
/** Task runner configuration */
tasksRunnerOptions?: {
[tasksRunnerName: string]: {
runner?: string;
options?: any;
};
};
/** Default target configurations */
targetDefaults?: TargetDefaults;
/** Named input definitions */
namedInputs?: { [inputName: string]: (string | InputDefinition)[] };
/** Generator defaults */
generators?: Record<string, Record<string, any>>;
/** CLI configuration */
cli?: {
packageManager?: PackageManager;
defaultCollection?: string;
};
/** Plugin configurations */
plugins?: PluginConfiguration[];
/** Default base branch for affected calculations */
defaultBase?: string;
/** Nx Cloud configuration */
nxCloudAccessToken?: string;
/** Remote cache configuration */
tasksRunnerOptions?: Record<string, any>;
}
interface NxAffectedConfig {
/** Default base branch */
defaultBase?: string;
}
type TargetDefaults = Record<string, Partial<TargetConfiguration>>;
interface ImplicitDependencyEntry<T = "*" | string[]> {
[key: string]: T | ImplicitJsonSubsetDependency<T>;
}
interface ImplicitJsonSubsetDependency<T = "*" | string[]> {
[key: string]: T;
}interface WorkspaceJsonConfiguration extends ProjectsConfigurations {
/** Workspace configuration version */
version: number;
}
interface ProjectsConfigurations {
/** Configuration version */
version: number;
/** Map of project names to configurations */
projects: Record<string, ProjectConfiguration>;
}
interface Workspace {
/** Workspace version */
version: number;
/** Map of project names to configurations */
projects: Record<string, ProjectConfiguration>;
/** Nx configuration */
cli?: {
defaultCollection?: string;
packageManager?: PackageManager;
};
}Install with Tessl CLI
npx tessl i tessl/npm-nx--devkit