WaterMelon643

The npm Blog——新的包名规则

原文链接: blog.npmjs.org

新的包名规则

最近我们对于包的命名方式进行了一些修改,为的是更好的防御「误植」攻击,同时帮助包开发者们挑选出更加合适的包名。

可能你已经阅读过我们之前发布的文章 npm注册表上的误植攻击。我们对这一事件的回应是对于那些与已有包名类似的包采用内部工具进行识别。我们一直在亲自回顾着这些并且将在一些案例上采取措施。在这些包当中我们所注意到的一些趋势正引导我们去相信,我们可以鼓励人们更好地为包命名,从而能够满足注册用户以及包开发者的需求。具体一点来说,与现有包名仅在标点上不同的包就不可以再发布了。

包名可以包括标点符号、破折号和下划线 (., -, _)等。 这些标点可以使包名变得简单易懂!比如react-native 就比 reactnative 更加的一目了然。 但是,许多存在「误植」攻击的名字故意通过标点符号来进行监听。比如, 在这种事情发生之前,你可以将react-native的包命名为reactnative来发布,但是在我们新的命名规则之下,是不允许的。

下面就来详细的讲一下这种变化。

新的规则

如果你要发布一个新的包——也就是这个包在注册表中从来没有被发布过——我们把包名中的标点符号去掉并与现有的包进行比较。如果包名中不存在标点符号,我们是不允许创建这个包的。相反,我们建议在自己的作用域之下以此名字来发布包。当然,你还可以找到一个与现有包名完全不同的新名称,但是用自己的作用域是更快的一种方式。

这里有一些实例来说明差异。

由于react-native已经存在,这样的就不可以再发布了:

  • reactnative

  • react_native

  • react.native

类似的,由于jsonstream已经存在了,这样的就不能再发布了:

  • json-stream

  • json.stream

  • json_stream

  • json-stream

使用作用域!

如果因为你起的包名与现有的包名太相近而被阻止发布这个包,那么找到一个独一无二包名最简单方法就是使用你的作用域。你可以使用@+你的npm用户名加在包名前面将包划到你的npm账户作用域下。比如,我的npm用户名是ceejbot,所以我的作用域是@ceejbot

在你自己的作用域下发布一个包是免费的!你可以这样去做:

我已经知道json-stream与现有包名太接近了,所以我需要找到一个新的名字。首先,我需要编辑我的package.json文件,添加我的npm账户名来划分一个作用域,所以:

{
    "name": "json-stream"
}

修改为:

{
    "name": "@ceejbot/json-stream"
}


然后我要发布这个包。被划了作用域的包默认是私有的,所以要通过--access=public 让它变为公有的包:

> npm publish --access=public
+ @ceejbot/json-stream@1.0.0

每个人都可以向npm注册表中发布公共的作用域包,但是你想发布_私有_的包就要付费订阅了。要了解更多关于作用域包的信息,请查看我们的文档

关于包命名的历史

在npm注册表上,包名的历史是一个很小心的地添加条件限制的过程。在最早的时候,npm允许在包名上添加url安全字符,包括大写和小写字母。但是现在创建的包名中不能再有大写字母了,但是在npm注册表中那些包名中有大写字母的包依然存在也依然在使用,包名仅仅在大小写上的差异让我们第一次遇到了误植事件!

可能大多数人遇到的例子是jsonstreamJSONStreamjsonstream 是不同的包但是很难区分。如果你在一些大小写不敏感的系统中安装这些包就可能有问题,比如在大多数的OSX电脑文件系统中。

并不是所有的url安全字符都是合法的,你可以使用 validate-npm-package-name 包来检测包名中的字符是不是都是合法的。但是,你需要对注册表进行搜索来确定您想要的名称是否已经在使用。

好的包名可以帮助到所有人

我们希望新的包名规则可以帮助包开发者们挑选出合适的名字,并且能够帮助用户去避免意外获取到错误的包,如果你有任何的问题/想法/困惑,可以在support@npmjs.com发消息给我们,或者发twitter到@npm_support