or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

executors.mdgenerators.mdindex.mdjson-utilities.mdpackage-management.mdplugins.mdproject-configuration.mdproject-graph.mdstring-path-utilities.mdtesting-utilities.mdtree-filesystem.md

project-graph.mddocs/

0

# Project Graph & Dependencies

1

2

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.

3

4

## Capabilities

5

6

### Project Graph Functions

7

8

Core functions for creating and accessing the project graph.

9

10

```typescript { .api }

11

/**

12

* Create the project graph asynchronously

13

* @param opts - Options for graph creation

14

* @returns Promise resolving to the complete project graph

15

*/

16

function createProjectGraphAsync(opts?: {

17

exitOnError?: boolean;

18

resetDaemonClient?: boolean;

19

nxJson?: NxJsonConfiguration;

20

projectsConfigurations?: ProjectsConfigurations;

21

}): Promise<ProjectGraph>;

22

23

/**

24

* Read the cached project graph

25

* @returns Previously computed and cached project graph

26

*/

27

function readCachedProjectGraph(): ProjectGraph;

28

29

/**

30

* Extract project configurations from the project graph

31

* @param projectGraph - Project graph to extract from

32

* @returns Projects configurations object

33

*/

34

function readProjectsConfigurationFromProjectGraph(

35

projectGraph: ProjectGraph

36

): ProjectsConfigurations;

37

38

/**

39

* Create a project file map using the project graph

40

* @param projectGraph - Project graph containing file information

41

* @param allWorkspaceFiles - Optional array of all workspace files

42

* @returns Map of projects to their files

43

*/

44

function createProjectFileMapUsingProjectGraph(

45

projectGraph: ProjectGraph,

46

allWorkspaceFiles?: FileData[]

47

): ProjectFileMap;

48

```

49

50

**Usage Examples:**

51

52

```typescript

53

import {

54

createProjectGraphAsync,

55

readCachedProjectGraph,

56

readProjectsConfigurationFromProjectGraph

57

} from "@nrwl/devkit";

58

59

async function analyzeProjectGraph() {

60

// Create fresh project graph

61

const projectGraph = await createProjectGraphAsync();

62

63

// Or use cached version for better performance

64

const cachedGraph = readCachedProjectGraph();

65

66

// Extract project configurations

67

const projectsConfig = readProjectsConfigurationFromProjectGraph(projectGraph);

68

69

// Analyze dependencies

70

Object.entries(projectGraph.dependencies).forEach(([project, deps]) => {

71

console.log(`${project} depends on:`, deps.map(d => d.target));

72

});

73

74

// Find all library projects

75

const libraries = Object.values(projectGraph.nodes)

76

.filter(node => node.type === 'lib')

77

.map(node => node.name);

78

79

console.log('Library projects:', libraries);

80

}

81

```

82

83

### Project Graph Types

84

85

Core interfaces and types for the project graph structure.

86

87

```typescript { .api }

88

/**

89

* Complete project graph containing all projects and dependencies

90

*/

91

interface ProjectGraph {

92

/** All nodes in the graph (projects and external dependencies) */

93

nodes: Record<string, ProjectGraphProjectNode | ProjectGraphExternalNode>;

94

/** Dependencies between nodes */

95

dependencies: Record<string, ProjectGraphDependency[]>;

96

/** Optional file map */

97

allWorkspaceFiles?: FileData[];

98

/** External nodes (npm packages, etc.) */

99

externalNodes?: Record<string, ProjectGraphExternalNode>;

100

}

101

102

/**

103

* Internal project node in the graph

104

*/

105

interface ProjectGraphProjectNode {

106

/** Project name */

107

name: string;

108

/** Node type */

109

type: 'app' | 'lib' | 'e2e';

110

/** Project configuration data */

111

data: ProjectConfiguration & {

112

/** File information */

113

files?: FileData[];

114

};

115

}

116

117

/**

118

* External dependency node (npm packages, etc.)

119

*/

120

interface ProjectGraphExternalNode {

121

/** Package name */

122

name: string;

123

/** Node type */

124

type: 'npm';

125

/** Package version */

126

version: string;

127

/** Additional data */

128

data: {

129

version: string;

130

packageName: string;

131

hash?: string;

132

};

133

}

134

135

/**

136

* Dependency relationship between nodes

137

*/

138

interface ProjectGraphDependency {

139

/** Source node name */

140

source: string;

141

/** Target node name */

142

target: string;

143

/** Type of dependency */

144

type: DependencyType;

145

}

146

147

/**

148

* Types of dependencies in the graph

149

*/

150

enum DependencyType {

151

/** Static import/require dependency */

152

static = 'static',

153

/** Dynamic import dependency */

154

dynamic = 'dynamic',

155

/** Implicit dependency (configured manually) */

156

implicit = 'implicit'

157

}

158

```

