Options
All
  • Public
  • Public/Protected
  • All
Menu

Package yarnpkg-pnpify

Enumerations

Classes

Interfaces

Type aliases

Variables

Functions

Type aliases

AllIntegrations

AllIntegrations: object

Type declaration

BaseSdks

BaseSdks: Array<[SupportedSdk, GenerateBaseWrapper]>

DirectoryWatcherMap

DirectoryWatcherMap: Map<PortablePath, DirectoryWatcher>

GenerateBaseWrapper

GenerateBaseWrapper: function

Type declaration

GenerateDefaultWrapper

GenerateDefaultWrapper: function

Type declaration

GenerateIntegrationWrapper

GenerateIntegrationWrapper: function

Type declaration

HoistInfo

HoistInfo: object | object | object

HoistOptions

HoistOptions: object

Type declaration

  • Optional check?: undefined | false | true
  • Optional debugLevel?: undefined | number

HoisterResult

HoisterResult: object

Type declaration

HoisterTree

HoisterTree: object

Type declaration

HoisterWorkTree

HoisterWorkTree: object

Type declaration

Ident

Ident: string

IntegrationSdks

IntegrationSdks: Array<[null, GenerateDefaultWrapper | null] | [SupportedSdk, GenerateIntegrationWrapper | null]>

InternalHoistOptions

InternalHoistOptions: object

Type declaration

  • Optional check?: undefined | false | true
  • debugLevel: number

Locator

Locator: string

LocatorKey

LocatorKey: string

Package locator key for usage inside maps

MapKey

MapKey<S>: S extends Map<infer K, infer V> ? K : never

Type parameters

  • S

NodeModulesBaseNode

NodeModulesBaseNode: object

Type declaration

NodeModulesFSOptions

NodeModulesFSOptions: object

Type declaration

  • Optional pnpifyFs?: undefined | false | true
  • Optional realFs?: typeof fs

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'}

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 popularity. You will check in next steps whether most popular ident for the given package name can be hoisted first, and if not, then you check the lest popular 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 popularity 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 popularity 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 popularity. You will check in next steps whether most popular ident for the given package name can be hoisted first, and if not, then you check the lest popular 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 popularity 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 popularity 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.

PopularityMap

PopularityMap: Map<string, Set<Ident>>

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.

SupportedIntegration

SupportedIntegration: MapKey<typeof SUPPORTED_INTEGRATIONS>

SupportedSdk

SupportedSdk: "eslint" | "prettier" | "typescript-language-server" | "typescript" | "stylelint" | "svelte-language-server" | "flow-bin"

TemplateOptions

TemplateOptions: object

Type declaration

  • Optional setupEnv?: undefined | false | true
  • Optional usePnpify?: undefined | false | true
  • Optional wrapModule?: undefined | string

Variables

Const BASE_SDKS

BASE_SDKS: BaseSdks = [[`eslint`, generateEslintBaseWrapper],[`prettier`, generatePrettierBaseWrapper],[`typescript-language-server`, generateTypescriptLanguageServerBaseWrapper],[`typescript`, generateTypescriptBaseWrapper],[`stylelint`, generateStylelintBaseWrapper],[`svelte-language-server`, generateSvelteLanguageServerBaseWrapper],[`flow-bin`, generateFlowBinBaseWrapper],]

Const COC_VIM_SDKS

COC_VIM_SDKS: IntegrationSdks = [[`eslint`, generateEslintWrapper],[`typescript`, generateTypescriptWrapper],]

Const INTEGRATIONS_FILE

INTEGRATIONS_FILE: string & object = `integrations.yml` as Filename

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 NODE_MODULES

NODE_MODULES: "node_modules" = `node_modules`

Const OLD_SDK_FOLDER

OLD_SDK_FOLDER: string & object = `.vscode/pnpify` as PortablePath

Const SDK_FOLDER

SDK_FOLDER: string & object = `.yarn/sdks` as PortablePath

Const SUPPORTED_INTEGRATIONS

