Legacy wrapper providing comprehensive Nx devkit utilities for creating plugins, generators, and executors
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Tools for analyzing and manipulating the dependency graph between workspace projects and external packages. The project graph represents all projects, their configurations, and dependency relationships, enabling advanced workspace analysis and optimization.
Core functions for creating and accessing the project graph.
/**
* Create the project graph asynchronously
* @param opts - Options for graph creation
* @returns Promise resolving to the complete project graph
*/
function createProjectGraphAsync(opts?: {
exitOnError?: boolean;
resetDaemonClient?: boolean;
nxJson?: NxJsonConfiguration;
projectsConfigurations?: ProjectsConfigurations;
}): Promise<ProjectGraph>;
/**
* Read the cached project graph
* @returns Previously computed and cached project graph
*/
function readCachedProjectGraph(): ProjectGraph;
/**
* Extract project configurations from the project graph
* @param projectGraph - Project graph to extract from
* @returns Projects configurations object
*/
function readProjectsConfigurationFromProjectGraph(
projectGraph: ProjectGraph
): ProjectsConfigurations;
/**
* Create a project file map using the project graph
* @param projectGraph - Project graph containing file information
* @param allWorkspaceFiles - Optional array of all workspace files
* @returns Map of projects to their files
*/
function createProjectFileMapUsingProjectGraph(
projectGraph: ProjectGraph,
allWorkspaceFiles?: FileData[]
): ProjectFileMap;Usage Examples:
import {
createProjectGraphAsync,
readCachedProjectGraph,
readProjectsConfigurationFromProjectGraph
} from "@nrwl/devkit";
async function analyzeProjectGraph() {
// Create fresh project graph
const projectGraph = await createProjectGraphAsync();
// Or use cached version for better performance
const cachedGraph = readCachedProjectGraph();
// Extract project configurations
const projectsConfig = readProjectsConfigurationFromProjectGraph(projectGraph);
// Analyze dependencies
Object.entries(projectGraph.dependencies).forEach(([project, deps]) => {
console.log(`${project} depends on:`, deps.map(d => d.target));
});
// Find all library projects
const libraries = Object.values(projectGraph.nodes)
.filter(node => node.type === 'lib')
.map(node => node.name);
console.log('Library projects:', libraries);
}Core interfaces and types for the project graph structure.
/**
* Complete project graph containing all projects and dependencies
*/
interface ProjectGraph {
/** All nodes in the graph (projects and external dependencies) */
nodes: Record<string, ProjectGraphProjectNode | ProjectGraphExternalNode>;
/** Dependencies between nodes */
dependencies: Record<string, ProjectGraphDependency[]>;
/** Optional file map */
allWorkspaceFiles?: FileData[];
/** External nodes (npm packages, etc.) */
externalNodes?: Record<string, ProjectGraphExternalNode>;
}
/**
* Internal project node in the graph
*/
interface ProjectGraphProjectNode {
/** Project name */
name: string;
/** Node type */
type: 'app' | 'lib' | 'e2e';
/** Project configuration data */
data: ProjectConfiguration & {
/** File information */
files?: FileData[];
};
}
/**
* External dependency node (npm packages, etc.)
*/
interface ProjectGraphExternalNode {
/** Package name */
name: string;
/** Node type */
type: 'npm';
/** Package version */
version: string;
/** Additional data */
data: {
version: string;
packageName: string;
hash?: string;
};
}
/**
* Dependency relationship between nodes
*/
interface ProjectGraphDependency {
/** Source node name */
source: string;
/** Target node name */
target: string;
/** Type of dependency */
type: DependencyType;
}
/**
* Types of dependencies in the graph
*/
enum DependencyType {
/** Static import/require dependency */
static = 'static',
/** Dynamic import dependency */
dynamic = 'dynamic',
/** Implicit dependency (configured manually) */
implicit = 'implicit'
}Usage Examples:
import {
ProjectGraph,
ProjectGraphProjectNode,
DependencyType
} from "@nrwl/devkit";
function analyzeProjectDependencies(projectGraph: ProjectGraph) {
// Find all application projects
const apps = Object.values(projectGraph.nodes)
.filter((node): node is ProjectGraphProjectNode =>
node.type === 'app'
);
apps.forEach(app => {
console.log(`Application: ${app.name}`);
console.log(`Root: ${app.data.root}`);
// Find dependencies
const dependencies = projectGraph.dependencies[app.name] || [];
const staticDeps = dependencies
.filter(dep => dep.type === DependencyType.static)
.map(dep => dep.target);
console.log(`Static dependencies:`, staticDeps);
});
}Interfaces for mapping files to projects in the workspace.
/**
* Information about a file in the workspace
*/
interface FileData {
/** Full file path */
file: string;
/** File hash for change detection */
hash: string;
/** Dependencies found in the file */
deps?: string[];
}
/**
* Map of all files in the workspace
*/
interface FileMap {
/** Files organized by project */
projectFileMap: ProjectFileMap;
/** Files not associated with any project */
nonProjectFiles: FileData[];
}
/**
* Map of projects to their associated files
*/
interface ProjectFileMap {
[projectName: string]: FileData[];
}Usage Examples:
import { FileData, ProjectFileMap } from "@nrwl/devkit";
function analyzeProjectFiles(projectFileMap: ProjectFileMap) {
Object.entries(projectFileMap).forEach(([project, files]) => {
console.log(`Project ${project} has ${files.length} files:`);
// Count file types
const fileTypes = files.reduce((acc, file) => {
const ext = file.file.split('.').pop() || 'unknown';
acc[ext] = (acc[ext] || 0) + 1;
return acc;
}, {} as Record<string, number>);
console.log('File types:', fileTypes);
});
}Programmatic interface for building and modifying project graphs.
/**
* Builder class for constructing project graphs
*/
class ProjectGraphBuilder {
constructor(graph?: ProjectGraph);
/**
* Add a project node to the graph
* @param node - Project node to add
*/
addNode(node: ProjectGraphProjectNode): void;
/**
* Add an external node to the graph
* @param node - External node to add
*/
addExternalNode(node: ProjectGraphExternalNode): void;
/**
* Add a dependency between nodes
* @param dependency - Dependency to add
*/
addDependency(dependency: ProjectGraphDependency): void;
/**
* Add a static dependency
* @param source - Source project
* @param target - Target project
* @param sourceFile - File where dependency is found
*/
addStaticDependency(
source: string,
target: string,
sourceFile?: string
): void;
/**
* Add a dynamic dependency
* @param source - Source project
* @param target - Target project
* @param sourceFile - File where dependency is found
*/
addDynamicDependency(
source: string,
target: string,
sourceFile?: string
): void;
/**
* Add an implicit dependency
* @param source - Source project
* @param target - Target project
*/
addImplicitDependency(source: string, target: string): void;
/**
* Remove a dependency
* @param source - Source project
* @param target - Target project
*/
removeDependency(source: string, target: string): void;
/**
* Build the final project graph
* @returns Constructed project graph
*/
getUpdatedProjectGraph(): ProjectGraph;
}
/**
* Raw dependency representation
*/
interface RawProjectGraphDependency {
source: string;
target: string;
type: DependencyType;
sourceFile?: string;
}
/**
* Validate a dependency
* @param dependency - Dependency to validate
* @returns Whether dependency is valid
*/
function validateDependency(dependency: RawProjectGraphDependency): boolean;Usage Examples:
import {
ProjectGraphBuilder,
ProjectGraphProjectNode,
DependencyType
} from "@nrwl/devkit";
function buildCustomProjectGraph() {
const builder = new ProjectGraphBuilder();
// Add a library project
const libNode: ProjectGraphProjectNode = {
name: 'shared-utils',
type: 'lib',
data: {
root: 'libs/shared-utils',
projectType: 'library'
}
};
builder.addNode(libNode);
// Add an application project
const appNode: ProjectGraphProjectNode = {
name: 'web-app',
type: 'app',
data: {
root: 'apps/web-app',
projectType: 'application'
}
};
builder.addNode(appNode);
// Add dependency from app to library
builder.addStaticDependency(
'web-app',
'shared-utils',
'apps/web-app/src/main.ts'
);
// Build the graph
const projectGraph = builder.getUpdatedProjectGraph();
return projectGraph;
}Utility functions for manipulating and analyzing project graphs.
/**
* Reverse the dependencies in a project graph
* @param graph - Project graph to reverse
* @returns New graph with reversed dependencies
*/
function reverse(graph: ProjectGraph): ProjectGraph;Usage Examples:
import { reverse, ProjectGraph } from "@nrwl/devkit";
function analyzeReverseDependencies(projectGraph: ProjectGraph) {
// Reverse the graph to find which projects depend on each project
const reversedGraph = reverse(projectGraph);
// Now dependencies show which projects depend on each project
Object.entries(reversedGraph.dependencies).forEach(([project, dependents]) => {
if (dependents.length > 0) {
console.log(`${project} is used by:`, dependents.map(d => d.target));
}
});
}Install with Tessl CLI
npx tessl i tessl/npm-nrwl--devkit