前端基础建设与架构-01(JS包管理工具与原理分析)

前端基础建设与架构-01(JS包管理工具与原理分析)

JS包管理工具与原理分析

npm

npm介绍
  • 核心目标:给你和你的团队、你的公司带来更好的开源库和依赖(Bring the best of open source you,your term and your company)。

  • 官网地址:https://www.npmjs.cn/

  • npm基本使用

# 检查npm是否已经安装以及安装的版本
npm -v

# 初始化一个package.json文件
npm init

# 安装依赖
# 不带包名:npm将会根据当前目录中的package.json文件安装所有依赖项
# 无参数:默认将包安装到项目的node_modules目录下,不会添加到package.json文件
# --global或-g:将包安装到全局环境,通常用于工具类包
# --save或-S:将包添加到package.json的dependencies字段,生产环境的依赖
# --save-dev或-D:将包添加到package.json的devDependencies字段,开发环境的依赖
# ‌--production:仅安装生产环境所需的依赖项,跳过开发依赖项
# ‌--legacy-peer-deps:允许使用旧版npm的peerDependencies行为
# ‌--no-save:安装包但不将其添加到package.json文件中的依赖项中‌
# --save-optional或-O:将包安装到可选环境,自动添加到optionalDependencies
# --workspace或-w:支持多工作区安装,适用于大型项目,可以独立管理不同部分的依赖
# --workspaces或-ws:禁用工作区,适用于不需要多工作区管理的项目
npm install <package-name>
npm i
npm add

# 更新依赖
npm update <package-name>

# 卸载依赖
npm uninstall <package-name>

# 运行脚本
npm run <script-name>
npm安装机制

在这里插入图片描述

  1. 检查并获取npm配置,这里的优先级为:项目级的.npmrc文件 > 用户级的.npmrc 文件 > 全局级的.npmrc 文件 > npm内置的.npmrc 文件。

    • .npmrc是一个配置文件,用于存储与npm相关的配置信息。在.npmrc文件中,你可以设置各种配置选项,例如:设置代理服务器、设置镜像源、登录到私有仓库、设置缓存位置。
  2. package-lock.json与package.json声明的依赖版本不一致时:

    • Npm v5.0.0前:npm锁定版本的方式是使用npm-shrinkwrap.json;
    • Npm v5.0.x:根据package-lock.json下载;
    • Npm v5.1.0 - v5.4.2:当package.json声明的依赖版本规范有符合更新版本时,忽略package-lock.json,按照package.json安装,并更新package-lock.json;
    • v5.4.2以上:当package.json声明的依赖版本规范与package-lock.json安装的版本兼容,则根据package-lock.json安装;如果不兼容,按照package.json安装,并更新package-lock.json。
  3. 构建依赖树时,当前依赖项目不管其是直接依赖还是子依赖的依赖,都应该按照扁平化原则,优先将其放置在node_modules根目录。

npm缓存机制
  • 介绍:在开发过程中,我们会多次的卸载和安装各种依赖包,导致了大量的网络请求。npm的缓存机制就是用来减少网络请求、加速重复安装过程。

  • 查看与清除npm缓存

# 查看npm缓存
npm config get cache

# 清除npm缓存
npm cache clean --force
  • _cacache文件夹目录
  1. content-v2:里面基本都是一些二进制文件。为了使这些二进制文件可读,我们把二进制文件的扩展名改为.tgz,然后进行解压,得到的结果其实就是我们的npm包资源。

  2. index-v5:里面基本都是一些二进制文件。将二进制文件的扩展名改为 .tgz,然后进行解压,就可以获得一些描述性的文件,这些内容就是content-v2里文件的索引。

  3. tmp

  • 缓存如何存储并利用
  1. npm install执行时,通过pacote把相应的包解压在对应的node_modules下。npm 在下载依赖时,先下载到缓存当中,再解压到项目 node_modules 下。(pacote 是一个专为Node.js设计的库,用于下载npm兼容的包。)

  2. pacote依赖npm-registry-fetch来下载包,npm-registry-fetch可以通过设置 cache属性,在给定的路径下生成缓存数据。

  3. 在每次安装资源时,根据package-lock.json中存储的integrity、version、name信息生成一个唯一的key,这个key能够对应到index-v5目录下的缓存记录。

  4. 如果发现有缓存资源,就会找到tar包的hash,根据hash再去找缓存的tar包,并再次通过pacote把对应的二进制文件解压到相应的项目node_modules下。

注: npm v5版本之前:~/.npm 文件夹中以模块名的形式直接存储,储存结构是:{cache}/{name}/{version}

npm小技巧
  • npm init命令:输出一个初始化的package.json文件
# 自定义npm init命令

# .npm-init/init.js文件

#!/usr/bin/env node
module.exports = {
    key: 'value'
    name: prompt('name?', process.cwd().split('/').pop()),
    version: prompt('version?' '0.0.1'),
    description: prompt('请输入项目描述''项目描述...'),
    main: 'index.js'
    repository: prompt('github repository url', '', function(url){
        if(url) {
            run('touch README.md');
            run('git init');
            run('git add README.md');
            run('git commit -m "first commit"');
            run(`git remote add origin ${url}`);
            run ('git push -u origin master');
        }
        return url;
    })
}


