前端底子创建与架构-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安装机制
- 检查并获取npm设置,这里的优先级为:项目级的.npmrc文件 > 用户级的.npmrc 文件 > 全局级的.npmrc 文件 > npm内置的.npmrc 文件。
- .npmrc是一个设置文件,用于存储与npm相关的设置信息。在.npmrc文件中,你可以设置各种设置选项,例如:设置代理服务器、设置镜像源、登录到私有堆栈、设置缓存位置。
- 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。
- 构建依赖树时,当前依赖项目不管其是直接依赖还是子依赖的依赖,都应该按照扁平化原则,优先将其放置在node_modules根目次。
npm缓存机制
- 介绍:在开发过程中,我们会多次的卸载和安装各种依赖包,导致了大量的网络哀求。npm的缓存机制就是用来淘汰网络哀求、加速重复安装过程。
- 查看与扫除npm缓存
- # 查看npm缓存
- npm config get cache
- # 清除npm缓存
- npm cache clean --force
复制代码
- content-v2:内里基本都是一些二进制文件。为了使这些二进制文件可读,我们把二进制文件的扩展名改为.tgz,然后进行解压,得到的结果实在就是我们的npm包资源。
- index-v5:内里基本都是一些二进制文件。将二进制文件的扩展名改为 .tgz,然后进行解压,就可以得到一些形貌性的文件,这些内容就是content-v2里文件的索引。
- tmp
- npm install执行时,通过pacote把相应的包解压在对应的node_modules下。npm 在下载依赖时,先下载到缓存当中,再解压到项目 node_modules 下。(pacote 是一个专为Node.js设计的库,用于下载npm兼容的包。)
- pacote依赖npm-registry-fetch来下载包,npm-registry-fetch可以通过设置 cache属性,在给定的路径下生成缓存数据。
- 在每次安装资源时,根据package-lock.json中存储的integrity、version、name信息生成一个唯一的key,这个key可以或许对应到index-v5目次下的缓存记录。
- 如果发现有缓存资源,就会找到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 的本质就是软链接,重要做了两件事:
- 为目标npm模块创建软链接,将其链接到全局node模块安装路径/usr/local/lib/node_modules/中。
- 为目标npm模块的可执行bin文件创建软链接将其链接到全局node命令安装路径/usr/local/bin/中。
- 可以直接执行node_modules/.bin文件夹下的文件、可以自动去node_modules/.bin 路径和环境变量$PATH内里检查命令是否存在。
- 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就出现了。
- 优点:
- 速率快:Yarn通过并行化操纵大大提升了依赖安装的速率。与npm串行安装差别,Yarn可以同时执行多个使命,从而更快速地完成依赖安装。
- 离线模式:Yarn支持离线模式,即使在没有网络的环境下,也能安装依赖包。Yarn会缓存下载过的每一个包,下一次安装时直接从缓存中读取,大大提升了安装速率。
- 确定性:Yarn利用yarn.lock文件锁定依赖包的版本,确保每次安装的依赖包版本一致,避免了“今天能用明天不能用”的环境。
- 采用扁平化的安装模式:将依赖包的差别版本,根据肯定的计谋,归结为单个版本,避免创建多个副本产生冗余。
- # 初始化项目
- 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怎样区分我们的包是要在网络上下载还是从缓存中进去查找了?
- yarn会根据cacheFolder+slug+node_modules+pkg.name生成一个path;
- 判断系统中是否存在这个路径,如果存在,说明系统中存在缓存,不需要重新下载,如果不存在就需要重新下载
- 链接包:这一步的目标是将依赖资源包放入到项目标node_modules中。
- 构建包:如果依赖资源包存在二进制包需要编译,会在这一步进行处理。
pnpm
pnpm介绍
- pnpm(Performant npm),速率快、节流磁盘空间的软件包管理器。
- 官网地点:https://www.pnpm.cn/
- 上风:
- 快速:pnpm比npm快了近2倍;
- 高效:node_modules中的所有文件均克隆或硬链接自单一存储位置;
- 支持单体堆栈:pnpm内置了对单个源码堆栈中包含多个软件包的支持;
- 权限严格: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):电脑文件系统中的多个文件划一地共享同一个文件存储单元
- 硬链接不会新建inode(索引节点),源文件与硬链接指向同一个索引节点;
- 硬链接不支持目次,只支持文件级别,也不支持跨分区;
- 删除源文件和所有硬链接之后,文件才真正被删除。
- 软连接(soft link):符号链接(软链接、Symbolic link)是一类特殊的文件,可以理解成快捷方式;
- 符号链接中存储的是源文件的路径,指向源文件,类似于Windows的快捷方式;
- 符号链接支持目次与文件,它与源文件是差别的文件,inode值不一样,文件类型也差别,因此符号链接可以跨分区访问;
- 删除源文件后,符号链接依然存在,但是无法通过它访问到源文件。
- pnpm起首将依赖安装到全局store,然后通过symbolic link和hard link来组织目次布局,将全局的依赖链接到项目中,将项目标直接依赖链接到node_modules的顶层,所有的依赖则平铺于node_modules/.pnpm目次下,实现了所有项目标依赖共享store的全局依赖,办理了幽灵依赖和NPM分身的问题
- 如果你对同一依赖包利用相同的版本,那么磁盘上只有这个依赖包的一份文件;
- 如果你对同一依赖包需要利用差别的版本,则仅有版本之间差别的文件会被存储起来;
- 所有文件都生存在硬盘上的同一的位置,当安装软件包时,其包含的所有文件都会硬链接到此位置,而不会占用额外的硬盘空间,这让你可以在项目之间方便地共享相同版本的依赖包;
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生态完全兼容,但在大型项目中有更好表现
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |