背景
npm repo loadsh 可以快速访问 loadsh的源码地址,那么当npm 执行这段脚本时候为什么能找到loadsh的github地址并打开引起了我的好奇。于是记录一次调试过程
步骤
查看npm 版本
npm -v
// 8.6.0
clone npm 源码
git clone --depth 1 -b v8.6.0 https://github.com/npm/cli.git
因可能会有node版本限制,我就只获取了8.6.0的代码
debugger
加入debugger脚本
"scripts": {
"debugger": "node ./bin/npm-cli.js repo loadsh",
...
}
npm-cli.js 加上断点
执行debugger
经过调试发现会进入lib/commands/repo.js 文件
const mani = await pacote.manifest(pkg, opts)
const r = mani.repository
const rurl = !r ? null
: typeof r === 'string' ? r
: typeof r === 'object' && typeof r.url === 'string' ? r.url
: null
if (!rurl) {
throw Object.assign(new Error('no repository'), {
pkgid: pkg,
})
}
const info = hostedFromMani(mani)
const url = info ?
info.browse(mani.repository.directory) : unknownHostedUrl(rurl)
if (!url) {
throw Object.assign(new Error('no repository: could not get url'), {
pkgid: pkg,
})
}
log.silly('docs', 'url', url)
await openUrl(this.npm, url, `${mani.name} repo available at the following URL`)
主要是通过 pacote 获取了package的信息(基本来自于包的package.json文件)
获取到 repository 再打开这个地址
同理,也可以调试npm docs loadsh
最终会进入
lib/commands/docs.js
async getDocs (pkg) {
const opts = { ...this.npm.flatOptions, fullMetadata: true }
const mani = await pacote.manifest(pkg, opts)
const url = this.getDocsUrl(mani)
log.silly('docs', 'url', url)
await openUrl(this.npm, url, `${mani.name} docs available at the following URL`)
}
getDocsUrl (mani) {
if (mani.homepage) {
return mani.homepage
}
const info = hostedFromMani(mani)
if (info) {
return info.docs()
}
return 'https://www.npmjs.com/package/' + mani.name
}
有homepage字段就进入homepage的地址 没有就跳 www.npmjs.com/package/xxx
总结
npm repo loadsh 会获取package.json中repository的地址并访问
npm docs loadsh 会获取package.json中homepage的地址并访问