怎么样写一个能告诉你npm包名字是否被占用的工具
事情是这样的:
因为我经常会写一些npm包,但是有时候我写完一个包,
npm publish
的时候却被提示说包名字被占用了,要不就改名字,要不就加scope,很无奈。
npm 命令行可以通过npm view
的方式去得知一个包是否存在,但是无法批量得知,所以就想着写一个工具来批量选名:)本教程的相关代码已经全上传到github: 源代码
NPM方式
在写工具之前,我们先看看怎么通过 npm 提供的命令来得知包名是否被占用。
npm view
通过 npm view -h
我们可以得知其用法:
npm view [<@scope>/]<pkg>[@<version>] [<field>[.subfield]...]
aliases: v, info, show
通过以上命令来看看 unused-npm-names
包:
```npm view unused-npm-names
# 或者
npm info unused-npm-names
```
会输出:
{ name: 'unused-npm-names',
'dist-tags': { latest: '1.1.1' },
versions: [ '1.0.0', '1.0.1', '1.1.0', '1.1.1' ],
time:
{ created: '2018-09-07T02:53:05.277Z',
'1.0.0': '2018-09-07T02:53:05.439Z',
modified: '2018-09-07T03:44:06.363Z',
'1.0.1': '2018-09-07T03:07:46.542Z',
'1.1.0': '2018-09-07T03:35:40.221Z',
'1.1.1': '2018-09-07T03:44:03.534Z' },
maintainers: [ 'pjy <731401082@qq.com>' ],
description: 'Find unused npm names',
homepage: 'https://github.com/PengJiyuan/unused-npm-names#readme',
keywords: [ 'npm', 'names', 'unused', 'find' ],
repository:
{ type: 'git',
url: 'git+https://github.com/PengJiyuan/unused-npm-names.git' },
author: 'PengJiyuan',
bugs:
{ url: 'https://github.com/PengJiyuan/unused-npm-names/issues' },
license: 'MIT',
readmeFilename: 'README.md',
version: '1.1.1',
main: 'index.js',
bin: { unn: 'cli.js' },
scripts: { test: 'echo "Error: no test specified" && exit 1' },
dependencies: { axios: '^0.18.0', chalk: '^2.4.1', commander: '^2.17.1' },
gitHead: '818611db1c2baeb589cb3f639559ab6afc9f8e8f',
dist:
{ integrity: 'sha512-t9bCfY3qbeVY54QC6Cznn3YhM0jq6HX0fE0r5TMAq1IOzu+NQ/caA8tfj62pZtDuZKb9R29ne7UyPB+4zAAplw==',
shasum: '0b7c162f7656c0d74868bf567713150488f8c473',
tarball: 'https://registry.npmjs.org/unused-npm-names/-/unused-npm-names-1.1.1.tgz',
fileCount: 5,
unpackedSize: 4544,
'npm-signature': '-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbkfQDCRA9TVsSAnZWagAAwS4QAKFC1MnosxmJEws07U4O\ngfUPLP04ZLZqtW6nuB/29A72DE1+bh/TGsir83r/sYf1TAPSLOCRd3Nrky3A\n7+umUUOl5zGU5WyG86Fo2XOl5cYgXXWXU6LcZufG/cwM3Xi9MUfxnT7zCEWt\nQPAE8Oh9UhkWCnvFMBA6M6knqK9K08nQf0Ke55UoiuX+OqF8BUlNw8LqEwrI\nMTW8hpjKqsAdo3JhBu0ZkrfTRMq7cTawfjAg+qDs4SSTuWD9OJ9d/2y4OC/p\nX6+3I+Et+SqFJxjGDBounjF1GYYiH3dQPRN8UWL1p9Ypu6YsiZ7l8dp6RH15\nHFUv6lsCmZvhkKc1zO1pY67xUOA9VbLjhXtObwopFvCIehlv3cCw5FMwoa7x\nz+tou0J4II6n68cG6IfTt+9odi9abj7M2YxStW32Miu3efhpXiw2PpX3HWOW\njkY7IQryyxJbQIdKHJqJ59fADHLxpdmr6WADYWt8mKI+9TK9onpSgFgX4udw\ng7fXN3z/L6i7yY+0fvvX/b0jjVzVFNP5kFnUBSnWk/Hjm+h96QS+0xfRCRNv\n5CmVT2kbxYNAdFsFFoNCqHqE+uQoMrSwBw1SIJdybWjs84QrLOrDFjhKypev\nl6bzrgcyE0VWYY1A+zdyquL1cQ+xEJacsfN5NbicxTZhDU0enAtcxhKSe7bz\nJ9CP\r\n=t8xy\r\n-----END PGP SIGNATURE-----\r\n' },
directories: {} }
这样的输出太长了,我们可以只看 unused-npm-names
最近的版本号:
```npm view unused-npm-names version
```
会输出:
1.1.1
当然,如果这个包不存在的话,就会报 404
的错误,我们也就知道这个包名是否被占用了。
写个命令行工具
上面的方式是可以得到我们想要的结果,可是如果我想从一批名字中选一个可用的,就没有那么方便了,就要一个一个试了。
如果有一个工具可以像这样使用:
```unn react react-router react-dom react-pp react-fdasf
```
能一步鉴别所有的包,那就太方便了。
所以,我们一步一步来看一下应该怎么实现这个功能。
一、看npm如何做的
我们通过 npm view
可以查看一个包的信息,那么在走这个命令的时候,npm 肯定是发了一个请求去拿到的这个包的数据,那么我们怎么知道 npm 发的什么请求呢?
```# 加 --verbose 后缀来看详细的输出
npm view unused-npm-names --verbose
```
会输出:
...
npm http request GET https://registry.npmjs.org/unused-npm-names
...
npm info ok
我们在其中发现,npm 发了个 GET
请求,请求的url是 https://registry.npmjs.org/unused-npm-names
。
哦,那知道了,我们可以请求 https://registry.npmjs.org/${packageName}
来获取名为 packageName
的包信息。当然,在npm的官方仓库也能找到相关api的用法:package-metadata。
二、开始写工具
之前有一篇文章,讲了怎么写一个命令行工具,见这里:手把手教你写命令行工具。这篇文章就不从怎么从零开始构建一个命令行工具开始了,我们直接来代码:
文件目录大概是这样:
unused-npm-names
├── node_modules
├── package.json
├── cli.js (bin)
└── index.js (main)
package.json
:
{
"name": "unused-npm-names",
"version": "1.0.0",
"description": "Find unused npm names",
"main": "index.js",
"bin": {
"unn": "cli.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"license": "MIT",
"dependencies": {
"axios": "^0.18.0",
"chalk": "^2.4.1",
"commander": "^2.17.1"
}
}
通过 package.json
中设置 bin
字段,我们将命令的名字设置为 unn
,比较简短,方便实用。
我们把查询的主逻辑放到 index.js
中,把命令行逻辑放到 cli.js
中,这样的话我们既可以通过 cli 的方式去使用,也可以通过 require
的方式在 nodejs 脚本中使用。
// index.js
const axios = require('axios'); // 用于发送 http 请求
const chalk = require('chalk'); // 终端输出带颜色的文本
// search方法的参数是一个数组,存放着需要查询的包的名字
// 比如我们要查询 react和react-dom,那么search(['react', 'react-dom'])
function search(pkgs = []) {
if (!Array.isArray(pkgs)) {
throw 'Param should be an array.';
}
console.log();
pkgs.forEach((pkg) => {
axios.get(`https://registry.npmjs.org/${pkg}`)
.then((res) => {
// 如果请求成功,说明包存在,那么名字被占用。
console.log(`${chalk.cyan(pkg)}: ${chalk.red('Used ❌')}`);
})
.catch((err) => {
// 如果请求失败,并且是因为404报错,那么证明包不存在,名字可用。
if (err.stack && /Request failed with status code 404/.test(err.stack)) {
console.log(`${chalk.cyan(pkg)}: ${chalk.green('Unused ✅')}`);
} else {
// 处理未知情况
console.log(`${chalk.cyan(pkg)}: ${chalk.gray('Unknown
怎么样写一个能告诉你npm包名字是否被占用的工具的更多相关文章
- 怎么写一个带 bin 的 npm 包
只需要2步: 1. 在package.json 定义 一下 : { "name": "my-cli", ..., "bin": { &quo ...
- 使用go写一个检测tcpudp状态的包
使用go写一个检测tcpudp状态的包 http://www.2cto.com/os/201501/367596.html
- 在2018年如何优雅的开发一个typescript语言的npm包?
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由小明plus发表 很多时候,我们可能想要用 typescript 语言来创建一些模块,并提交到 npm 供别人使用, 那么在 2018 ...
- 通过npm写一个cli命令行工具
前言 如果你想写一个npm插件,如果你想通过命令行来简化自己的操作,如果你也是个懒惰的人,那么这篇文章值得一看. po主的上一篇文章介绍了定制自己的模版,但这样po主还是不满足啊,项目中我们频繁的需要 ...
- 如何发布一个npm包(基于vue)
前言:工作的时候总是使用别人的npm包,然而我有时心底会好奇自己如何发布一个npm包呢,什么时候自己的包能够被很多人喜欢并使用呢...今天我终于迈出了第一步. 前提:会使用 npm,有 vue 基础, ...
- 从0到1发布一个npm包
从0到1发布一个npm包 author: @TiffanysBear 最近在项目业务中有遇到一些问题,一些通用的方法或者封装的模块在PC.WAP甚至是APP中都需要使用,但是对于业务的PC.WAP.A ...
- 如何开发一个自己的npm包
目录 一.初始化npm包 二.新建自己的工具类 三.新建入口文件index.js 四.编写单元测试 五.登录仓库 六.发布包 七.安装使用 八.删除包 一.初始化npm包 npm init 运行输入包 ...
- 不会发布npm包?进来看看?
前言 npm(Node Package Manager),一个Node的包管理器,平时我们常用的公共模块(插件)或者叫做包大多都放在上面,所以接下来要封装的插件,我们就简单称它为npm包,本文从就从这 ...
- 自定义npm包——typeScript版本
前言 这篇文章是在我之前的文章 [自定义npm包的创建.发布.更新和撤销] 的基础上做的扩展,主要是针对如何创建以及发布一个typeScript语言的npm包. 大纲 1.创建关于typeScript ...
随机推荐
- 代码篇之AOP框架
AopFrameworkTest类 public class AopFrameworkTest { public static void main(String[] args) throws Exce ...
- 客户推广微信小程序的几种方法如下
一.店面二维码推广 1.店铺门口张贴 2.餐桌.柜台张贴 3.展架.海报宣传展示 二.结合促销活动,宣传单页上印小程序二维码线下派发 三.餐厅送餐时附带点餐小卡片,印小程序二维码 四.首次扫码立送积分 ...
- HTTP学习笔记(一)报文和连接管理
对TCP/IP协议簇有些了解的同学们应该都知道.TCP/IP协议通过精简ISO网络7层协议(事实上了解历史渊源的话,TCP/IP协议本来目的并非简化ISO的7层协议.仅仅是因为ISO协议簇制定速度慢于 ...
- 【C语言学习】封装和模块化思想
刚学习完C后,做的关于C的课程设计是在一个源文件里放了几百行代码,并且各个功能之间都是相互依赖的,这样就会非常麻烦. 由于当我要改动某个地方的时候,就会牵连着要改动喝多的地方.而在实际的程序设计中.这 ...
- [BLE--Link Layer]物理信道
简述 有线通信,是用电缆直接连接.然后分距离的长短.有些会须要载入波,信号也可能会经过不同的调制方式调制. 无线通信也是一样,仅仅是信号的传输是通过射频了,通过在某一频段.对无线信道进行调制,将数据发 ...
- Chrome 插件 CrxMouse 去除后门优化版
说明 CrxMouse 是一款挺不错的 Chrome 插件.仅仅是据说这个插件会在后台偷偷的上传用户的浏览数据,无论上传的内容是不是涉及隐私数据,总让人认为不放心,可是因为插件本身功能还是挺好用的,所 ...
- Log4net日志记录、详细配置(自己使用>)
log4net库是Apache log4j框架在Microsoft.NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具 1.首先添加对log4net.dll的引 ...
- HDU 3416
Marriage Match IV Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- Java提高篇
http://www.cnblogs.com/chenssy/p/3850230.html http://www.cnblogs.com/chenssy/p/3521565.html http://w ...
- HTML元素定位
一切皆为框 div.h1 或 p 元素常常被称为块级元素(block element).这意味着这些元素显示为一块内容,即"块框".与之相反,span 和 strong 等元素称为 ...