MCPcopy
hub / github.com/vitejs/vite / isNodeWithinCircularImports

Function isNodeWithinCircularImports

packages/vite/src/node/server/hmr.ts:898–964  ·  view source on GitHub ↗

* Check importers recursively if it's an import loop. An accepted module within * an import loop cannot recover its execution order and should be reloaded. * * @param node The node that accepts HMR and is a boundary * @param nodeChain The chain of nodes/imports that lead to the node. * (The l

(
  node: EnvironmentModuleNode,
  nodeChain: EnvironmentModuleNode[],
  currentChain: EnvironmentModuleNode[] = [node],
  traversedModules = new Set<EnvironmentModuleNode>(),
)

Source from the content-addressed store, hash-verified

896 * @param traversedModules The set of modules that have traversed
897 */
898function isNodeWithinCircularImports(
899 node: EnvironmentModuleNode,
900 nodeChain: EnvironmentModuleNode[],
901 currentChain: EnvironmentModuleNode[] = [node],
902 traversedModules = new Set<EnvironmentModuleNode>(),
903): boolean {
904 // To help visualize how each parameter works, imagine this import graph:
905 //
906 // A -> B -> C -> ACCEPTED -> D -> E -> NODE
907 // ^--------------------------|
908 //
909 // ACCEPTED: the node that accepts HMR. the `node` parameter.
910 // NODE : the initial node that triggered this HMR.
911 //
912 // This function will return true in the above graph, which:
913 // `node` : ACCEPTED
914 // `nodeChain` : [NODE, E, D, ACCEPTED]
915 // `currentChain` : [ACCEPTED, C, B]
916 //
917 // It works by checking if any `node` importers are within `nodeChain`, which
918 // means there's an import loop with a HMR-accepted module in it.
919
920 if (traversedModules.has(node)) {
921 return false
922 }
923 traversedModules.add(node)
924
925 for (const importer of node.importers) {
926 // Node may import itself which is safe
927 if (importer === node) continue
928
929 // Check circular imports
930 const importerIndex = nodeChain.indexOf(importer)
931 if (importerIndex > -1) {
932 // Log extra debug information so users can fix and remove the circular imports
933 if (debugHmr) {
934 // Following explanation above:
935 // `importer` : E
936 // `currentChain` reversed : [B, C, ACCEPTED]
937 // `nodeChain` sliced & reversed : [D, E]
938 // Combined : [E, B, C, ACCEPTED, D, E]
939 const importChain = [
940 importer,
941 ...[...currentChain].reverse(),
942 ...nodeChain.slice(importerIndex, -1).reverse(),
943 ]
944 debugHmr(
945 colors.yellow(`circular imports detected: `) +
946 importChain.map((m) => colors.dim(m.url)).join(' -> '),
947 )
948 }
949 return true
950 }
951
952 // Continue recursively
953 if (!currentChain.includes(importer)) {
954 const result = isNodeWithinCircularImports(
955 importer,

Callers 1

propagateUpdateFunction · 0.85

Calls 2

hasMethod · 0.80
addMethod · 0.80

Tested by

no test coverage detected