前言
npm
是node
包管理工具,类似于pip
之于python
;是前端工程化重要的组成部分,安装完node
后,npm
会自动安装好,也就是npm
与node
绑定使用,出场自带,所以npm
非常的重要
本文是学习的时候做的笔记,也有本人理解的部分
1.包的安装
安装源
因为npm
的服务器在国外,所以一般在国内安装包的时候,速度一般是比较慢或则失败
国内淘宝提供一个服务器进行下载,也就是我们经常说的淘宝源(淘宝镜像)
- 设置淘宝源
npm config set registry https://registry.npmmirror.com
- 查看当前的源
npm config get registry
- 淘宝镜像的原理 当执行命令安装某个包的时候,淘宝镜像会在自己的库中去查找,如果有对应的数据,那么直接返回安装包 如果没有对应的包安装库,那么直接从国外的原始的服务器去下载安装包,当然淘宝的服务器是经过处理的,连接国外的网站速度是比较快的
本地安装
- 使用命令
npm install
或则npm i
来进行安装包 - 安装的包在当前目录下的
node_modules
目录中 - 因为
node_modules
的安装包通常比较大,所以最好用gitignore
来进行忽略
全局安装
全局安装其实跟项目的局部安装差不多,只不过全局安装的目录会是一个特殊的地址,不会变动
(通过npm root -g
可以找到全局的安装目录)
注意:全局安装的包并不是所有的工程都可以使用,是仅仅提供全局的CLI命令;比如典型的vue-cli工具
全局包的安装场景有如下三种情况
- 包的版本比较稳定,很少有大的更新
- 提供的CLI工具经常使用得到,不频繁的命令一般可以通过
npx 工具命令
来临时下载 - CLI 工具仅为开发环境提供支持,而非部署环境
2.包的配置
目前遇到的问题
- 复制的工程如何恢复原样,里面的包如何还原
- 生产依赖和开发依赖如何区分
- 如果当前的项目就是一个三方包,那么如何描述包的信息
配置文件
npm
会把每个项目当作包,包的信息通过package.json
配置文件来描述
注意:配置文件固定为package.json
一般通过npm init
来创建,配置文件内的信息如下
- name 包名(必须是英文单词字符)
- version 版本号
- description 包的描述
- homepage 官网地址
- author 包的作者 一般 account ;如果账号或则邮箱不正确的话,可能导致包发布失败
- repository 包的仓库地址
解决代码移植的问题
- 通过
package.json
配置文件来描述项目所需的安装包,这样在移植项目的时候,就不需要将node_modules
全部复制过来了 - 为了更加方便的安装依赖,一般通过
npm install
之后,会自动在package.json
中加入了额外的参数
# 安装生产依赖
npm install xxx
npm install --save xxx
npm install -S
# 安装开发依赖
npm install --save-dev xxx
npm install -D
3.包的使用
在node
中,对npm
支持的非常友好
当引用一个包的时候,只要不是以 './' 或则 '../' 开头,那么node
就会认为此模块来自于node_modules
中
关于导入模块的方法的查找方法如下
举例var v = require('vue')
- 查找
node_modules/vue.js
- 查找
node_modules/入口文件
- package.json中的
main
对应的文件 - 如果没有定义
main
字段,那么就用index.js
文件
- package.json中的
- 如果当前项目的
node_module
中没有上述的文件,那么就逐级向上一级目录中,继续上述两步的查找
4.语义版本
简介
比如我们在开发一个公共包A的时候,内部使用到了包B,此时的B的版本为2.3.4
,那么当别人在安装包A的时候,具体是安装依赖包的哪个版本呢?
是2.3.4
,还是安装最新的版本(比如最新的版本为3.0.0),又或则你希望的只是它安装的是2版本下最高版本
为了解决这些问题,npm
为此定义了一套使用规则,用来描述具体的依赖规则,我们称之为语义版本
版本号的详细含义
版本号一般的格式是 主版本号.次版本号.补丁版本号(比如2.3.4
)
- 主版本号
功能发生了很大的变化,技术架构发生了很大的变化,比如
Vue2
和Vue3
- 次版本号 当包发生小的方面的功能变化,基本上属于小改动
- 补丁版本号
只是修复一些
bug
,或则一些非常小的优化
语义版本具体解释
符号 | 描述 | 示例 | 示例描述 |
---|---|---|---|
大于某个版本 | >2.3.4 | 大于2.3.4版本 | |
>= | 大于等于某个版本 | >=2.3.4 | 大于等于2.3.4版本 |
< | 小于某个版本 | <2.3.4 | 小于2.3.4版本 |
<= | 小于等于某个版本 | <=2.3.4 | 小于等于2.3.4版本 |
- | 介于两个版本之间 | 1.0.0 - 2.3.4 | 介于1.0.0和2.3.4之间 |
x | 不固定版本号 | 2.3.x | 只要是2.3的版本就行 |
~ | 补丁号可增 | ~2.3.4 | 主版本号2,次版本号2,补丁版本号大于等于4 |
次版本和补丁版本号可增 | ^2.3.4 | 主版本号2,次版本号大于等于3,补丁版本号大于等于4 |
如何避免还原的差异
版本依赖的控制具体如何选择是一个比较头疼的问题
如果我们写死版本,不允许升级,也就是依赖B为2.3.4,那么确实能保证在引入包的时候,其依赖都是对的,跟开发的时候一致,但是这也放弃了包的自我升级与优化,
比如依赖包B又一个小bug,在下一个版本中优化了,那么就无法通过写死包的版本的方法无法得到这样的好处
如果我们允许依赖的升级,比如依赖B为2.3.4,当B包优化了很多功能,修复和很多bug,确实我们能享受得到这部分的优化,
但是由于是新的版本,也有可能有新的API
,有新的其他bug
针对上述遇到的问题,npm
在安装包的时候会自动生成一个package-lock.json
文件,此文件记录了安装包的时候准确的包的依赖关系,
当我们在移植工程的时候,一起移植了package-lock.json
,那么npm
就会以 lock
文件来安装包
这样就保证了与之前安装的依赖包一摸一样,如果你想用新的升级的包,可以直接删除lock
文件,重新安装依赖,此时就会生成新的package-lock.json
文件,记录此次安装的准确依赖
npm的差异版本的处理
当两个包中同时依赖同一个包的不同版本,那么此时node_moudles
不会扁平化处理,而是会形成嵌套的目录
5.npm 脚本
在实际的开发过程中,可能会涉及到很多的命令操作,命令非常的长,有很多的CLI命令,例如
- 启动命令(node或则第三方包提供的CLI命令,比如 webpack-cli)
- 部署命令(同上)
- 测试命令(同上)
上述命令中可能还要混入其他自定义的命令比如
rm -rf xxx
,自动清理某个文件夹自定义的操作 那么多命令非常的难以记忆,所以npm
,提供了相应的配置支持,就是scripts
字段,只需要在此字段上,配置相应的命令,那么就可以通过npm run xxx
来执行对应的一长串的命令
如果是一些比较常用的命令不需要使用 npm run xxx
,只需要npm xxx
就可以,包含的命令如下
- start(start 有默认值 node index.js)
- stop
- test
在脚本中可以神略npx
比如我们在控制台输入
npx webpack index.js
,到了script
中设置的时候start:webpack index.js
6.环境变量
原由
一般情况下,我们在真实开发的过程中,会有不同的环境,最简单的就是 开发环境/生产环境/测试环境 很多时候,我们需要根据不同的环境去做不同的配置
那么,我们通过环境变量来解决这个问题
- node中有一个global全局变量(类似于浏览器中的window对象),这个变量有很多的属性
- process 就是 global 中的一个变量,它是包含当前运行node进程的计算机的很多信息
- process 其中有一个 env的变量,是一个对象,包含了计算机中所有系统变量
- NODE_ENV 通常我们通过系统变量
NODE_ENV
,来判断程序处于哪种环境
如何配置
一般我们有两种方式配置NODE_ENV
,永久设置和临时设置,我们一般选择临时设置
# window设置
start: set NODE_ENV=development&&node index.js
# macos && linux
start: export NODE_ENV=development&&node index.js
- 因为不同系统设置存在差异,所以一般我们选用三方库就是
cross-env
start: cross-env NODE_ENV=development node index.js
package.json 中读取配置
很多时候,我们可能需要从 package.json
中获取一些数据(可以定义一些自定义的字段),那么直接通过require
导入就可
在node中,直接导入json文件,可以自动转成JS对象
7.其他npm命令
安装
# 精准的安装最新的版本
npm install --save-exact 包名
npm install -E 包名
# 安装指定版本
npm install 报名@版本号
查询
- 查询安装包的路径
npm root [-g]
- 查询包信息
# 全写(这样输出的信息比较多,子信息就是输出指定的属性,比如versions)
npm view 包名 [子信息]
# 简写
npm v 包名 [子信息]
- 查询安装包
# 依赖是嵌套的,通过 --depth=0/1/2,来指定输出到哪个层级
npm list [-g] [--depth=依赖深度]
# 简化写法
list 可以使用 ll/la/ls 来代替
更新
- 检查哪些包需要更新
npm outdated
- 更新包
npm update [-g] [包名]
## update的别名有 up/upgrade
卸载包
npm unstall [-g] 包名
# uninstall 的别名是 remove/rm/r/un/unlink
npm配置
通常我们在安装完npm
之后会有两份配置,一份是用户配置,一份是系统配置,当两分配有冲突的时候,用户配置会覆盖系统配置
当然我们通常不太关心这些,而是比较关注最终生成的配置
- 查询当前生效的配置
npm config ls [-l] [-json]
# ls 也可以用list 来代替
# -l 输出形式为 key-value形式
# -json 输出形式为 json的形式
- 获取某个配置项
npm config get 配置项
- 设置某个配置项
npm config set 配置项
- 移除某个配置项
npm config delete 配置项
8.发布包
准备工作
- 移除taobao镜像源
- npm官网注册账号(邮箱认证需要通过)
- 使用本地命令登录
npm
npm login
登录npm whoami
查询当前账号npm logout
登出
- 创建工程目录
- 使用
npm init
进行初始化
发布
- 开发
- 确定版本
npm publish
完成发布