欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-31 11:38:38
...

前言

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

分类

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

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

scopes

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

@myusername/mypackage
复制代码

这样有什么作用呢?

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

public package

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

public package也有两种:

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

private package

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

私有包肯定是指定了范围的(scoped),默认地,指定了范围的包都是私有包(当然后面可以手动更改)

私有包可以划分两种

  • 用户范围的私有包:只能由你和你授予读或读/写访问权限的协作者访问。
  • 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 [email protected]
复制代码

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

package.json

上一篇我们说过,package是由一个package.json文件描述组织起来的,所以这个文件至关重要。先大概看一下这个文件长哪样

{
  "name": "xxxx",
  "version": "1.0.0",
  "description": "xxx",
  "author": "myname <[email protected]>",
  "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 protected]> (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 [email protected] 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了。如果你想取消的是一个组织包,非个人包,那么需要联系 [email protected]

安装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>
复制代码

指定删除某个全局包

转载于:https://juejin.im/post/5c7c920de51d4560896aea5d