Helpers to assist monorepo dependencies traversals
yarn add @semrel-extra/topo
import { topo } from '@semrel-extra/topo'
const graph = topo({
workspaces: ['packages/*'],
cwd: '/path/to/project/root'
})
{
queue: ['pkg-a', 'pkg-b', 'pkg-z', 'pkg-y', 'pkg-x'],
nodes: ['pkg-a', 'pkg-b', 'pkg-x', 'pkg-y', 'pkg-z'],
edges: [
['pkg-a', 'pkg-b'],
['pkg-z', 'pkg-y'],
['pkg-y', 'pkg-x'],
],
// packages entries map
packages: {
'pkg-a': {
manifest: {
name: 'pkg-a',
dependencies: {}
},
manifestPath: '/path/to/project/root/packages/a/package.json',
path: 'packages/a', // legacy
relPath: 'packages/a',
absPath: '/path/to/project/root/packages/a'
},
'pkg-b': {...},
...
}
}
Filter option is a function: gets IPackageEntry
as argument, returns boolean
const graph = topo({
workspaces: ['packages/*'],
cwd: '/path/to/project/root',
filter: ({manifest}) => !manifest.private // to omit private packages from graph
})
Applies filter to any kind of pkg dependencies to omit them from the graph.
const gpaph = topo({
workspaces: ['packages/*'],
cwd: '/path/to/project/root',
depFilter: ({version}) => version.startsWith('workspace:') // include only workspace deps
})
Injects extra pattern to the resolved workspaces
value from package.json
/ pnpm-workspace.yaml
const gpaph = topo({
workspacesExtra: ['!packages/foo'],
cwd: '/path/to/project/root'
})
Iterates up to the pkg deps graph.
import {topo, traverseDeps} from '@semrel-extra/topo'
const {packages} = topo({
workspaces: ['packages/*'],
cwd: '/path/to/project/root'
})
const pkg = packages['pkg-a']
const cb = async ({name, pkg}: IDepEntry) => {
await traverseDeps({pkg, packages, cb})
}
await traverseDeps({packages, pkg, cb})
Iterates over the queue of packages in the order of their dependencies.
import {topo, traverseQueue} from '@semrel-extra/topo'
const {queue, prev} = await topo({
workspaces: ['packages/*'],
cwd: '/path/to/project/root'
})
const cb = async (name: string) => {
// some async action
}
await traverseQueue({ queue, prev, cb })
Walks through the package dependencies and applies the cb()
for each.
const results: any[] = []
const manifest = {
name: 'foo',
version: '0.0.0',
dependencies: {
bar: '1.0.0'
},
devDependencies: {
baz: '2.0.0'
}
}
iterateDeps(manifest, ({ name, version, scope, deps }) => {
results.push({ name, version, scope, deps })
})