获取所有NPM依赖项的列表最低node.js引擎版本

vbkedwbf  于 2023-11-18  发布在  Node.js
关注(0)|答案(2)|浏览(143)

我们有一个NPM项目X,我想获得项目中所有依赖项的不同列表,以及它们需要的最低Node.js(引擎)版本。
我该怎么做?
动机当然是发现我们在开发和生产中需要运行的最低Nodejs版本。

npm ls | grep "engines"

字符串
类似的东西,除了上面的不会工作,希望有更强大的东西

6rqinv9w

6rqinv9w1#

$ npx ls-engines

字符串
或者使用下面的脚本。

$ node minimum-engines.mjs node_modules 
{"node":"18.12.0","npm":"1.0.0","iojs":"1.0.0"}


minimum-engines.mjs

#!/usr/bin/env node

// Prerequisite:
//   npm i --save-dev semver

// Usage:
//   node minimum-engines.mjs node_modules

import { compare, ltr, minVersion, parse, satisfies, validRange } from 'semver';
import { readFile, readdir } from 'node:fs/promises';
import { resolve } from 'node:path';

if (process.argv.length < 3) {
  console.error('You need to supply the path to the node_modules folder');
  process.exit(1);
}

const nodeModulesPath = process.argv[2];

const getPackageJsonFiles = async function* (path) {
  const dirEntries = await readdir(path, { withFileTypes: true });
  for (const entry of dirEntries) {
    const file = resolve(path, entry.name);
    if (entry.isDirectory()) {
      yield* getPackageJsonFiles(file);
    } else if (entry.name === 'package.json') {
      yield file;
    }
  }
};

const getEngines = async (path) => {
  const json = await readFile(path, 'utf8');
  try {
    const { engines = {} } = JSON.parse(json);
    return engines;
  } catch {
    return {};
  }
};

const mergeEngine = (engines, engine, value) => {
  const range = value.trim();
  if (range === '' || validRange(range) === null) {
    return;
  }
  const current = engines[engine] ?? '0.0.0';
  if (satisfies(current, range)) {
    return;
  }
  const currentVersion = parse(current);
  const newCurrent = minVersion(
    range
      .split('||')
      .map((r) => minVersion(r).raw)
      .filter((r) => ltr(currentVersion, r))
      .map((r) => (ltr(currentVersion, r) ? r : current))
      .join(' || '),
  ).raw;
  engines[engine] = compare(newCurrent, current) === -1 ? current : newCurrent;
};

const result = {};

try {
  for await (const file of getPackageJsonFiles(nodeModulesPath)) {
    const engines = await getEngines(file);
    for (const engine of Object.keys(engines)) {
      mergeEngine(result, engine, engines[engine]);
    }
  }
  console.log(JSON.stringify(result));
} catch (e) {
  console.error(e);
}

2mbi3lxu

2mbi3lxu2#

我可以这样做:

let npm = require('npm');

npm.load({}, function(err, npm) {

  if(err) throw err;

  npm.config.set('global', false); // => we don't want to consider global deps

  npm.commands.list([], true, function(err, pkgInfo) {

    let enginesList = Object.keys(pkgInfo.dependencies).map(function(k){
        return {
          dep: k,
          engines: pkgInfo.dependencies[k].engines || {}
        }
    });

    enginesList.forEach(function(val){
      console.log(val.dep + ' => ', val.engines);
    });

  });

});

字符串

相关问题