我可以在www.npmjs.com上找到软件包的对等依赖项吗

时间:2019-06-06 12:01:01

标签: npm

我有一个项目,该项目通过NPM安装了大约50个软件包。在忽略了几个月之后,我现在需要更新大多数软件包,从而导致一些不匹配的对等依赖项。为了找到正确的软件包版本组合,我想查看某个软件包的所有版本的对等依赖性。

在www.npmjs.com上的哪里可以找到软件包的对等依赖项?

一个软件包的页面显示了“依赖关系”和“依赖关系”,但是我相信这些是正常的依赖关系,而不是“对等依赖关系”。

1 个答案:

答案 0 :(得分:1)

www.npmjs.com网站未公开对等依赖项信息。但是,此元数据位于npm注册表端点https://registry.npmjs.org/上。

通过命令行,您可以使用npm view命令来访问它。例如:

npm view <pkg_name> peerDependencies

注意:,您需要将<pkg_name>部分替换为真实的软件包名称。

上述命令将列出peerDependencies以获得给定软件包的最新版本。


  

我想查看某个软件包的所有版本的同级依赖。

要实现这一目标,您可以:

  1. 运行以下命令以获取给定软件包的所有版本

    npm view babel-loader versions --json
    

    注意在这里,我们检查babel-loader,但这可以是任何有效的软件包名称

    这将打印:

    [
      "4.0.0",
      "4.1.0",
      "4.2.0",
      "4.3.0",
      "5.0.0",
      ...
    ]
    
  2. 然后运行以下命令以获取先前列出的每个版本的对等依赖性:

    npm view babel-loader@4.0.0 peerDependencies --json
                         ^^^^^^
    

    打印:

    {
      "babel-core": "^4.0.0",
      "webpack": "^1.4.5"
    }
    

    再次重复-与之前类似,但是更改后缀@<version>,即以下示例中的@4.1.0

    npm view babel-loader@4.1.0 peerDependencies --json
                         ^^^^^^
    

    此打印:

    {
      "babel-core": "^4.7.0",
      "webpack": "^1.4.5"
    }
    

    以此类推...


自动化任务:

您可能要考虑通过如下创建 node.js 脚本来自动化上述步骤。这利用了nodejs execSync()方法来封装必要的npm命令,但是如果您希望它异步运行,则可以将其更改为利用exec()方法:

script.js

const fs = require('fs');
const sh = require('child_process').execSync;

const PKG_NAME = 'babel-loader'; // <-- Change the package name.

const destFilePath = PKG_NAME.replace(/\//g, '_') + '-peer-deps.json';

const versions = JSON.parse(sh('npm view ' + PKG_NAME + ' versions --json').toString());

const data = versions.map(function(semver) {
  const pkgVersion = PKG_NAME + '@' + semver;
  console.log('> Fetching peerDependencies info for: ' + pkgVersion);

  const peerDeps = sh('npm view ' + pkgVersion +
      ' peerDependencies --json').toString().replace(/[\r\n]/, '');

  return {
    name: pkgVersion,
    peerDependencies: peerDeps ? JSON.parse(peerDeps) : null
  }
});

fs.writeFileSync(destFilePath, JSON.stringify(data, null, 2));

console.log('\nDone !');

然后运行以下命令以调用node.js脚本:

node ./path/to/script.js

注意::您需要根据需要重新定义./path/to/部分。

鉴于babel-loader中当前分配给PKG_NAME变量的script.js的值,您会看到类似以下内容的日志记录到控制台:

> Fetching peerDependencies info for: babel-loader@4.0.0
> Fetching peerDependencies info for: babel-loader@4.1.0
> Fetching peerDependencies info for: babel-loader@4.2.0
...

完成后,会将.json文件写入名为babel-loader-peer-deps.json的磁盘,其中包括以下内容:

babel-loader-peer-deps.json

[
  {
    "name": "babel-loader@4.0.0",
    "peerDependencies": {
      "babel-core": "^4.0.0",
      "webpack": "^1.4.5"
    }
  },
  {
    "name": "babel-loader@4.1.0",
    "peerDependencies": {
      "babel-core": "^4.7.0",
      "webpack": "^1.4.5"
    }
  },
  {
    "name": "babel-loader@4.2.0",
    "peerDependencies": {
      "babel-core": "^4.7.0",
      "webpack": "^1.4.5"
    }
  },
  ...
]

编辑:减少https GET请求的数量

如果您希望将https GET请求的数量减少到一个,那么我建议使用内置https.get()的nodejs从https://registry.npmjs.org/端点获取JSON数据。

下面的示例要点会更快。

get-peer-deps.js

const fs = require('fs');
const path = require('path');
const https = require('https');

const pkgName = process.argv[2];
const myName = path.basename(__filename);

// Check the package name has been provided
if (!pkgName) {
  console.log('\x1b[40;37m%s\x1b[0m \x1b[40;31m%s\x1b[0m', myName,
      'ERR!', 'Missing package name argument');
  process.exit(1);
}

const fileName = pkgName.replace(/\//g, '_') + '-peer-deps.json';
const destFilePath = path.join(path.dirname(__filename), fileName);
const endPoint = 'https://registry.npmjs.org/' + encodeURIComponent(pkgName);

// Request JSON from npm registry endpoint.
https.get(endPoint, function(resuest) {
  console.log('> Fetching peerDependencies info for: %s...', pkgName);
  var response = '';

  resuest.on('data', function(chunk) {
    response += chunk;
  });

  resuest.on('end', function() {
    processJsonResponse(response);
  });

}).on('error', function(err) {
  console.error(err);
});

/**
 * Processes the JSON response to extract the necessary metadata and saves
 * resultant JSOn to disk.
 * @param {String} data - The JSON response from the npm registry.
 */
function processJsonResponse(data) {
  const versions = JSON.parse(data).versions;
  const semvers = Object.keys(versions);

  const peerDepsInfo = semvers.map(function(semver) {
    const current = versions[semver];
    return {
      name: current.name + '@' + current.version,
      peerDependencies: current.peerDependencies || null
    };
  });

  fs.writeFile(destFilePath, JSON.stringify(peerDepsInfo, null, 2), function(err) {
    if(err) {
      return console.log(err);
    }
    console.log('> Done. Saved result to:\n  %s', destFilePath);
  });
}

用法:

然后通过命令行工具运行以下命令以调用get-peer-deps.js

node ./path/to/get-peer-deps.js babel-loader
                                ^^^^^^^^^^^^

注意::调用get-peer-deps.js时,必须提供程序包名称作为参数。在上面的示例中,我们传入babel-loader。可以用您喜欢的任何有效软件包名称代替。例如,在下一个示例中,我们传入@angular/forms

node ./path/to/get-peer-deps.js @angular/forms
                                ^^^^^^^^^^^^^^

生成的.json文件将按照前面所述的格式进行格式化,并将保存到get-peer-deps.js所在的目录中。