npm
设置镜像
- 淘宝npm源将在2022年5月31日更换域名服务
yarn config set registry https://registry.npmmirror.com
yarn config set sass-binary-site https://registry.npmmirror.com/mirrors/node-sass
或者
npm set registry https://registry.npmmirror.com
npm set sass-binary-site https://registry.npmmirror.com/mirrors/node-sass
使用nrm来设置npm源镜像
npm install -g nrm
nvm use taobao
# 添加私有源
nrm add registry_home registry_url
# 比如添加公司私有源
nrm add 公司源名称 公司源地址
# 移除
nrm del 源名称
lock文件
目前常见的两种lock文件:
packahe-lock.json是npm5之后默认生成的锁文件yarn.lock是yarn的锁文件
作用:
- 1、锁定安装时的包的版本号,并且需要上传到git,以保证其他人在yarn install/npm install时大家的依赖能保证一致
- 2、会避免由于开发人员意外更改或者更新版本导致错误
npm 缓存机制
对于一个依赖包的同一版本进行本地化缓存,是当代依赖包管理工具的一个常见设计。使用时要先执行以下命令:
- 查看缓存路径
npm config get cache
这些缓存如何被储存并被利用的呢?
这就和 npm install 机制联系在了一起。当 npm install 执行时,通过pacote把相应的包解压在对应的 node_modules 下面。npm 在下载依赖时,先下载到缓存当中,再解压到项目 node_modules 下。pacote 依赖npm-registry-fetch来下载包,npm-registry-fetch 可以通过设置 cache 属性,在给定的路径下根据IETF RFC 7234生成缓存数据。
- 在每次安装包的时候,根据 package-lock.json 中存储的 integrity、version、name 信息生成一个唯一的 key,这个 key 能够对应到目录下的缓存记录,如果发现有缓存资源,就会找到 tar 包的 hash,根据 hash 再去找缓存的 tar 包,并再次通过pacote把对应的二进制文件解压到相应的项目 node_modules 下面,省去了网络下载资源的开销。
npm install理解
- npm install执行之后,首先会获取npm的配置 【项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件】
- 然后检查项目中
package-lock.json文件- 如果有,则检查 package-lock.json 和 package.json 中声明的依赖是否一致:
- 一致,直接使用 package-lock.json 中的信息,从缓存或网络资源中加载依赖;
- 不一致,按照 npm 版本进行处理
- 如果没有package-lock.json,则根据 package.json 递归构建依赖树。然后按照构建好的依赖树下载完整的依赖资源,在下载时就会检查是否存在相关资源缓存
- 存在,则将缓存内容解压到 node_modules 中;
- 否则就先从 npm 远程仓库下载包,校验包的完整性,并添加到缓存,同时解压到 node_modules
- 最后生成 package-lock.json。
如何加速 npm install
npx理解
- npx 会在当前目录下的
./node_modules/.bin里去查找是否有可执行的命令,没有找到的话再从全局里查找是否有安装对应的模块,全局也没有的话就会npm仓库下载对应的模块 - npx 执行模块时会安装依赖,但是在安装执行后便删除此依赖
- 避免全局安装模块
npm publish理解
发布文件配置
发布哪些文件?
- 发布一个包,考虑到别人的下载速度,包体积肯定需要尽量小,所以源文件最好不包括,那如何控制只发哪些文件呢?
files 属性用于描述你 npm publish 后推送到 npm 服务器的文件列表,如果指定文件夹,则文件夹内的所有内容都会包含进来。我们可以看到下载后的包是下面的目录结构:
另外,你还可以通过配置一个
.npmignore文件来排除一些文件, 防止大量的垃圾文件推送到npm, 规则上和你用的.gitignore是一样的。.gitignore文件也可以充当.npmignore文件。
- 一般发布是dist、lib 打包编译后的文件
{
"files": [
"bin",
"dist",
"lib"
]
}
发布版本
npm的发包需要遵循语义化版本,一个版本号包含三个部分: patch、minor、major
在修改 npm 包某些功能后通常需要发布一个新的版本,我们通常的做法是直接去修改 package.json 到指定版本。如果操作失误,很容易造成版本号混乱,我们可以借助符合 Semver 规范的命令来完成这一操作:
npm version patch: 升级修订版本号npm version minor: 升级次版本号npm version major: 升级主版本号
依赖类型理解
npm 设计了以下几种依赖类型声明:
dependencies 项目依赖
devDependencies 开发依赖
peerDependencies 同版本依赖
bundledDependencies 捆绑依赖
optionalDependencies 可选依赖
dependencies
dependencies 表示项目依赖(生产环境依赖),这些依赖都会成为线上生产环境中的代码组成部分。当npm 包被下载时【npm install】,这个包的dependencies 下的模块也会作为依赖,一起被下载。
devDependencies
表示开发依赖,不会被自动下载,因为 devDependencies 一般只在开发阶段起作用或只是在开发环境中需要用到。比如 Webpack,预处理器 babel-loader、scss-loader,测试工具 E2E、Chai 等,这些都是辅助开发的工具包,无须在生产环境使用。
注意:如果开发工具如脚手架命令行,webpack、babel、less等工具需要安装在生产环境,当用户下载npm install cli -g的时候(一般是安装在全局环境下,如果局部安装的话,需要安装在项目的开发环境中),也会把依赖下载到node_modules,如果安装在开发环境,使用这个包的时候如webpack、commander的时候会报错,显示找不到这个包
- 因为我们发布这个脚手架的时候,一般是发布打包编译后的代码 dist、lib,要把webpack、commamer等依赖也要打包进去做工具依赖使用
注意:
- typesscript和@type 类型文件不会被打包在最终的bundle中,所以安装在开发环境和生产环境都一样
peerDependencies
简单来说:peerDependencies就是用来防止多次引入相同的库,peerDependencies去声明一下需要依赖的插件和版本,如果出问题 npm 就会有警告来提醒使用者去解决版本冲突问题。
peer意思是同辈、同级,即peerDependencies理解为同级依赖
指定当前组件的依赖以其版本。如果组件使用者在项目中安装了其他版本的同一依赖,会提示报错。
- peerDependencies 表示同版本依赖,简单来说就是:如果你安装我,那么你最好也安装我对应的依赖。
peerDependencies 主要的使用场景。这类场景有以下特点:
- 插件不能单独运行
- 插件正确运行的前提是核心依赖库必须先下载安装
- 我们不希望核心依赖库被重复下载
- 插件 API 的设计必须要符合核心依赖库的插件编写规范
- 在项目中,同一插件体系下,核心依赖库版本最好相同
开发库主要注意的地方
- 生产环境依赖的问题:
- 如果当前库依赖这个包的版本,需要放在peerDependencies,因为业务方很可能也会使用安装这个包,会导致重复打包
- 使用webpack的话。可在 webpack 中加入 external 排除掉
npm版本控制
语义版本控制的概念很简单:所有的版本都有 3 个数字:x.y.z。
- 第一个数字是主版本。
- 第二个数字是次版本。
- 第三个数字是修复版本。
~: 如果写入的是 〜1.13.0,则当运行 npm update 时,会更新到修复版本:即 1.13.1 可以,但 1.14.0 不可以
^: 如果写入的是 〜1.13.0,则当运行 npm update 时,会更新到次版本:即 1.x.x, 不能 2.x.x
npm发布包 废弃/删除
npm包发布后可以对包进行废弃或删除操作,废弃和删除的区别在于:
- 废弃不会将包或版本从npm仓库删除,仍然可以继续下载安装,并在安装的时候会有警示
- 删除会将包从npm彻底删除,无法被下载安装
无论是废弃还是删除,都包含两个层面:
- 版本的废弃/删除
- 包的废弃/删除
一、废弃
废弃原因:
- 版本:鼓励用户更新最新版本
- 包:此包内容已经过时,没有了维护的价值
二、删除
npm不鼓励任何形式的删除,主要因为我们发布的包可能已经被其他人引用,如果我们删除了此包,其他人在重新安装含有我们包的依赖的工程时,出现找不到包问题。
基于此,npm做了相关的删除限制:
删除的版本24小时后方可重发!只有发布72小时之内的包可以删除!
npm run xxx执行过程
在前端开发的工作当中,使用
npm run dev的命令启动本地开发环境,是再正常不过的事了。那么,当输入完类似npm run xxx的命令后,究竟是如何触发各种构建工具的构建命令以及启动 Node 服务等功能的呢
npm 脚本的原理非常简单。每当执行 npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。
- 比较特别的是,
npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。- 这意味着,当前目录的
node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径
- 这意味着,当前目录的
如果npm run dev
- 1、找到dev对应的package.json的scripts对应命令
- 2、如果dev对应的是vite,那么就去
node_modules/vite目录下执行bin脚本
npm 包模块批量更新
- https://github.com/raineorshine/npm-check-updates
- npm-check-updates会将package.json依赖项升级到最新版本,而忽略指定的版本
ncu -u to upgrade package.json
然后执行 ncu -u,检查package.json文件,会发现package.json里面的依赖版本号已经变成最新版本
然后再 npm install即可
方法一:手动跟新:
- 修改
package.json中依赖包版本,执行npm install --force
方法二:使用第三方插件:
- npm-check-updates
`npm install -g npm-check-updates`
`ncu` // 查看可更新包
`ncu` -u // 更新package.json
`npm install` // 升级到最新版本
- taze
pnpm dlx taze -w
方法三:使用yarn代替npm
yarn upgrade
npm2/npm3
npm2
- npm2 是通过嵌套的方式管理 node_modules 的
- 嵌套的方式,会存在依赖复制多次的问题
- 每个依赖都有自己的node_modules,因此会导致依赖的依赖可能会被复制多次。
npm3
- npm3+ 通过铺平的扁平化的方式来管理 node_modules,避免了多层嵌套, 但是引入了幽灵依赖的问题,并且同名的包只会提升一个版本的,其余的版本依然会复制多次。
--legacy-peer-deps理解
- 启用
--legacy-peer-deps会使 npm 忽略 Peer Dependencies 的版本冲突错误 - 用于快速跳过包版本依赖检查
npm install --legacy-peer-deps
使用场景
- 项目中使用了旧版本依赖包,这些依赖的
peerDependencies声明与当前环境或其他依赖冲突。 - 快速解决安装问题,比如在老项目中新增一个依赖,而不想因为依赖冲突而进行复杂调整。
- 临时解决某些依赖问题
风险问题
- 潜在风险:忽略 Peer Dependencies 可能导致运行时问题,因为某些包可能依赖于特定版本的对等依赖