159

160

**Usage Examples:**

161

162

```typescript

163

import {

164

ProjectGraph,

165

ProjectGraphProjectNode,

166

DependencyType

167

} from "@nrwl/devkit";

168

169

function analyzeProjectDependencies(projectGraph: ProjectGraph) {

170

// Find all application projects

171

const apps = Object.values(projectGraph.nodes)

172

.filter((node): node is ProjectGraphProjectNode =>

173

node.type === 'app'

174

);

175

176

apps.forEach(app => {

177

console.log(`Application: ${app.name}`);

178

console.log(`Root: ${app.data.root}`);

179

180

// Find dependencies

181

const dependencies = projectGraph.dependencies[app.name] || [];

182

const staticDeps = dependencies

183

.filter(dep => dep.type === DependencyType.static)

184

.map(dep => dep.target);

185

186

console.log(`Static dependencies:`, staticDeps);

187

});

188

}

189

```

190

191

### File System Mapping

192

193

Interfaces for mapping files to projects in the workspace.

194

195

```typescript { .api }

196

/**

197

* Information about a file in the workspace

198

*/

199

interface FileData {

200

/** Full file path */

201

file: string;

202

/** File hash for change detection */

203

hash: string;

204

/** Dependencies found in the file */

205

deps?: string[];

206

}

207

208

/**

209

* Map of all files in the workspace

210

*/

211

interface FileMap {

212

/** Files organized by project */

213

projectFileMap: ProjectFileMap;

214

/** Files not associated with any project */

215

nonProjectFiles: FileData[];

216

}

217

218

/**

219

* Map of projects to their associated files

220

*/

221

interface ProjectFileMap {

222

[projectName: string]: FileData[];

223

}

224

```

225

226

**Usage Examples:**

227

228

```typescript

229

import { FileData, ProjectFileMap } from "@nrwl/devkit";

230

231

function analyzeProjectFiles(projectFileMap: ProjectFileMap) {

232

Object.entries(projectFileMap).forEach(([project, files]) => {

233

console.log(`Project ${project} has ${files.length} files:`);

234

235

// Count file types

236

const fileTypes = files.reduce((acc, file) => {

237

const ext = file.file.split('.').pop() || 'unknown';

238

acc[ext] = (acc[ext] || 0) + 1;

239

return acc;

240

}, {} as Record<string, number>);

241

242

console.log('File types:', fileTypes);

243

});

244

}

245

```

246

247

### Project Graph Builder

248

249

Programmatic interface for building and modifying project graphs.

250

251

