npm知识大梳理

151 阅读10分钟

前言

npmnode包管理工具,类似于pip之于python;是前端工程化重要的组成部分,安装完node后,npm会自动安装好,也就是npmnode绑定使用,出场自带,所以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文件
  • 如果当前项目的 node_module中没有上述的文件,那么就逐级向上一级目录中,继续上述两步的查找

4.语义版本

简介

比如我们在开发一个公共包A的时候,内部使用到了包B,此时的B的版本为2.3.4,那么当别人在安装包A的时候,具体是安装依赖包的哪个版本呢? 是2.3.4,还是安装最新的版本(比如最新的版本为3.0.0),又或则你希望的只是它安装的是2版本下最高版本 为了解决这些问题,npm为此定义了一套使用规则,用来描述具体的依赖规则,我们称之为语义版本

版本号的详细含义

版本号一般的格式是 主版本号.次版本号.补丁版本号(比如2.3.4)

  • 主版本号 功能发生了很大的变化,技术架构发生了很大的变化,比如 Vue2Vue3
  • 次版本号 当包发生小的方面的功能变化,基本上属于小改动
  • 补丁版本号 只是修复一些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 报名@版本号

查询

  1. 查询安装包的路径 npm root [-g]
  2. 查询包信息
# 全写(这样输出的信息比较多,子信息就是输出指定的属性,比如versions)
npm view 包名 [子信息]
# 简写
npm v 包名 [子信息]
  1. 查询安装包
# 依赖是嵌套的,通过 --depth=0/1/2,来指定输出到哪个层级
npm list [-g] [--depth=依赖深度]
# 简化写法
list 可以使用 ll/la/ls 来代替

更新

  1. 检查哪些包需要更新 npm outdated
  2. 更新包
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.发布包

准备工作

  1. 移除taobao镜像源
  2. npm官网注册账号(邮箱认证需要通过)
  3. 使用本地命令登录npm
    • npm login 登录
    • npm whoami 查询当前账号
    • npm logout 登出
  4. 创建工程目录
  5. 使用npm init 进行初始化

发布

  1. 开发
  2. 确定版本
  3. npm publish 完成发布