Options
All
  • Public
  • Public/Protected
  • All
Menu

Package yarnpkg-nm

Type aliases

AliasedLocator

AliasedLocator: string & object

HoistInfo

HoistInfo: object | object | object

HoistOptions

HoistOptions: object

Type declaration

  • Optional check?: undefined | false | true

    Runs self-checks after hoisting is finished

  • Optional debugLevel?: DebugLevel

    Debug level

  • Optional hoistingLimits?: Map<Locator, Set<PackageName>>

    Hoist borders are defined by parent node locator and its dependency name. The dependency is considered a border, nothing can be hoisted past this dependency, but dependency can be hoisted

HoisterResult

HoisterResult: object

Type declaration

HoisterTree

HoisterTree: object

Type declaration

HoisterWorkTree

HoisterWorkTree: object

Type declaration

Ident

Ident: string

InternalHoistOptions

InternalHoistOptions: object

Type declaration

  • Optional check?: undefined | false | true
  • debugLevel: DebugLevel
  • fastLookupPossible: boolean
  • hoistingLimits: Map<Locator, Set<PackageName>>

Locator

Locator: string

LocatorKey

LocatorKey: string

Package locator key for usage inside maps

NodeModulesBaseNode

NodeModulesBaseNode: object

Type declaration

NodeModulesLocatorMap

NodeModulesLocatorMap: Map<LocatorKey, object>

NodeModulesPackageNode

NodeModulesPackageNode: object

Type declaration

NodeModulesTree

Node modules tree - a map of every folder within the node_modules, along with their directory listing and whether they are a symlink and their location.

Sample contents: /home/user/project/node_modules -> {dirList: ['foo', 'bar']} /home/user/project/node_modules/foo -> {target: '/home/user/project/.yarn/.cache/foo.zip/node_modules/foo', linkType: 'HARD'} /home/user/project/node_modules/bar -> {target: '/home/user/project/packages/bar', linkType: 'SOFT'}

Sample contents: /home/user/project/node_modules -> {dirList: ['foo', 'bar']} /home/user/project/node_modules/foo -> {target: '/home/user/project/.yarn/.cache/foo.zip/node_modules/foo', linkType: 'HARD'} /home/user/project/node_modules/bar -> {target: '/home/user/project/packages/bar', linkType: 'SOFT'}

NodeModulesTreeErrors

NodeModulesTreeErrors: Array<object>

PackageName

PackageName: string