```typescript { .api }

252

/**

253

* Builder class for constructing project graphs

254

*/

255

class ProjectGraphBuilder {

256

constructor(graph?: ProjectGraph);

257

258

/**

259

* Add a project node to the graph

260

* @param node - Project node to add

261

*/

262

addNode(node: ProjectGraphProjectNode): void;

263

264

/**

265

* Add an external node to the graph

266

* @param node - External node to add

267

*/

268

addExternalNode(node: ProjectGraphExternalNode): void;

269

270

/**

271

* Add a dependency between nodes

272

* @param dependency - Dependency to add

273

*/

274

addDependency(dependency: ProjectGraphDependency): void;

275

276

/**

277

* Add a static dependency

278

* @param source - Source project

279

* @param target - Target project

280

* @param sourceFile - File where dependency is found

281

*/

282

addStaticDependency(

283

source: string,

284

target: string,

285

sourceFile?: string

286

): void;

287

288

/**

289

* Add a dynamic dependency

290

* @param source - Source project

291

* @param target - Target project

292

* @param sourceFile - File where dependency is found

293

*/

294

addDynamicDependency(

295

source: string,

296

target: string,

297

sourceFile?: string

298

): void;

299

300

/**

301

* Add an implicit dependency

302

* @param source - Source project

303

* @param target - Target project

304

*/

305

addImplicitDependency(source: string, target: string): void;

306

307

/**

308

* Remove a dependency

309

* @param source - Source project

310

* @param target - Target project

311

*/

312

removeDependency(source: string, target: string): void;

313

314

/**

315

* Build the final project graph

316

* @returns Constructed project graph

317

*/

318

getUpdatedProjectGraph(): ProjectGraph;

319

}

320

321

/**

322

* Raw dependency representation

323

*/

324

interface RawProjectGraphDependency {

325

source: string;

326

target: string;

327

type: DependencyType;

328

sourceFile?: string;

329

}

330

331

/**

332

* Validate a dependency

333

* @param dependency - Dependency to validate

334

* @returns Whether dependency is valid

335

*/

336

function validateDependency(dependency: RawProjectGraphDependency): boolean;

337

```

338

339

**Usage Examples:**

340

341

```typescript

342

import {

343

ProjectGraphBuilder,

344

ProjectGraphProjectNode,

345

DependencyType

346

} from "@nrwl/devkit";

347

348

function buildCustomProjectGraph() {

349

const builder = new ProjectGraphBuilder();

350

351

// Add a library project

352

const libNode: ProjectGraphProjectNode = {

353

name: 'shared-utils',

354

type: 'lib',

355

data: {

356

root: 'libs/shared-utils',

357

projectType: 'library'

358

}

359

};

360

361

builder.addNode(libNode);

362

363

// Add an application project

364

const appNode: ProjectGraphProjectNode = {

365

name: 'web-app',

366

type: 'app',

367

data: {

368

root: 'apps/web-app',

369

projectType: 'application'

370

}

371

};

372

373

builder.addNode(appNode);

374

375

// Add dependency from app to library

376

builder.addStaticDependency(

377

'web-app',

378

'shared-utils',

379

'apps/web-app/src/main.ts'

380

);

381

382

// Build the graph

383

const projectGraph = builder.getUpdatedProjectGraph();

384

385

return projectGraph;

386

}

387

```

388

389

### Graph Operations

390

391

Utility functions for manipulating and analyzing project graphs.

392

393

```typescript { .api }

394

/**

395

* Reverse the dependencies in a project graph

396

* @param graph - Project graph to reverse

397

* @returns New graph with reversed dependencies

398

*/

399

function reverse(graph: ProjectGraph): ProjectGraph;

400

```

401

402

**Usage Examples:**

403

404

```typescript

405

import { reverse, ProjectGraph } from "@nrwl/devkit";

406

407

function analyzeReverseDependencies(projectGraph: ProjectGraph) {

408

// Reverse the graph to find which projects depend on each project

409

const reversedGraph = reverse(projectGraph);

410

411

// Now dependencies show which projects depend on each project

412

Object.entries(reversedGraph.dependencies).forEach(([project, dependents]) => {

413

if (dependents.length > 0) {

414

console.log(`${project} is used by:`, dependents.map(d => d.target));

415

}

416

});

417

}

418

```