npm config set init-module ./.npm-init/init.js
npm config set init.author.name ""
npm config set init.author.email ""
npm config set init.author.url ""
npm config set init.license "MIT"
  • npm link命令:高效率在本地调试已验证包的可用性。npm link 的本质就是软链接,主要做了两件事:
  1. 为目标npm模块创建软链接,将其链接到全局node模块安装路径/usr/local/lib/node_modules/中。

  2. 为目标npm模块的可执行bin文件创建软链接将其链接到全局node命令安装路径/usr/local/bin/中。

  • npx
  1. 可以直接执行node_modules/.bin文件夹下的文件、可以自动去node_modules/.bin 路径和环境变量$PATH里面检查命令是否存在。

  2. npx执行模块时会优先安装依赖,但是在安装执行后便删除此依赖,这就避免了全局安装模块带来的问题。如:npx create-react-app react-project

npm镜像源管理工具
  • 镜像源切换
# 切换至淘宝镜像源
npm config set init.author.name ""npm config set registry http://registry.npm.taobao.org

# 查看镜像源使用状态
npm get registry

# 切回官方镜像源
npm config set registry http://www.npmjs.org
  • 使用nrm(npm registry manager)的镜像源管理工具
# 全局安装nrm
npm install -g nrm

# 查看可选的源
nrm ls

# 切换源
nrm use taobao

# 增加源
nrm add <registry> <url> #reigstry为源名,url为源的路径

# 删除源
nrm del <registry>

# 测试相应源的响应时间
nrm test  <registry>
  • 通过npm-preinstall的钩子和npm脚本,在安装公共依赖前自动切换源
"scripts": {
  "preinstall": "node ./bin/preinstall.js"
}

# preinstall.js 
require(' child_process').exec('npm config get registry', function(error, stout, stderr) {
  if (!stdout.toString().match(/registry\.x\/com/)) {
    exec('npm config set @xscope:registry https://xxx.com/npm/')
  }
})
部署一个私有的npm镜像
  • 常用工具:nexus、verdaccio、cnpm

yarn

yarn介绍
  • 背景:解决npm安装速度慢,稳定性差的问题。在npm还处于V3的时候,npm还没有package-lock.json文件,当时的npm安装速度慢,稳定性差,所以在2016年,Yarn就出现了。

  • 优点:

  1. 速度快:Yarn通过并行化操作大大提升了依赖安装的速度。与npm串行安装不同,Yarn可以同时执行多个任务,从而更快速地完成依赖安装。

  2. 离线模式:Yarn支持离线模式,即使在没有网络的情况下,也能安装依赖包。Yarn会缓存下载过的每一个包,下一次安装时直接从缓存中读取,大大提升了安装速度。

  3. 确定性:Yarn使用yarn.lock文件锁定依赖包的版本,确保每次安装的依赖包版本一致,避免了“今天能用明天不能用”的情况。

  4. 采用扁平化的安装模式:将依赖包的不同版本,根据一定的策略,归结为单个版本,避免创建多个副本产生冗余。

  • 常用基本使用
# 初始化项目
yarn init 

# 安装依赖
# –-dev 安装到devDependencies下
yarn add <packageName> 

# 移除依赖包
yarn remove <packageName> 

# 更新目录下指定的依赖包
yarn upgrade <packageName> 

# 在全局安装依赖包
yarn global add <packageName> 

# 查看配置key的值
yarn config get key 

# 设置配置项key的值
yarn config set key 

# 查询所有依赖
yarn list

# 查看依赖包的信息
yarn info <packageName>  

# 获取配置信息
yarn config list
yarn缓存
  • yarn默认使用prefer-online模式,也就是优先使用网络数据,如果网络数据请求失败,再去请求缓存数据。
# 查看yarn的缓存目录
yarn cache dir 

# 查看缓存的包文件
yarn cache list

# 清除缓存
yarn cache clean
yarn的安装理念

在这里插入图片描述

  • 检查包(Checking):检查是否存在npm相关的一些文件,比如package-lock.json文件等,如果有会提醒用户,可能会产生冲突,还会有cup、os的检查。

  • 解析包(Resolving):解析依赖树中的所有包的版本信息。由于依赖树是一个多层嵌套的结构,所有在这一步会进行一个递归解析。

  • 获取包:包资源的来源有两个地方,一个是网络,一个是缓存。Yarn如何区分我们的包是要在网络上下载还是从缓存中进去查找了?

  1. yarn会根据cacheFolder+slug+node_modules+pkg.name生成一个path;
  2. 判断系统中是否存在这个路径,如果存在,说明系统中存在缓存,不需要重新下载,如果不存在就需要重新下载
  • 链接包:这一步的目的是将依赖资源包放入到项目的node_modules中。

  • 构建包:如果依赖资源包存在二进制包需要编译,会在这一步进行处理。

pnpm

