手搓一个node切换源小工具!

简介: 目前已经有一款工具了nrm 也是做切换源的 例如tabao源,腾讯源,下载依赖包的时候能加速,那有这么多的源nrm可以帮我们管理起来随时切换。

image.png


嗨嗨嗨,又到了写轮子环节了,为什么要写这个东西呢?


应为npm自带的源下载东西灰常慢


目前已经有一款工具了nrm 也是做切换源的 例如tabao源,腾讯源,下载依赖包的时候能加速,那有这么多的源nrm可以帮我们管理起来随时切换。


第一个朋友安装nrm很麻烦还需要用源码的方式安装


image.png


第二个朋友公司私服多,自己又懒得手动切换


image.png


于是我们想自己写一个小工具实现简易的切换npm源


思路1,调用命令 设置源


npm config set registry  源地址


思路2 使用查看命令获取源地址


npm config get registry


主要就是这两步操作


代码实现


commander


commander是一个nodejs的模块可以解析我们输入的命令,常用于各种脚手架如vue vite等,


例如 xxx -V查看版本  xxx use执行脚本  xxx -h查看帮助 等都可以使用 commander实现


image.png


inquirer


inquirer也是nodejs的一个模块,常用于命令交互,如vue的cli,vite等,react脚手架等


image.png


例如这种选项,还有输入框,多选等


registries.json


这个文件里面放一些初始的源,从nrm的github偷的ping是我自己加的


{
    "npm": {
        "home": "https://www.npmjs.org",
        "registry": "https://registry.npmjs.org/",
        "ping": "https://registry.npmjs.org"
    },
    "yarn": {
        "home": "https://yarnpkg.com",
        "registry": "https://registry.yarnpkg.com/",
        "ping": "https://registry.yarnpkg.com"
    },
    "tencent": {
        "home": "https://mirrors.cloud.tencent.com/npm/",
        "registry": "https://mirrors.cloud.tencent.com/npm/",
        "ping": "https://mirrors.cloud.tencent.com/npm"
    },
    "cnpm": {
        "home": "https://cnpmjs.org",
        "registry": "https://r.cnpmjs.org/",
        "ping": "https://r.cnpmjs.org"
    },
    "taobao": {
        "home": "https://npmmirror.com",
        "registry": "https://registry.npmmirror.com/",
        "ping": "https://registry.npmmirror.com"
    },
    "npmMirror": {
        "home": "https://skimdb.npmjs.com/",
        "registry": "https://skimdb.npmjs.com/registry/",
        "ping": "https://skimdb.npmjs.com/registry"
    }
}
#!/usr/bin/env node
const { program } = require('commander')
const PKG = require('../package.json') //引入package json
const registries = require('../registries.json'); //引入初始源
const inquirer = require('inquirer');
const { exec, execSync } = require('child_process') //子线程用于执行shell命令
const ping = require('node-http-ping') //ping网址的一个库
const fs = require('fs')
const chalk = require("chalk"); //console 变颜色的一个库
const path = require('path')
program.version(PKG.version) //设置版本默认命令 -V --version
//读取源地址方便设置*
const getOrigin = async () => {
    return await execSync('npm get registry', { encoding: "utf-8" })
}
//列出所有的源,如果当前有在使用前面加上*
program.command('ls').description('查看镜像').action(async () => {
    const res = await getOrigin()
    const keys = Object.keys(registries)
    const message = []
    //填充横线算法npm------  yarn------
    const max = Math.max(...keys.map(v => v.length)) + 3
    keys.forEach(k => {
        const newK = registries[k].registry == res.trim() ? ('* ' + k) : ('  ' + k)
        const Arr = new Array(...newK)
        Arr.length = max;
        const prefix = Array.from(Arr).map(v => v ? v : '-').join('')
        message.push(prefix + '  ' + registries[k].registry)
    })
    console.log(message.join('\n'))
})
//切换源
program.command('use').description('请选择镜像').action(() => {
    inquirer.prompt([
        {
            type: "list",
            name: "sel",
            message: "请选择镜像",
            choices: Object.keys(registries)
        }
    ]).then(result => {
        const reg = registries[result.sel].registry
        exec(`npm config set registry ${reg}`, null, (err, stdout, stderr) => {
            if (err) {
                console.error('切换错误', err)
            } else {
                console.log('切换成功')
            }
        })
    })
})
//获取当前源
program.command('current').description('查看当前源').action(async () => {
    const reg = await getOrigin()
    const v = Object.keys(registries).find(k => {
        if (registries[k].registry === reg.trim()) {
            return k;
        }
    })
    console.log(chalk.blue('当前源:', v))
})
//ping 源
program.command('ping').description('测试镜像地址速度').action(() => {
    inquirer.prompt([
        {
            type: "list",
            name: "sel",
            message: "请选择镜像",
            choices: Object.keys(registries)
        }
    ]).then(result => {
        const url = registries[result.sel].ping.trim()
        ping(url).then(time => console.log(chalk.blue(`响应时长: ${time}ms`)))
            .catch(() => console.log(chalk.red('GG')))
    })
})
//添加源 读写registries.json 文件实现
program.command('add').description('自定义镜像').action(() => {
    inquirer.prompt([
        {
            type: "input",
            name: "name",
            message: "请输入镜像名称",
            validate(answer) {
                const keys = Object.keys(registries)
                if (keys.includes(answer)) {
                    return `不能起名${answer}跟保留字冲突`
                }
                if (!answer) {
                    return '名称不能为空'
                }
                return true
            }
        },
        {
            type: "input",
            name: "url",
            message: "请输入镜像地址",
            validate(answer) {
                if (!answer) {
                    return `url不能为空`
                }
                return true
            }       
        }
    ]).then(result => {
        const del = (url) => {
            const arr = url.split('')
            //本来想用at 16 以下不支持
            return arr[arr.length - 1] == '/' ? (arr.pop() && arr.join('')) : arr.join('')
        }
        registries[result.name] = {
            home: result.url.trim(),
            registry: result.url.trim(),
            ping: del(result.url.trim()), //去掉末尾/ 不然无法ping
        }
        fs.writeFileSync(path.join(__dirname, '../registries.json'), JSON.stringify(registries, null, 4))
        console.log(chalk.blue('添加完成'))
    })
})
program.parse(process.argv)     


