当你写的node进程运行在遥远的某一个客户端时,如何帮助用户判断是否使用淘宝源呢?
伪代码
还是按照我的习惯,上一段伪代码,先大概了解下Vue-Cli是如何判断的:
shouldUseTaobao(包管理器command){
if(没有指定包管理器command){
设置command = 包管理器
}
if(已经调用过shouldUseTaobao) return 上一次调用的结果
const saved = 读取~/.vuerc文件中的useTaobaoRegistry配置
if(saved是boolean类型) return saved
《3》saveOptions(boolean) useTaobaoRegistry = boolean
《1》执行 command config get registry 获取 源
如果抛出错误,则 saveOptions(false) return
判断用户是否指定了源,如果是则 saveOptions(false) return
《2》判断当前源和淘宝源哪个更快,如果两个都抛出异常,则 saveOptions(false) return
如果更快的是淘宝源,询问用户是否使用淘宝源,获取用户答案并 设置 saveOptions(answer)
}
《1》通过指定的包管理器获取源
默认源有一下几种
- npm: 'https://registry.npmjs.org'
- yarn: 'https://registry.yarnpkg.com'
- taobao: 'https://registry.npm.taobao.org'
- pnpm: 'https://registry.npmjs.org'
let userCurrent
try {
userCurrent = (await execa(command, ['config', 'get', 'registry'])).stdout
} catch (registryError) {
try {
// Yarn 2 uses `npmRegistryServer` instead of `registry`
userCurrent = (await execa(command, ['config', 'get', 'npmRegistryServer'])).stdout
} catch (npmRegistryServerError) {
return save(false)
}
}
《2》判断当前源和淘宝源哪个更快
let faster
try {
faster = await Promise.race([
ping(defaultRegistry),
ping(registries.taobao)
])
} catch (e) {
return save(false)
}
这里主要使用了ES6的 Promise.race 方法,该方法会返回请求最快的返回结果。
async function ping (registry) {
await request.get(`${registry}/vue-cli-version-marker/latest`)
return registry
}
尝试访问源的某个目录下的文件,来进行网络请求。
《3》修改 ~/.vuerc
exports.saveOptions = toSave => {
const options = Object.assign(cloneDeep(exports.loadOptions()), toSave)
for (const key in options) {
if (!(key in exports.defaults)) {
delete options[key]
}
}
cachedOptions = options
try {
fs.writeFileSync(rcPath, JSON.stringify(options, null, 2))
return true
} catch (e) {
error(
`Error saving preferences: ` +
`make sure you have write access to ${rcPath}.\n` +
`(${e.message})`
)
}
}
这里首先进行了对象合并,然后清理掉不支持的配置字段,再尝试写入 ~/.vuerc,为防止用户写入权限不足,这里使用了try..catch进行异常捕获