pnpm介绍
  • pnpm(Performant npm),速度快、节省磁盘空间的软件包管理器。

  • 官网地址:https://www.pnpm.cn/

  • 优势:

  1. 快速:pnpm比npm快了近2倍;
  2. 高效:node_modules中的所有文件均克隆或硬链接自单一存储位置;
  3. 支持单体仓库:pnpm内置了对单个源码仓库中包含多个软件包的支持;
  4. 权限严格:pnpm创建的node_modules默认并非扁平结构,因此代码无法对任意软件包进行访问
  • 常用基本使用
# 安装软件包及其依赖的任何软件包
# 默认保存到dependencies
# -D:保存到 devDependencies
# -O:保存到 optionalDependencies
# -g:全局安装
pnpm add 

# 用于安装项目所有依赖
pnpm install 

# 根据指定的范围更新软件包的最新版本
pnpm update

# 从node_modules和项目的package.json中删除相关packages
pnpm remove
pnpm缓存
# 查看pnpm的缓存路径
# 您可以手动删除该路径下的文件,以清除pnpm的缓存
pnpm store path

# 清除缓存
pnpm store prune
pnpm的原理
  • 硬连接(hard link):电脑文件系统中的多个文件平等地共享同一个文件存储单元
  1. 硬链接不会新建inode(索引节点),源文件与硬链接指向同一个索引节点;
  2. 硬链接不支持目录,只支持文件级别,也不支持跨分区;
  3. 删除源文件和所有硬链接之后,文件才真正被删除。
  • 软连接(soft link):符号链接(软链接、Symbolic link)是一类特殊的文件,可以理解成快捷方式;
  1. 符号链接中存储的是源文件的路径,指向源文件,类似于Windows的快捷方式;
  2. 符号链接支持目录与文件,它与源文件是不同的文件,inode值不一样,文件类型也不同,因此符号链接可以跨分区访问;
  3. 删除源文件后,符号链接依然存在,但是无法通过它访问到源文件。
  • pnpm首先将依赖安装到全局store,然后通过symbolic link和hard link来组织目录结构,将全局的依赖链接到项目中,将项目的直接依赖链接到node_modules的顶层,所有的依赖则平铺于node_modules/.pnpm目录下,实现了所有项目的依赖共享store的全局依赖,解决了幽灵依赖和NPM分身的问题
  1. 如果你对同一依赖包使用相同的版本,那么磁盘上只有这个依赖包的一份文件;
  2. 如果你对同一依赖包需要使用不同的版本,则仅有版本之间不同的文件会被存储起来;
  3. 所有文件都保存在硬盘上的统一的位置,当安装软件包时,其包含的所有文件都会硬链接到此位置,而不会占用额外的硬盘空间,这让你可以在项目之间方便地共享相同版本的依赖包;

npm、pnpm、yarn对比

特性NPMYarnPNPM
发布时间2010年2016年2017年
工作原理递归地安装所有依赖到node_modules目录下构建扁平化的依赖树并优化安装过程使用单个全局存储层和符号链接来减少磁盘空间占用
安装方式npm installyarn add/installpnpm install
缓存机制本地缓存每个项目的依赖共享缓存,保证多个项目间的依赖版本一致共享存储层缓存,避免重复下载
安装速度相对较慢,尤其在网络不佳时快于npm,支持并行安装更快,充分利用磁盘空间和网络资源
磁盘空间占用每个项目下的node_modules有完整副本,占用较多空间同一依赖只在全局缓存一份利用符号链接进一步减少磁盘占用
离线模式支持,但需先下载过相关包供强大的离线模式也支持离线安装
网络策略单线程请求多线程并行请求多线程并行请求,智能网络调度
锁定文件package-lock.jsonyarn.lockpnpm.lock.yaml
依赖一致性通过package-lock.json实现一定的依赖版本控制强制一致,每次安装都会严格按照yarn.lock文件同样强制一致,基于pnpm-lock.yaml
磁盘空间使用重复存储包,空间利用率低缓存机制较好通过硬链接节省空间
安全性通过npm audit检查依赖的安全性同样具有审计功能,检查安全漏洞支持安全审计
特色功能npx,用于执行一次性命令;npm ci用于快速、可靠的持续集成环境构建更加严格的版本控制,改进的冲突解决策略;workspaces支持多包管理针对monorepo设计,高效的多包管理和tree shaking能力
生态系统最大,兼容性最好兼容npm的所有特性,并额外增强了一些功能对npm生态完全兼容,但在大型项目中有更好表现
依赖一致性通过package-lock.json实现一定的依赖版本控制强制一致,每次安装都会严格按照yarn.lock文件同样强制一致,基于pnpm-lock.yaml
磁盘空间使用重复存储包,空间利用率低缓存机制较好通过硬链接节省空间
安全性通过npm audit检查依赖的安全性同样具有审计功能,检查安全漏洞支持安全审计
特色功能npx,用于执行一次性命令;npm ci用于快速、可靠的持续集成环境构建更加严格的版本控制,改进的冲突解决策略;workspaces支持多包管理针对monorepo设计,高效的多包管理和tree shaking能力
生态系统最大,兼容性最好兼容npm的所有特性,并额外增强了一些功能对npm生态完全兼容,但在大型项目中有更好表现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值