持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
上篇文章讲解了检查node版本和检查root启动,接着下面按照这个图来实现准备阶段
检查用户主目录
检查用户主目录实现
const userHome = require('user-home')
const pathExists = require('path-exists').sync;
// 检查用户主目录
function checkUserHome(){
if(!userHome || !pathExists(userHome)){
throw new Error(colors.red('当前登录用户主目录不存在'))
}
}
其中使用到了两个第三方node库,分别是user-home和path-exists。
下面看下这两个node库
user-home
功能
可以跨操作系统获取用户主目录
源码
// user-home
'use strict';
module.exports = require('os-homedir')();
// os-homedir
'use strict';
var os = require('os');
function homedir() {
var env = process.env;
var home = env.HOME;
var user = env.LOGNAME || env.USER || env.LNAME || env.USERNAME;
if (process.platform === 'win32') {
return env.USERPROFILE || env.HOMEDRIVE + env.HOMEPATH || home || null;
}
if (process.platform === 'darwin') {
return home || (user ? '/Users/' + user : null);
}
if (process.platform === 'linux') {
return home || (process.getuid() === 0 ? '/root' : (user ? '/home/' + user : null));
}
return home || null;
}
module.exports = typeof os.homedir === 'function' ? os.homedir : homedir;
path-exists
功能
判断文件路径是否存在
源码
'use strict';
const fs = require('fs');
const {promisify} = require('util');
const pAccess = promisify(fs.access);
module.exports = async path => {
try {
await pAccess(path);
return true;
} catch (_) {
return false;
}
};
module.exports.sync = path => {
try {
fs.accessSync(path);
return true;
} catch (_) {
return false;
}
};
检查入参和debug模式
可能会使用debug模式,需要提前检查入参
实现
// 检查入惨
function checkInputArgs(){
const minimst = require('minimist')
args = minimst(process.argv.slice(2))
checArgs()
}
// 检查参数
function checArgs(){
if(args.debug){
process.env.LOG_LEVEL = 'verbose'
}else{
process.env.LOG_LEVEL = 'info'
}
log.level = process.env.LOG_LEVEL; // 后置修改log level
}
其中使用了minimist第三方node库
通过minimist来进行参数解析,当用户命令中有debug,则进入debug模式,否则是普通模式
minimist
进行参数解析
效果
可以进入debug模式
检查环境变量
将一些变量,如账号存到环境变量中,不写到代码里,可以实时读取
实现
// 检查环境变量
function checkEnv(){
const dotenv = require('dotenv');
const dotenvPath = path.resolve(userHome,'.env');
if(pathExists(dotenvPath)){
config = dotenv.config({
path: dotenvPath
});
}
log.verbose('环境变量', config)
}
其中使用dotenv第三方node库,具体可以看下npm
dotenv
从.env中加载环境变量
效果
加上默认环境变量
// 检查环境变量
function checkEnv(){
const dotenv = require('dotenv');
const dotenvPath = path.resolve(userHome,'.env');
if(pathExists(dotenvPath)){
dotenv.config({
path: dotenvPath
});
}
createDefaultConfig()
// 获取cliHomePathq
log.verbose('环境变量', process.env.CLI_HOME_PATH)
}
// 如果没有环境变量。默认配置
function createDefaultConfig(){
const cliConfig = {
home: userHome
}
if(process.env.CLI_HOME){
cliConfig['cliHome'] = path.join(userHome,process.env.CLI_HOME)
}else{
cliConfig['cliHome'] = path.join(userHome,DEFAULT_CLI_HOME)
}
// 将cliHome放入环境变量中,随时可以取
process.env.CLI_HOME_PATH = cliConfig.cliHome
}
效果
检查当前是否为最新版本
1.获取当前版本号和模块名
2.调用npm API,获取所有版本号
3.提取所有版本号,比对哪些版本号是大于当前版本号
4.获取最新版本号,提示用户更新到该版本
实现
// 检查是否要全局更新
async function checkGlobalUpdate(){
// 1.获取当前版本号和模块名
const currentVersion = pkg.version;
const npmName = pkg.name;
// 2.调用npm API,获取所有版本号
const {getNpmSemverVersion } = require('@rd-cli-dev/get-npm-info')
// 3.提取所有版本号,比对哪些版本号是大于当前版本号
const lastVersion = await getNpmSemverVersion(currentVersion, npmName)
if(lastVersion && semver.gt(lastVersion,currentVersion)){
// 4.获取最新版本号,提示用户更新到该版本
log.warn(colors.yellow(`请手动更新 ${npmName},当前版本:${currentVersion}, 最新版本:${lastVersion},
更新命令:npm install -g ${npmName}
`))
}
}
get-npm-info模块
'use strict';
const axios = require('axios');
const urlJoin = require('url-join');
const semver = require('semver')
function getNpmInfo(npmName, registry) {
if(!npmName) return null;
const registryUrl = registry || getDefaultRegistry()
const npmInfoUrl = urlJoin(registryUrl, npmName);
console.log(npmInfoUrl)
return axios.get(npmInfoUrl).then(res => {
if(res.status === 200){
return res.data;
}else{
return null;
}
}).catch(err => {
return Promise.reject(err)
})
}
// 获取默认的registry
function getDefaultRegistry(isOriginal = true){
return isOriginal ? 'https://registry.npmjs.org': 'https://registry.npmj.taobao.org'
}
// 获取 npm versions
async function getNpmVersions(npmName, registry){
const data = await getNpmInfo(npmName, registry)
if(data){
return Object.keys(data.versions)
}else{
return [];
}
}
// 获取所有满足条件的版本号
function getNpmSemverVersions(baseVersion, versions){
return versions.filter(version =>
semver.satisfies(version, `^${baseVersion}`)
).sort((a,b)=>{
return semver.gt(b,a)
})
}
// 获取最新版本
async function getNpmSemverVersion(baseVersion, npmName,registry){
const versions = await getNpmVersions(npmName, registry)
const newVersions = getNpmSemverVersions(baseVersion, versions)
console.log('newVersions', newVersions)
if(newVersions && newVersions.length > 0){
return newVersions[0]
}
}
module.exports = {
getNpmInfo,
getNpmVersions,
getNpmSemverVersion
};