跳到主要内容

npm

设置镜像​

text
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源镜像​

bash
npm install -g nrm
nvm use taobao
# 添加私有源
nrm add registry_home registry_url
# 比如添加公司私有源
nrm add 公司源名称 公司源地址
# 移除
nrm del 源名称

lock文件​

目前常见的两种lock文件:

  1. packahe-lock.json 是npm5之后默认生成的锁文件
  2. yarn.lock 是yarn的锁文件

作用:

  • 1、锁定安装时的包的版本号,并且需要上传到git,以保证其他人在yarn install/npm install时大家的依赖能保证一致
  • 2、会避免由于开发人员意外更改或者更新版本导致错误

npm 缓存机制​

对于一个依赖包的同一版本进行本地化缓存,是当代依赖包管理工具的一个常见设计。使用时要先执行以下命令:

  • 查看缓存路径
text
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 打包编译后的文件
json
{
"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 包模块批量更新​

text
ncu -u to upgrade package.json

然后执行 ncu -u,检查package.json文件,会发现package.json里面的依赖版本号已经变成最新版本

然后再 npm install即可

方法一:手动跟新:

  • 修改package.json中依赖包版本,执行npm install --force

方法二:使用第三方插件:

  • npm-check-updates
bash
`npm install -g npm-check-updates`
`ncu` // 查看可更新包
`ncu` -u // 更新package.json
`npm install` // 升级到最新版本
  • taze
js
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 的版本冲突错误
  • 用于快速跳过包版本依赖检查
bash
npm install --legacy-peer-deps

使用场景

  • 项目中使用了旧版本依赖包,这些依赖的 peerDependencies 声明与当前环境或其他依赖冲突。
  • 快速解决安装问题,比如在老项目中新增一个依赖,而不想因为依赖冲突而进行复杂调整。
  • 临时解决某些依赖问题

风险问题

  • 潜在风险:忽略 Peer Dependencies 可能导致运行时问题,因为某些包可能依赖于特定版本的对等依赖