High-level node_modules hoisting algorithm recipe

  1. Take input dependency graph and start traversing it, as you visit new node in the graph - clone it if there can be multiple paths to access the node from the graph root to the node, e.g. essentially represent the graph with a tree as you go, to make hoisting possible.
  2. You want to hoist every node possible to the top root node first, then to each of its children etc, so you need to keep track what is your current root node into which you are hoisting
  3. Traverse the dependency graph from the current root node and for each package name that can be potentially hoisted to the current root node build a list of idents in descending hoisting preference. You will check in next steps whether most preferred ident for the given package name can be hoisted first, and if not, then you check the less preferred ident, etc, until either some ident will be hoisted or you run out of idents to check (no need to convert the graph to the tree when you build this preference map).
  4. The children of the root node are already "hoisted", so you need to start from the dependencies of these children. You take some child and sort its dependencies so that regular dependencies without peer dependencies will come first and then those dependencies that peer depend on them. This is needed to make algorithm more efficient and hoist nodes which are easier to hoist first and then handle peer dependent nodes.
  5. You take this sorted list of dependencies and check if each of them can be hoisted to the current root node. To answer is the node can be hoisted you check your constraints - require promise and peer dependency promise. The possible answers can be: YES - the node is hoistable to the current root, NO - the node is not hoistable to the current root and DEPENDS - the node is hoistable to the root if nodes X, Y, Z are hoistable to the root. The case DEPENDS happens when all the require and other constraints are met, except peer dependency constraints. Note, that the nodes that are not package idents currently at the top of preference list are considered to have the answer NO right away, before doing any other constraint checks.
  6. When you have hoistable answer for each dependency of a node you then build a list of nodes that are NOT hoistable. These are the nodes that have answer NO and the nodes that DEPENDS on these nodes. All the other nodes are hoistable, those that have answer YES and those that have answer DEPENDS, because they are cyclically dependent on each another
  7. You hoist all the hoistable nodes to the current root and continue traversing the tree. Note, you need to track newly added nodes to the current root, because after you finished tree traversal you want to come back to these new nodes first thing and hoist everything from each of them to the current tree root.
  8. After you have finished traversing newly hoisted current root nodes it means you cannot hoist anything to the current tree root and you need to pick the next node as current tree root and run the algorithm again until you run out of candidates for current tree root.
  1. Take input dependency graph and start traversing it, as you visit new node in the graph - clone it if there can be multiple paths to access the node from the graph root to the node, e.g. essentially represent the graph with a tree as you go, to make hoisting possible.
  2. You want to hoist every node possible to the top root node first, then to each of its children etc, so you need to keep track what is your current root node into which you are hoisting
  3. Traverse the dependency graph from the current root node and for each package name that can be potentially hoisted to the current root node build a list of idents in descending hoisting preference. You will check in next steps whether most preferred ident for the given package name can be hoisted first, and if not, then you check the less preferred ident, etc, until either some ident will be hoisted or you run out of idents to check (no need to convert the graph to the tree when you build this preference map).
  4. The children of the root node are already "hoisted", so you need to start from the dependencies of these children. You take some child and sort its dependencies so that regular dependencies without peer dependencies will come first and then those dependencies that peer depend on them. This is needed to make algorithm more efficient and hoist nodes which are easier to hoist first and then handle peer dependent nodes.
  5. You take this sorted list of dependencies and check if each of them can be hoisted to the current root node. To answer is the node can be hoisted you check your constraints - require promise and peer dependency promise. The possible answers can be: YES - the node is hoistable to the current root, NO - the node is not hoistable to the current root and DEPENDS - the node is hoistable to the root if nodes X, Y, Z are hoistable to the root. The case DEPENDS happens when all the require and other constraints are met, except peer dependency constraints. Note, that the nodes that are not package idents currently at the top of preference list are considered to have the answer NO right away, before doing any other constraint checks.
  6. When you have hoistable answer for each dependency of a node you then build a list of nodes that are NOT hoistable. These are the nodes that have answer NO and the nodes that DEPENDS on these nodes. All the other nodes are hoistable, those that have answer YES and those that have answer DEPENDS, because they are cyclically dependent on each another
  7. You hoist all the hoistable nodes to the current root and continue traversing the tree. Note, you need to track newly added nodes to the current root, because after you finished tree traversal you want to come back to these new nodes first thing and hoist everything from each of them to the current tree root.
  8. After you have finished traversing newly hoisted current root nodes it means you cannot hoist anything to the current tree root and you need to pick the next node as current tree root and run the algorithm again until you run out of candidates for current tree root.

PreferenceMap

PreferenceMap: Map<string, object>

Mapping which packages depend on a given package alias + ident. It is used to determine hoisting weight, e.g. which one among the group of packages with the same name should be hoisted. The package having the biggest number of parents using this package will be hoisted.

ShadowedNodes

ShadowedNodes: Map<HoisterWorkTree, Set<PackageName>>

WorkspaceMap

WorkspaceMap: Map<LocatorKey, Set<PhysicalPackageLocator>>

WorkspaceTree

WorkspaceTree: object

Type declaration

Variables

Const MAX_NODES_TO_DUMP

MAX_NODES_TO_DUMP: 50000 = 50000

Const NODE_MODULES

NODE_MODULES: string & object = `node_modules` as Filename

node_modules path segment

Const WORKSPACE_NAME_SUFFIX

WORKSPACE_NAME_SUFFIX: "$wsroot$" = `$wsroot$`

The workspace name suffix used internally by this implementation and appeneded to the name of workspace package. It is needed to create and distinguuish special nodes for workspaces

Functions

Const areRealLocatorsEqual

Const benchmarkBuildTree

Const benchmarkRawHoisting

  • benchmarkRawHoisting(packageTree: HoisterTree): number

Const buildLocatorMap

Const buildNodeModulesTree

Const buildPackageTree

Const buildPreferenceMap

Const buildWorkspaceMap

Const cloneTree