使用方式


npm i xmzs -g


安装完之后会有一个mmp 命令为什么不叫xmzs  别问问就是喜欢mmp


mmp ls


列出所有的源


image.png


mmp use


切换源 nrm是输入,我这儿是选择框方便一些


image.png


mmp current


查看当前源


image.png


mmp ping


测速


image.png


image.png


map add 


自定义源


image.png


mmp ls 查看


image.png

目录
相关文章
|
6月前
|
缓存 JavaScript 前端开发
猿如意中的【Node.js】工具详情介绍
猿如意中的【Node.js】工具详情介绍
|
1月前
|
存储 JavaScript 前端开发
Node.js 常用工具
10月更文挑战第6天
25 2
|
1月前
|
Web App开发 JavaScript 前端开发
Node.js:JavaScript世界的全能工具
Node.js:JavaScript世界的全能工具
|
2月前
|
存储 JavaScript 前端开发
Node 版本控制工具 NVM 的安装和使用(Windows)
本文介绍了NVM(Node Version Manager)的Windows版本——NVM for Windows的安装和使用方法,包括如何安装Node.js的特定版本、列出已安装版本、切换使用不同版本的Node.js,以及其他常用命令,以实现在Windows系统上对Node.js版本的便捷管理。
Node 版本控制工具 NVM 的安装和使用(Windows)
|
1月前
|
JavaScript 网络协议
Node.js 工具模块
10月更文挑战第7天
21 0
|
2月前
|
JavaScript Linux 开发者
一个用于管理多个 Node.js 版本的安装和切换开源工具
【9月更文挑战第14天】nvm(Node Version Manager)是一个开源工具,用于便捷地管理多个 Node.js 版本。其特点包括:版本安装便捷,支持 LTS 和最新版本;版本切换简单,不影响开发流程;多平台支持,包括 Windows、macOS 和 Linux;社区活跃,持续更新。通过 nvm,开发者可以轻松安装、切换和管理不同项目的 Node.js 版本,提高开发效率。
101 4
|
3月前
|
JavaScript 小程序 Java
【工具】用nvm管理nodejs版本切换,真香!
本文详细介绍了如何使用 nvm(node.js 版本管理工具)解决在不同项目间频繁切换 Node.js 版本的问题。通过实例展示了 A、B 两个项目分别依赖 v14.19.1 和 v16.15.0 版本时的解决方案,并提供了 nvm 的下载、安装及常用命令等实用信息,帮助读者轻松管理 Node.js 版本。文章还包括了卸载已安装的 Node.js、配置环境变量等步骤,确保切换顺畅无阻。
181 0
【工具】用nvm管理nodejs版本切换,真香!
|
3月前
|
JavaScript IDE 前端开发
前端开发工具配置 nodejs & git & IDE
前端开发工具配置 nodejs & git & IDE
|
5月前
|
存储 JavaScript 前端开发
Node.js 常用工具
Node.js 常用工具
32 1
|
4月前
|
JavaScript 数据安全/隐私保护
node.js 命令行的命令注册和配置工具(最新版) commander.js 实用教程(含自研脚手架的创建流程)
node.js 命令行的命令注册和配置工具(最新版) commander.js 实用教程(含自研脚手架的创建流程)
185 0
下一篇
无影云桌面