npm 内部机制的理解

目录

npm 的安装机制和背后思想

npm 缓存机制

npm link :在本地调试验证包的可用性 

npx 的作用

搭建 npm 企业级部署私服

npm 镜像问题配置


参考文档:

npm官方文档:https://docs.npmjs.com/cli/v7/commands/npm-init

聊聊 NPM 镜像那些险象环生的坑: https://mp.weixin.qq.com/s/2ntKGIkR3Uiy9cQfITg2NQ

npm link的使用:https://www.jianshu.com/p/aaa7db89a5b2

npm 的安装机制和背后思想

 

  • npm install 执行之后,首先,检查并获取 npm 配置,这里的优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件。
  • 然后检查项目中是否有 package-lock.json 文件
    • 如果有,则检查 package-lock.json 和 package.json 中声明的依赖是否一致:
      • 一致,直接使用 package-lock.json 中的信息,从缓存或网络资源中加载依赖;
      • 不一致,按照 npm 版本进行处理(不同 npm 版本处理会有不同,具体处理方式如图所示)。
    • 如果没有,则根据 package.json 递归构建依赖树。然后按照构建好的依赖树下载完整的依赖资源,在下载时就会检查是否存在相关资源缓存:
      • 存在,则将缓存内容解压到 node_modules 中;
      • 否则就先从 npm 远程仓库下载包,校验包的完整性,并添加到缓存,同时解压到 node_modules。最后生成 package-lock.json。

  • 构建依赖树时,当前依赖项目不管其是直接依赖还是子依赖的依赖,都应该按照扁平化原则,优先将其放置在 node_modules 根目录(最新版本 npm 规范)。在这个过程中,遇到相同模块就判断已放置在依赖树中的模块版本是否符合新模块的版本范围,如果符合则跳过;不符合则在当前模块的 node_modules 下放置该模块(最新版本 npm 规范)。

npm 缓存机制

  • 查看npm 缓存文件:npm config get cache   
  • 清除缓存命令: npm cache clean --force
    •  content-v2 里面基本都是一些二进制文件。为了使这些二进制文件可读,我们把二进制文件的扩展名改为 .tgz,然后进行解压,得到的结果其实就是我们的 npm 包资源
    • 而 index-v5 文件中,我们采用跟刚刚一样的操作就可以获得一些描述性的文件,事实上这些内容就是 content-v2 里文件的索引
  • 这些缓存如何被储存并被利用的呢?
    • 当 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 能够对应到 index-v5 目录下的缓存记录。
    • 如果发现有缓存资源,就会找到 tar 包的 hash,根据 hash 再去找缓存的 tar 包,并再次通过pacote把对应的二进制文件解压到相应的项目 node_modules 下面,省去了网络下载资源的开销。

注意:这里提到的缓存策略是从 npm v5 版本开始的。在 npm v5 版本之前,每个缓存的模块在 ~/.npm 文件夹中以模块名的形式直接存储,储存结构是:{cache}/{name}/{version}。

npm link :在本地调试验证包的可用性 

  • 作用: 将模块链接到对应的业务项目中运行
  • 业务场景:假设你正在开发项目 project 1,其中有个包 package 1,对应 npm 模块包名称是 npm-package-1,我们在 package 1 项目中加入了新功能 feature A,现在要验证在 project 1 项目中能否正常使用 package 1 的 feature A,你应该怎么做?
    • 我们先在 package 1 目录中,执行 npm link,这样 npm link 通过链接目录和可执行文件,实现 npm 包命令的全局可执行。
    • 然后在 project 1 中创建链接,执行 npm link npm-package-1 命令时,它就会去 /usr/local/lib/node_modules/ 这个路径下寻找是否有这个包,如果有就建立软链接。
    • 这样一来,我们就可以在 project 1 的 node_module 中会看到链接过来的模块包 npm-package-1,此时的 npm-package-1 就带有最新开发的 feature A,这样一来就可以在 project 1 中正常开发调试 npm-package-1。当然别忘了,调试结束后可以执行 npm unlink 以取消关联。
  • 工作原理
    • 为目标 npm 模块(npm-package-1)创建软链接,将其链接到全局 node 模块安装路径 /usr/local/lib/node_modules/ 中
    • 为目标 npm 模块(npm-package-1)的可执行 bin 文件创建软链接,将其链接到全局 node 命令安装路径 /usr/local/bin/ 中

npx 的作用

  • npx 由 npm v5.2 版本引入,解决了 npm 的一些使用快速开发、调试,以及项目内使用全局模块的痛点。 
  • npx 执行模块时会优先安装依赖,但是在安装执行后便删除此依赖,这就避免了全局安装模块带来的问题。
  • 使用代码检测工具 ESLint比较方便
    • npx eslint --init
      npx eslint yourfile.js

搭建 npm 企业级部署私服

npm 镜像问题配置

  • 设置模块依赖的镜像地址 
# 查看Node版本和NPM版本确认已安装Node环境
node -v
npm -v

# 安装nrm并设置NPM的淘宝镜像
npm i -g nrm
nrm use taobao

# 设置依赖安装过程中内部模块下载Node的淘宝镜像
npm config set disturl https://npm.taobao.org/mirrors/node/

# 设置常用模块的淘宝镜像
npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/
npm config set sharp_dist_base_url https://npm.taobao.org/mirrors/sharp-libvips/
npm config set electron_mirror https://npm.taobao.org/mirrors/electron/
npm config set puppeteer_download_host https://npm.taobao.org/mirrors/
npm config set phantomjs_cdnurl https://npm.taobao.org/mirrors/phantomjs/
npm config set sentrycli_cdnurl https://npm.taobao.org/mirrors/sentry-cli/
npm config set sqlite3_binary_site https://npm.taobao.org/mirrors/sqlite3/
npm config set python_mirror https://npm.taobao.org/mirrors/python/
  • 针对node-sass的情况:
# 安装rimraf并设置package.json
npm i -g rimraf

# 安装前请确保当前的Node版本和node-sass版本已兼容

# 安装失败
npm cache clean -f
npm rebuild node-sass 或 npm run reinstall
  •  package.json中加入npm scripts
{
  "scripts": {
    "reinstall": "rimraf node_modules && npm i"
  }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值