1.npm是Node官方提供的包管理工具,他已经成了Node包的标准发布平台,用于Node包的发布、传播、依赖控制。npm提供了命令行工具,使你可以方便地下载、安装、升级、删除包,也可以让你作为开发者发布并维护包。随着大前端技术React,webpack,Vue等的发展,它的定义变成了广义的包管理器,可以实现JavaScript,webpack,Vue,JQuery,Gulp等包或者模块管理,是目前开源里最大生态最健全的包管理器
npm是随同Node一起安装的包管理工具,能解决Node.js在模块管理上的很多问题,常见的场景有以下几种:
1.允许用户从npm服务器下载别人编写的第三方包到本地使用。
2.允许用户从npm服务器下载并安装别人编写的命令行程序到本地使用。
3.允许用户将自己编写的包或命令行程序上传到npm服务器供别人使用。
我们只要一行命令,就能安装别人写好的模块 。
安装
安装NPM
由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了。
"npm -v" ---查看NPM版本
npm install npm@latest -g.
npm install npm@next -g.
安装指定版本:npm install npm@4.0.1 -g
NPM版本介绍
NPM v2:典型的树形依赖,层次深依赖重叠,安装时间长(node V5以下)
NPM v3:扁平化依赖,将依赖移到了顶层,下载速度快不少,当依赖多个版本时采用NPM v2的方式
npm必须首先遍历所有的项目依赖关系,然后再决定如何生成扁平的node_modules目录结构。npm必须为所有使用到的模块构建一个完整的依赖关系树,这是一个耗时的操作,是npm安装速度慢的一个很重要的原因
图------------------
NPM v5:自动记录依赖书,下载使用强校验,重写缓存系统,代表性的改动:新增了package-json.json用于记录和锁定依赖信息,与Yarn类似
将开发者从繁琐的包管理工作(版本、依赖等)中解放出来,更加专注于功能的开发。
NPM安装模块
$ npm install
npm install --选项
本地:
无选项:不保存在packjson里
--save-prod(--save或-P) : package.json, Dependencies
--save-dev:package.json,devDependencies( 为避免引用模块消失,多人协同开发,保证依赖模块出现在package.json里,--save是好习惯)
本地使用:var lodash = require('lodash'); 无需指定第三方包路径
全局
--global(-g)安装的模块是全局模块,如果是命令行模块,会直接连接到环境变量里
两者兼有:需要在两个地方安装它或使用 npm link
npm提供了一个有趣的命令npm link,它的功能是在本地包和全局包之间创建符号链接。
我们说过使用全局模式安装的包不能直接通过require使用。但通过npm link命令可以打破这一限制。
举个例子,我们已经通过npm install -g express安装了express,这时在工程的目录下运行命令:
npm link express ./node_modules/express ->/user/local/lib/node_modules/express
我们可以在node_modules子目录中发现一个指向安装到全局的包的符号链接。通过这种方法,我们就可以把全局包当做本地包来使用了。 除了将全局的包链接到本地以外,使用npm link命令还可以将本地的包链接到全局。
使用方法是在包目录(package.json所在目录)中运行npm link命令。如果我们要开发一个包,利用这种方法可以非常方便地在不同的工程间进行测试。
语义化的版本号:
语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。
补丁版本,解决了bug或者一些较小的更改,增加最后一位数字,如:1.0.1
小版本,增加了新特性,同时不会影响之前的版本,增加中间一位数据,如:1.1.0
大版本,大改版,无法兼容之前的版本,增加第一位数字,如:2.0.0
~会匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0
^会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0
*会安装最新版本的依赖包
使用方案:
指定特定的版本号,直接写1.2.3,前面什么前缀都没有,这样固然没问题,但是如果依赖包发布新版本修复了一些小bug,那么需要手动修改package.json文件;~和^则可以解决这个问题。但是需要注意^版本更新可能比较大,会造成项目代码错误,所以建议使用~来标记版本号,这样可以保证项目不会出现大的问题,也能保证包中的小bug可以得到修复。版本号写*,这意味着安装最新版本的依赖包,但缺点同上,可能会造成版本不兼容,慎用!
Working with package.json
npm init新建一个package.json:使用-f(代表force)、-y(代表yes),则跳过提问阶段
或者使用
npm set
npm set用来设置环境变量
$ npmsetinit-author-name'Your name'
$ npmsetinit-author-email'Your email'
$ npmsetinit-author-url'http://yourdomain.com'$ npmsetinit-license'MIT'
上面命令等于为npm init设置了默认值,以后执行npm init的时候,package.json的作者姓名、邮件、主页、许可证字段就会自动写入预设的值。这些信息会存放在用户主目录的~/.npmrc文件,使得用户不用每个项目都输入。
dependencies:--save
应用能够正常运行所依赖的包。这种 dependencies 是最常见的,用户在使用 npm install 安装你的包时会自动安装这些依赖。
devDependencies:--save-dev
开发应用时所依赖的工具包。通常是一些开发、测试、打包工具,例如 webpack、ESLint、Mocha。应用正常运行并不依赖于这些包,用户在使用 npm install 安装你的包时也不会安装这些依赖。
当项目正式上线的时候,开发依赖可以删除,生产依赖不可以删除。
npm不仅可以用于模块管理,还可以用于执行脚本。package.json文件有一个scripts字段,可以用于指定脚本命令,供npm直接调用
更新
npm outdated 查看有哪些过时的软件包
npm update
npm install 版本号
更新的原理:
NPM组成三部分中包括欧注册表: 是一个巨大的数据库,保存了每个包(package)的信息
https://registry.npmjs.org/react/v0.14.6
返回的 JSON 对象里面,有一个dist.tarball属性,是该版本压缩包的网址。
模块的安装过程
发出npm install命令
npm 向 registry 查询模块压缩包的网址
下载压缩包,存放在~/.npm目录
解压压缩包到当前项目的node_modules目录
卸载:
npm uninstall (-g)
对比
NRM:
nrm(npm registry manager )是npm的镜像源管理工具
npm install -g nrm
nrm ls
nrm test 测速:国内CNPM和taobao更有优势,尤其在阿里云上部署时
nrm use taobao
npm yarn pnpm cnpm
nrm add yourcompany http://registry.npm.yourcompany.com/
内网部署NPM源的好处:
1.安装速度快
2.私有模块,仅供企业内部使用,更安全
3.适合多团队开发
CNPM
cnpm跟npm用法完全一致,只是在执行命令时将npm改为cnpm。
npm安装插件是从国外服务器下载,受网络影响大,可能出现异常,如果npm的服务器在中国就好了,于是淘宝团队干了这事。来自官网:“这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。”
NPM最大的问题:::
即使不同的开发人员使用了相同的package.json文件,在他们自己的机器上也可能会安装同一个库的不同种版本,这样就会存在潜在的难以调试的错误和“在我的电脑上…”的情形。
大多数npm库都严重依赖于其他npm库,这会导致嵌套依赖关系,并增加无法匹配相应版本的几率。
虽然可以通过npm config set save-exact true命令关闭在版本号前面使用^的默认行为,但这个只会影响顶级依赖关系。由于每个依赖的库都有自己的package.json文件,而在它们自己的依赖关系前面可能会有^符号,所以无法通过package.json文件为嵌套依赖的内容提供保证。
为了解决这个问题,npm提供了shrinkwrap命令。此命令将生成一个npm-shrinkwrap.json文件,为所有库和所有嵌套依赖的库记录确切的版本。
Yarn
Yarn发布于2016年10月
Yarn一开始的主要目标是解决上一节中描述的由于语义版本控制而导致的npm安装的不确定性问题。虽然可以使用npm shrinkwrap来实现可预测的依赖关系树,但它并不是默认选项,而是取决于所有的开发人员知道并且启用这个选项。(npm5.0之前存在的问题)
Yarn采取了不同的做法。每个yarn安装都会生成一个类似于npm-shrinkwrap.json的yarn.lock文件,而且它是默认创建的。除了常规信息之外,yarn.lock文件还包含要安装的内容的校验和,以确保使用的库的版本相同。
yarn是经过重新设计的崭新的npm客户端,它能让开发人员并行处理所有必须的操作,并添加了一些其他改进。
运行速度得到了显著的提升,整个安装时间也变得更少
pnpm
可阅读pnpm的作者Zoltan Kochan发表的“为什么要用pnpm?”
https://blog.csdn.net/cuk0051/article/details/108341552
pnpm采用了一种巧妙的方法,利用硬链接和符号链接来避免复制所有本地缓存源文件,这是yarn的最大的性能弱点之一
使用链接并不容易,会带来一堆问题需要考虑。
pnpm继承了yarn的所有优点,包括离线模式和确定性安装
创建NPM包
包是在模块基础上更深一步的抽象,Node的包类似于C/C++的函数库或者Java、.Net的类库。它将某个独立的功能封装起来,用于发布、更新、依赖管理和版本控制。
Node根据CommonJS规范实现了包机制,开发了npm来解决包的发布和获取需求。
Node的包是一个目录,其中包含了一个JSON格式的包说明文件package.json。
严格符合CommonJS规范的包应该具备以下特征:
package.json必须在包的顶层目录下;
二进制文件应该在bin目录下;
JavaScript代码应该在lib目录下;
文档应该在doc目录下;
单元测试应该在test目录下。
Node对包的要求并没有这么严格,只要顶层目录下有package.json,并符合一些规范即可。当然为了提高兼容性,我们还是建议你在制作包的时候,严格遵守CommonJS规范。
我们也可以把文件夹封装为一个模块,即所谓的包。包通常是一些模块的集合,在模块的基础上提供了更高层的抽象,相当于提供了一些固定接口的函数库。通过定制package.json,我们可以创建更复杂,更完善,更符合规范的包用于发布。
Node在调用某个包时,会首先检查包中packgage.json文件的main字段,将其作为包的接口模块,如果package.json或main字段不存在,会尝试寻找 index.js 或 index.node 作为包的接口。
package.json是CommonJS规定的用来描述包的文件,完全符合规范的package.json文件应该含有以下字段: name: 包的名字,必须是唯一的,由小写英文字母、数字和下划线组成,不能包含空格。
description: 包的简要说明。
version: 符合语义化版本识别规范的版本字符串。
keywords: 关键字数组,通常用于搜索。
maintainers: 维护者数组,每个元素要包含name、email(可选)、web(可选)字段。
contributors: 贡献者数组,格式与maintainers相同。包的作者应该是贡献者数组的第一个元素。
bugs: 提交bug的地址,可以是网址或者电子邮件地址。
licenses: 许可证数组,每个元素要包含type(许可证的名称)和 url(链接到许可证文本的地址)字段。
repositories: 仓库托管地址数组,每个元素要包含type(仓库的类型,如 git)、URL(仓库的地址)和 path(相对于仓库的路径,可选)字段。
dependencies: 包的依赖,一个关联数组,由包名称和版本号组成。
包的发布
通过使用npm init可以根据交互式回答产生一个符合标准的package.json。创建一个index.js作为包的接口,一个简单的包就制作完成了。
在发布前,我们还需要获得一个账号用于今后维护自己的包,使用npm adduser根据提示完成账号的创建 完成后可以使用npm whoami检测是否已经取得了账号。
接下来,在package.json所在目录下运行npm publish,稍等片刻就可以完成发布了,
打开浏览器,访问NPM搜索就可以找到自己刚刚发布的包了。
现在我们可以在世界的任意一台计算机上使用npm install neveryumodule命令来安装它。
如果你的包将来有更新,只需要在package.json文件中修改version字段,然后重新使用npm publish命令就行了。
如果你对已发布的包不满意,可以使用npm unpublish命令来取消发布。
使用