Const decoupleGraphNode

  • This method clones the node and returns cloned node copy, if the node was not previously decoupled.

    The node is considered decoupled if there is no multiple parents to any node on the path from the dependency graph root up to this node. This means that there are no other nodes in dependency graph that somehow transitively use this node and hence node can be hoisted without side effects.

    The process of node decoupling is done by going from root node of the graph up to the node in concern and decoupling each node on this graph path.

    The node is considered decoupled if there is no multiple parents to any node on the path from the dependency graph root up to this node. This means that there are no other nodes in dependency graph that somehow transitively use this node and hence node can be hoisted without side effects.

    The process of node decoupling is done by going from root node of the graph up to the node in concern and decoupling each node on this graph path.

    Parameters

    Returns HoisterWorkTree

    decoupled node

Const dumpDepTree

  • Pretty-prints dependency tree in the yarn why-like format

    The function is used for troubleshooting purposes only.

    The function is used for troubleshooting purposes only.

    Parameters

    Returns string

    sorted node_modules tree

Const dumpDepTree

Const dumpNodeModulesTree

Const getAliasedLocator

Const getArchivePath

Const getHoistIdentMap

  • Builds a map of most preferred packages that might be hoisted to the root node.

    The values in the map are idents sorted by preference from most preferred to less preferred. If the root node has already some version of a package, the value array will contain only one element, since it is not possible for other versions of a package to be hoisted.

    The values in the map are idents sorted by preference from most preferred to less preferred. If the root node has already some version of a package, the value array will contain only one element, since it is not possible for other versions of a package to be hoisted.

    Parameters

    Returns Map<PackageName, Array<Ident>>

Const getIdentName

  • getIdentName(locator: Locator): string

Const getNodeHoistInfo

getRealPackageLocation

Const getSortedRegularDependencies

getTargetLocatorPath

Const getTreeHeight

Const getUsedDependencies

Const getZeroRoundUsedDependencies

Const hasUnhoistedDependencies

Const hoist

  • Hoists package tree.

    The root node of a tree must has id: '.'. This function does not mutate its arguments, it hoists and returns tree copy.

    The root node of a tree must has id: '.'. This function does not mutate its arguments, it hoists and returns tree copy.

    Parameters

    Returns HoisterResult

    hoisted tree copy

Const hoistGraph

Const hoistTo

  • Performs hoisting all the dependencies down the tree to the root node.

    The algorithm used here reduces dependency graph by deduplicating instances of the packages while keeping:

    1. Regular dependency promise: the package should require the exact version of the dependency that was declared in its package.json
    2. Peer dependency promise: the package and its direct parent package must use the same instance of the peer dependency

    The regular and peer dependency promises are kept while performing transform on tree branches of packages at a time: root package -> parent package 1 ... parent package n -> dependency We check wether we can hoist dependency to root package, this boils down basically to checking:

    1. Wether root package does not depend on other version of dependency
    2. Wether all the peer dependencies of a dependency had already been hoisted from all parent packages

    If many versions of the dependency can be hoisted to the root package we choose the most used dependency version in the project among them.

    This function mutates the tree.

    The algorithm used here reduces dependency graph by deduplicating instances of the packages while keeping:

    1. Regular dependency promise: the package should require the exact version of the dependency that was declared in its package.json
    2. Peer dependency promise: the package and its direct parent package must use the same instance of the peer dependency

    The regular and peer dependency promises are kept while performing transform on tree branches of packages at a time: root package -> parent package 1 ... parent package n -> dependency We check wether we can hoist dependency to root package, this boils down basically to checking:

    1. Wether root package does not depend on other version of dependency
    2. Wether all the peer dependencies of a dependency had already been hoisted from all parent packages

    If many versions of the dependency can be hoisted to the root package we choose the most used dependency version in the project among them.

    This function mutates the tree.

    Parameters

    Returns object

    • anotherRoundNeeded: boolean
    • isGraphChanged: boolean

Const isExternalSoftLink

Const makeIdent

  • makeIdent(name: string, reference: string): string

Const makeLocator

  • makeLocator(name: string, reference: string): string

Const populateNodeModulesTree

Const prettyPrintLocator

  • prettyPrintLocator(locator?: Locator): string

Const selfCheck

Const shrinkTree

Const stringifyLocator

Const toTree

  • toTree(obj: any, key?: string, nodes?: Map<any, any>): HoisterTree

Generated using TypeDoc