SoFunction
Updated on 2025-03-03

Detailed explanation of the simulation implementation of PNPM Monorepo dependency management function

text

PNPM MonorepoIs a way to manage dependencies in large projects, which allows multiple subprojects to share the samenode_modulesdirectory, thus reducing the problem of duplicate installation.

In this article, we will simulate the implementationPNPM MonorepoThe dependency management function facilitates us to understand project structure management ideas.

Read File

We need to read the root directoryFile, get the path to all subprojects. This can be achieved with the following code:

javascriptCopy code
const fs = require('fs');
const path = require('path');
const packageJson = (('./'));
const packages = ;

Create a soft link

Next, we need to create anode_modulesDirectory and create a soft link for each subproject to the root directorynode_modulesTable of contents. ifnode_modulesThe directory already exists, so it does not need to be created. This can be achieved with the following code:

javascriptCopy code
if (!('node_modules')) {
  ('node_modules');
}
// traverse all subprojects((pkg) => {
  // Get the file path and node_modules path of the subproject  const pkgPath = (pkg, '');
  const nodeModulesPath = (pkg, 'node_modules');
  // If the node_modules directory of the subproject does not exist, create a soft link to the node_modules directory in the root directory  if (!(nodeModulesPath)) {
    (('node_modules'), nodeModulesPath, 'dir');
  }
});

Install dependencies and create links

Next, we need to install the dependencies for each subproject and in the subproject'snode_modulesCreate a hard link in the directory to link the dependencies of the subproject with the dependencies in the root directory. This can be achieved with the following code:

// traverse all subprojects((pkg) => {
  // Dependencies for installing subprojects  // Read the file of the subproject and get the dependency list  const packageJson = ((pkgPath));
  const dependencies =  || {};
  // traverse the dependency list, install the dependencies, and create hard links in the node_modules directory of the subproject  for (const dep in dependencies) {
    const version = dependencies[dep];
    const depPath = (nodeModulesPath, dep);
    const depVersionPath = (depPath, version);
    const globalDepVersionPath = ('node_modules', dep, version);
    // Check whether the dependencies of this version have been installed    if (!(depVersionPath)) {
      // If not installed, use the spawnSync function to execute the npm install command to install the dependencies      (`Installing ${dep}@${version}...`);
      spawnSync('npm', ['install', `${dep}@${version}`], { cwd: pkg, stdio: 'inherit' });
      // Create a hard link to link the dependencies of the subproject with the dependencies in the root directory      if ((globalDepVersionPath)) {
        (globalDepVersionPath, depVersionPath);
      } else {
        // If the dependency does not exist in the root directory, create a soft link to the dependency in the root directory        (depPath);
        (globalDepVersionPath, depVersionPath, 'dir');
      }
    }
  }
});

Next, we can encapsulate the above code into a function for easy use in the project. CompletePNPM MonorepoThe code that simulates the dependency management function is as follows:

const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
function installDependencies() {
  const packageJson = (('./'));
  const packages = ;
  if (!('node_modules')) {
    ('node_modules');
  }
  ((pkg) => {
    const pkgPath = (pkg, '');
    const nodeModulesPath = (pkg, 'node_modules');
    if (!(nodeModulesPath)) {
      (('node_modules'), nodeModulesPath, 'dir');
    }
    const packageJson = ((pkgPath));
    const dependencies =  || {};
    for (const dep in dependencies) {
      const version = dependencies[dep];
      const depPath = (nodeModulesPath, dep);
      const depVersionPath = (depPath, version);
      const globalDepVersionPath = ('node_modules', dep, version);
      if (!(depVersionPath)) {
        (`Installing ${dep}@${version}...`);
        spawnSync('npm', ['install', `${dep}@${version}`], { cwd: pkg, stdio: 'inherit' });
        if ((globalDepVersionPath)) {
          (globalDepVersionPath, depVersionPath);
        } else {
          (depPath);
          (globalDepVersionPath, depVersionPath, 'dir');
        }
      }
    }
  });
  ('All dependencies installed!');
}
installDependencies();

Using this function is very simple, just run it in the root directory.

Summarize:

PNPM Monorepo is a way to manage dependencies in large projects, which allows multiple subprojects to share the samenode_modulesdirectory, thus reducing the problem of duplicate installation. This article simulates the code to implement the dependency management function of PNPM Monorepo.

We can read the root directoryFile, get the paths to all subprojects, create a node_modules directory, and create a soft link for each subproject to point to the root directorynode_modulesTable of contents. We then install dependencies for each subproject and create a hard link in the node_modules directory of the subproject to link the subproject's dependencies with the dependencies in the root directory. Finally, we can encapsulate the code into a function for easy use in the project.

The above is a detailed explanation of the simulation implementation of PNPM Monorepo dependency management function. For more information about PNPM Monorepo dependency management, please follow my other related articles!