npm入门(二)—package(包)的管理

前言

上一篇 npm入门(一)—了解基本组成与概念 简单介绍了一下npm的相关知识,这篇能够说是npm的核心知识。css

分类

关于pacakge,是有分为public pacakge(公共包)、private pacakge(私有包)。前面咱们也知道npm帐号也有两种,一直的免费用户,一个是付费用户。私有包是付费用户才能发布的。html

直观地,在npn website上看,package前面会有个标签标注该包是公有的仍是私有的vue

scopes

在此以前,咱们先了解这么一个概念——scopes(中文意思是做用域)。咱们在注册npm帐号和建立组织时,你将被授予一个与你的用户或组织名称匹配的范围,即你得到了一个适用范围(scope),这个范围是你的用户名或者建立的组织名。你能够将此范围用做相关包的命名空间。如你有一个package名叫mypackage,你的用户名为myusername,则你能够把这个package放到你的域里node

@myusername/mypackage
复制代码

这样有什么做用呢?jquery

  1. 避免与别人的包重名,发生冲突。
  2. 限制该包的访问权限。假设你是付费用户,想要建立一个私有包,那么能够在你的域里受权哪些用户才能访问

public package

默认地,若是咱们不对registry进行了任何设置,那么发布的包就是基于默认的registry(http://registry.npmjs.org)的,发布出来的包是公共的,任何人均可以访问使用。webpack

public package也有两种:git

  • unscoped package:这个就是普通的共用包了,没有指定范围
  • scoped package:这个是在划分了范围的包,默认是私有的,可是手动转化为共有的。

private package

私有包,只有付费用户才能建立。私有包,是指只有受权用户才能进行下载发布等管理,并且还能指定各类权限,例如只读只写之类的。github

私有包确定是指定了范围的(scoped),默认地,指定了范围的包都是私有包(固然后面能够手动更改)web

私有包能够划分两种vue-router

  • 用户范围的私有包:只能由你和你授予读或读/写访问权限的协做者访问。
  • org(组织)范围的私有包:只能被授予读或读/写访问权限的团队访问。

包类型的转换

上面咱们知道包的一些分类,那么,如何在须要时改变它们的类型呢?

公有转私有

在npm website上操做的方法就不说了,直接说敲命令的方式:

npm access restricted <pacakge-name>
复制代码

<pacakge-name>替换为真实包名

私有转公有

在npm website上操做的方法就不说了,直接说敲命令的方式:

npm access public <pacakge-name>
复制代码

<pacakge-name>替换为真实包名

须要注意的是,只有是付费用户才能转为私有。

私有包受权用户

私有包有时候为了协做,须要添加其余开发者进行一块儿管理,因此须要把私有包受权给某些用户。根据私有包类型

用户私有包

在npm website上操做的方法就不说了,直接说敲命令的方式:

npm owner add <user> <your-package-name>
复制代码

组织私有包

要授予npm用户对私有组织包的访问权,您必须有一个组织全部者将它们添加到您的组织中,而后将它们添加到有权访问私有包的团队中。具体步骤参考 这里


建立package

说了那么多,是时候应该知道,如何建立一个package了。

进入你想要建立package的文件夹根目录中,运行如下命令

npm init
复制代码

进行npm项目(package)的初始化,当运行这个命令后,会出现一个问卷,例如问你项目的名称,做者,描述等信息,你按照实际状况输入回应便可。填完问卷后,会在该目录下生成一个package.json文件,该文件里包含刚回应问卷的一些信息。

若是你懒得一个个回应,可使用默认的状况,运行

npm init --y 或者 npm init --yes
复制代码

这样会自动根据你当前目录的状况,生成一系列默认信息在package.json文件。

固然咱们也能够设置一些init时的固定指定信息,如

npm set init.author.name xxxx
npm set init.author.email xxxx
复制代码

这里就设定了init时固定做者信息是啥

若是你想建立的是指定域的包,那么运行

npm init --scope=@yourscopename
复制代码

yourscopename替换成你想要起的域的名称

package.json

上一篇咱们说过,package是由一个package.json文件描述组织起来的,因此这个文件相当重要。先大概看一下这个文件长哪样

{
  "name": "xxxx",
  "version": "1.0.0",
  "description": "xxx",
  "author": "myname <myname@xxx.com>",
  "private": true,
  "scripts": {
    "dev": "concurrently \"webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --env.sysName=eod\" \"node mock-server.js\""
  },
  "dependencies": {
    "vue-router": "3.0.1"
  },
  "devDependencies": {
    "autoprefixer": "7.1.2"
  },
  ...
}

复制代码

挑了些经常使用常见的内容展现出来。

属性 描述
name 必需。package的名称
version 必需。package的版本,遵循semantic versioning spec(语义版本控制规范)
description 推荐。用来描述你的package的一些信息,方便别人在npm website上查找你的pacakge
author 做者的相关信息。格式Your Name <email@example.com> (http://example.com)。包含了你的名称、邮箱和博客之类的网址,不必定要全写
private 你的package是私有的仍是公有的
scripts 一些npm脚本,造成npm指令,方便你进行某些工做,如构建
dependencies 这是你的package发布后,罗列的所须要依赖的一些别人的package,缺少了这些package,你的package也会不能如期正常工做
devDependencies 这里是罗列你在开发过程当中所依赖的一些package,为了方便你的开发所用的包,缺乏他们也不会影响到你的包发布后的正常使用,就放在这里了。

做用

  1. 从文件里能看出,该包的一些基础信息,以及所依赖的一些包
  2. 能看出所依赖的包的一些版本信息
  3. 使你的构建具备可重复性,所以更容易与其余开发人员共享

README.md

顾名思义,这个至关于用该package以前先看它的意思,即便用手册之类的意思。通常地,推荐package包含这个文件比较好,方便用户使用你的包。这个文件是使用markdown语法

此文件只有在发布包的新版本时才会在包页面上更新。

发布package

发布package以前,要好好检查你的文件里是否包含某些私人信息,敏感信息。请注意删除或者发布时忽略掉。使用.npmignore.gitignore文件来忽略掉,详情见

发布包命令:

npm publish
复制代码
  1. 若是要发布一个未指定域的公用包,直接运行上述命令便可。
  2. 若是要发布一个指定域的私有包,直接运行上述命令便可(默认指定域是私有包)。须要注意的是,publish以前要注意npm所在registry,如你要发布到公司的registry里,则发布前须要切换到公司registry下,才运行该命令,例如使用上一篇提到的npmrc工具
  3. 若是要发布一个指定域的私有包进行公有化,运行
npm publish --access public
复制代码

pacakge的版本控制规范

一个package必定要指定某个版本,而为了规范网络上你们各类各样的package,方便你们交流共享等,就制定了一个版本控制规范,你们在给本身package指定版本/更新版本的时候就好好考虑版本号了。

以当前版本为1.0.0为例子,遵循如下规范:

更新状况 位置 version
修复当前版本的一些bug 第三位 1.0.1
新增向后兼容的新特性 第二位 1.1.0
进行了破坏性地没法向后兼容的更改 第一位 2.0.0

在package.json里,咱们看到依赖项里,包的版本信息里会出现^~符号。这里要知道这些符号表明什么意思。例如

"eslint": "^3.19.0",
"css-loader": "~3.19.0",
复制代码

表明安装这个包的版本信息是浮动的,而不是指定死版本。

  • ^表明固定主版本号的,其他号浮动,如^1.3.0,高于等于1.3.0,1.x.x都符合,可是要低于2.0.0

  • ~表明固定次版本号的,修订号浮动,如~1.3.0,高于等于1.3.0,1.3.x都符合,可是要低于1.4.0

为package打tag

虽然package已经有版本号做为一些信息反馈给用户,可是语义化不够,不够直观明了,所以能够为package加上tag,即标签,为其备注一些信息,让用户更浅显易懂点。如运行

npm publish --tag beta
复制代码

在发布时,就为package打上了beta标签了。

默认地,发布时会自动继承这个包上次发布的标签的信息,如上次打了个beta标签,后面直接运行npm publish时,也会自动应用上beta标签。

须要注意的是,tag名尽可能不要使用数字或者v(不论大小写)开头的名字,由于tag的命名空间和版本号是一块儿的,会发生冲突。

若是想要指定版本进行打标签,运行

npm dist-tag add <packagename>@<version> tagname
复制代码

npm dist-tag add vue@1.2.0 beta
复制代码

发布后对于package的管理

更新版本

当你在维护一个包时,免不得了在调整以后须要对版本进行改变,以告知使用你的包的人,运行如下命令进行更新版本并进行发布

npm version <new-version>
npm publish
复制代码

弃用与取消弃用package

弃用

当你再也不想维护一个package,你须要告知那些依赖了你的包的人,让他们知道你的这个包你再也不进行维护了,这是出于你的责任心啦。运行

npm deprecate <package-name> 'message'
复制代码

这里的message就是你须要告知别人你的一些关于弃用的消息,这里必定要带上这个消息哦,否则就是另外一个含义了。

若是你只想弃用某个版本,而不是整个package,运行

npm deprecate <package-name>@<version> 'message'
复制代码

注意:弃用以后别人在npm的网站上会搜不出你的包来哦。访问你的包的网页也会有标识表名你的包给弃用了。别人在安装你的包时也会出现弃用的消息

取消弃用

若是往后你又回心转意了,想继续维护这个包,那么你就能够取消弃用了。运行

npm deprecate <package-name> ''
复制代码

你们留意到吗,这里跟弃用的命令很像,惟一的区别在于,以前的message替换成'',这样就能够取消弃用了

转移package

若是你不想维护你的包了,你能够选择弃用,也能够选择转移你的包,但愿它再找个主人吧。你能够把你的包转移给@npm,运行

npm owner add npm <package-name>
npm owner rm <user> <package-name>
复制代码

上面的两句命令就是,为你的package添加受权给npm,而后删除你对该包的拥有权。<user>为你的帐号名

因此,当转移了包以后,你就没了对它的使用权了,也不能更新它。

取消发布

发布了一个包以后,若是往后你不想让它再出现了,又不想仅是标志弃用,那么能够选择取消这个包的发布。固然这个行为可能会对别人产生很差的影响,例如别人依赖你的包,你无声无息地把这个包给取消掉了,叫别人情何以堪。

当你发布了一个公共package以后,72小时内后悔了,能够运行

npm unpublish <package-name> -f
复制代码

若是你仅想取消某个版本,运行

npm publish <package-name>@<version>
复制代码

若是是72小时后,那么须要联系 npm support了。若是你想取消的是一个组织包,非我的包,那么须要联系 enterprise@npmjs.com

安装package

咱们已经了解过了pacakge的基本状况,知道从他的建立到发布,到发布后的管理。都是从自身做为包的拥有者角度去处理包,那么如今是时候做为一名使用者角度,知道如何使用别人的包了。

使用别人的包,首先就得安装下载他们的包,安装分为两类:

  • local install (本地安装)
  • global install (全局安装)

本地安装

例如在你的某个项目中,须要使用到别人的一些包,那么须要在你这个项目下下载安装所需的包,下载下来的包只会在该项目中被引用。

换个思路去理解,就是像好久之前开发一个项目,须要引入某个类库,如jquery,那么就下载jquery.min.js,放在项目里某个文件夹里,而后在适当的位置引入它来进行使用,如在index.html里经过script标签进行引用。这样的话,其实这个jquery.min.js只会在这个项目里被引入使用,而不能在第二个项目B中被引用,由于它是被放在项目A里面了,这种就是本地安装

运行如下命令进行本地安装:

npm install 
复制代码

会依据项目中的package.json文件的依赖项以及声明的semver规则的最新版原本进行安装对应的包。若是该项目里没有node_modules文件夹,那么会新建一个,里面内容就是安装的package代码,若是有,那么直接在这个文件夹下新增pacakge

若是想要安装指定某个包(私有包请带上@域名/),运行

npm install <package-name>
复制代码

若是项目里没有package.json文件,那么会下载指定包的最新版本,若是存在,会下载package.json中声明的semver规则的最新版本。

若是想要指定依赖的类型(dependencies, devDependencies等)

npm install <package-name> --save
复制代码

加上--save是指该package是生产依赖项,存放在package.jsondependencies里,其实这是个默认的行为,即就算不加上--save,默认也是放在dependencies里。

若是想放在开发依赖里,运行

npm install <package-name> --save-dev
复制代码

若是想要安装指定版本或者tag的包,运行

npm install <package-name>@<version>
npm install <package-name> <tag>
复制代码

须要注意的是,若是是指定了某个tag的package进行安装,那么下载安装若是不带上tag,会自动默认依据上次的tag信息进行安装,例如,

npm install loadash beta
复制代码

下次安装loadash的时候,默认是下载beta标签的loadash

全局安装

全局安装,就是指安装一些共用的包,在你的本地计算机下的项目,都能共用这些包。例如npm了,每一个项目都须要使用npm,那么全局安装就行了,没必要要每一个项目都独立安装一遍。指令也很简单

npm install -g
npm install -g <package-name>
复制代码

其实跟本地安装介绍的意思是同样的,只不过区别就在于,多了个-g来标记是全局安装

更新package

随着时间的变化,可能你本地下载的包已是比较老的了,须要更新一下别人的包,那么在项目根目录下运行

npm update
复制代码

便可更新package.json里罗列的包。

若是想单独更新某个包(私有包请带上@域名/),运行

npm update <package-name>
复制代码

一样地,若是想更新全局的包,也是加个-g便可,如

npm update -g
复制代码

若是想看看当前项目里有哪些过期的包,能够运行

npm outdated
复制代码

会显示当前有哪些包过期了。固然这也能够用来检验是否更新成功了

若是想看看有哪些过期的全局包,运行

npm outdated -g --depth=0
复制代码

取消安装/删除package

若是某个包你不想要了,为了节省空间以及协做时避免别人下载一些没必要要的资源,能够删除某些不须要的包。运行(私有包请带上@域名/

npm uninstall <package-name>
复制代码

指定删除某个包

npm uninstall -g <package-name>
复制代码

指定删除某个全局包