枚举当前javascript项目中从源代码安装的所有包

枚举当前javascript项目中从源代码安装的所有包,javascript,node.js,package,Javascript,Node.js,Package,我试图找到一种从源代码递归枚举当前javascript项目中所有包的方法 我想做的是相当于npm列表或纱线列表,但来自源代码 我想避免的是: 直接解析/导入我自己的package.json,然后分析每个package.json的依赖关系 生成进程npm列表或纱线列表并解析其输出 我对这样一个库所做的每一次搜索都会被交互式解决方案的结果所污染,比如npm list或warn list,以下是我最后做的: 使用warn逻辑树和npm逻辑树包,并根据warn.lock或package lock.

我试图找到一种从源代码递归枚举当前javascript项目中所有包的方法

我想做的是相当于
npm列表
纱线列表
,但来自源代码

我想避免的是:

  • 直接解析/导入我自己的package.json,然后分析每个package.json的依赖关系
  • 生成进程
    npm列表
    纱线列表
    并解析其输出

我对这样一个库所做的每一次搜索都会被交互式解决方案的结果所污染,比如
npm list
warn list

,以下是我最后做的:

  • 使用
    warn逻辑树
    npm逻辑树
    包,并根据
    warn.lock
    package lock.json的存在使用正确的包
  • 解析结果树
const fs=require('fs'))
const path=require('路径')
const fsPromises=fs.promises
const lockfile=require(“@yarnpkg/lockfile”)
const-yarnlogical-tree=require('warn-logical-tree')
const npmllogicaltree=require('npm-logical-tree')
/**
*文件存在且可读时返回true
*@param{string}文件名
*/
const fileExists=async(文件名)=>{
试一试{
等待fspromissions.access(文件名,fs.constants.R\u确定)
返回真值
}捕获(错误){
返回错误
}
}
/**
*查找与作为参数传递的目录关联的项目目录(通过在从该目录到根目录的所有目录中搜索package.json)
*@param{string}dir
*/
const findProject=async(dir)=>{
设parsedDir=null
dir=wait.realpath(dir)
设为假
做{
parsedDir=path.parse(dir)
const packageFile=path.join(dir'package.json')
如果(等待文件存在(packageFile)){
返回目录
}
dir=parsedDir.dir
}而((!found)&&parsedDir&&parsedDir.base!='')
返回空
}
/**
*获取包树(通过搜索'warn.lock'或'package lock.json')
*@param{string}dir查找节点项目的目录
*/
常量getTree=async(dir)=>{
const project=wait find项目(dir)
const packageFilename=path.join(项目'package.json')
const yarnFilename=path.join(项目'warn.lock')
const npmFilename=path.join(项目“package lock.json”)
const packageContent=await fspromissions.readFile(packageFilename,“utf-8”)
如果(等待文件存在(yarnFilename)){
const yarnLockContent=await fspromissions.readFile(yarnFilename,'utf-8')
const package=JSON.parse(packageContent)
const yarnLock=lockfile.parse(yarnLockContent)
返回YarnLogicTree(包,yarnLock.object)
}else if(等待文件存在(npmFilename)){
const npmLockContent=await fspromissions.readFile(npmFilename,'utf-8')
const packageParsed=JSON.parse(packageContent)
const npmLock=JSON.parse(npmLockContent)
返回npmLogicalTree(packageParsed,npmLock)
}
返回空
}
/**
*从项目树中查找所有直接或间接依赖项
*@param{LogicalTree}树要分析的树
*@param{Object.}deps要更新的deps结构
*@返回{Object.}
*/
const searchTree=async(tree,deps={})=>{
常量{name,version,dependencies}=tree
常量id=`${name}@${version}`
如果(!deps[id]){
deps[id]={名称,版本}
for(让subTreeName of dependencies.keys()){
const subTree=dependencies.get(subTreeName)
等待搜索树(子树,deps)
}
}
退货部
}
然后,我像这样使用它:

const start=async()=>{
设dir='.'
const project=wait find项目(dir)
const tree=await getTree(项目)
const deps=等待搜索树(树)
for(让对象的id.keys(deps.sort()){
const{name,version}=deps[id]
console.log(`${name}(${version})`)
}
}
开始()