SUPPORTED_INTEGRATIONS: Map<"vim" | "vscode", ([null, null | function] | ["typescript" | "eslint" | "prettier" | "typescript-language-server" | "stylelint" | "svelte-language-server" | "flow-bin", null | function])[]> = new Map([[`vim`, COC_VIM_SDKS],[`vscode`, VSCODE_SDKS],] as const)

Const VSCODE_SDKS

VSCODE_SDKS: IntegrationSdks = [[null, generateDefaultWrapper],[`eslint`, generateEslintWrapper],[`prettier`, generatePrettierWrapper],[`typescript-language-server`, null],[`typescript`, generateTypescriptWrapper],[`stylelint`, generateStylelintWrapper],[`svelte-language-server`, generateSvelteLanguageServerWrapper],[`flow-bin`, generateFlowBinWrapper],]

Const WRITE_FLAGS_REGEX

WRITE_FLAGS_REGEX: RegExp = /[+wa]/

__non_webpack_require__

__non_webpack_require__: any

Const cli

cli: Cli<object> = new Cli({binaryLabel: `Yarn PnPify`,binaryName: `pnpify`,binaryVersion: require(`@yarnpkg/pnpify/package.json`).version,})

Const dynamicRequire

dynamicRequire: any = typeof __non_webpack_require__ !== `undefined`? __non_webpack_require__: require

Let fsPatched

fsPatched: boolean = false

Let pnp

pnp: PnpApi

Functions

Const TEMPLATE

  • TEMPLATE(relPnpApiPath: PortablePath, module: string, __namedParameters: object): string

Const addCocVimWorkspaceConfiguration

Const addSettingWorkspaceConfiguration

  • addSettingWorkspaceConfiguration(pnpApi: PnpApi, relativeFileName: PortablePath, patch: any): Promise<void>

Const addVSCodeWorkspaceConfiguration

Const benchmarkBuildTree

Const benchmarkRawHoisting

  • benchmarkRawHoisting(packageTree: HoisterTree): number

Const buildLocatorMap

Const buildNodeModulesTree

Const buildPackageTree

Const buildPopularityMap

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

Const dumpDepTree

Const dumpNodeModulesTree

Const generateDefaultWrapper

  • generateDefaultWrapper(pnpApi: PnpApi): Promise<void>

Const generateEslintBaseWrapper

Const generateEslintWrapper

Const generateEslintWrapper

Const generateFlowBinBaseWrapper

Const generateFlowBinWrapper

Const generatePrettierBaseWrapper

Const generatePrettierWrapper

Const generateSdk

  • generateSdk(pnpApi: PnpApi, __namedParameters: object, __namedParameters: object): Promise<void>

Const generateStylelintBaseWrapper

Const generateStylelintWrapper

Const generateSvelteLanguageServerBaseWrapper

Const generateSvelteLanguageServerWrapper

Const generateTypescriptBaseWrapper

Const generateTypescriptLanguageServerBaseWrapper

Const generateTypescriptWrapper

Const generateTypescriptWrapper

Const getArchivePath

Const getDisplayName

  • getDisplayName(name: string): string

Const getHoistIdentMap

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

    The values in the map are idents sorted by popularity from most popular to less popular. 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 popularity from most popular to less popular. 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 getHoistedDependencies

Const getIdentName

  • getIdentName(locator: Locator): string

Const getNodeHoistInfo

Const getSortedRegularDependencies

getTargetLocatorPath

Const getTreeHeight

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 void

isPortalLocator

  • isPortalLocator(locatorKey: LocatorKey): boolean

Const makeIdent

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

Const makeLocator

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

Const merge

  • merge(object: unknown, source: unknown): unknown

Const patchFs

  • patchFs(): void

Const populateNodeModulesTree

Const prettyPrintLocator

  • prettyPrintLocator(locator: Locator): string

Const resolveNodeModulesPath

Const selfCheck

Const shrinkTree

Const stringifyLocator

Const toTree

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

Const validateIntegrations

  • validateIntegrations(integrations: Set<string>): void

Generated using TypeDoc