- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
相信小伙伴们都接触过 npm/yarn ,这两种包管理工具想必是大家工作中用的最多的包管理工具, npm 作为 node 官方的包管理工具,它是随着node的诞生一起出现在大家的视野中,而 yarn 的出现则是为了解决 npm 带来的诸多问题,虽然 yarn 提高了依赖包的安装速度与使用体验,但它依旧没有解决 npm 的依赖重复安装等致命问题。 pnpm 的出现完美解决了依赖包重复安装的问题,并且实现了 yarn 带来的所有优秀体验,所以说 pnpm才是前端工程化项目的未来 .
如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,文章公众号首发,关注 前端南玖 第一时间获取最新文章~ 。
在npm@3之前, node_modules 结构可以说是 整洁 、 可预测 的,因为当时的依赖结构是这样的:
node_modules
└─ 依赖A
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
└─ package.json
└─ 依赖C
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
└─ package.json
每个依赖下面都维护着自己的 node_modules ,这样看起来确实非常整洁,但同时也带来一些较为严重的问题:
从上面的依赖结构我们可以看出,依赖A与依赖C同时引用了依赖B,此时的依赖B会被下载两次。此刻我们想想要是某一个依赖被引用了n次,那么它就需要被下载n次。(此时心里是不是在想,怎么会有如此坑的设计) 。
我们再来看另外一种依赖结构:
node_modules
└─ 依赖A
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖C
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖D
├─ index.js
└─ package.json
这种依赖层级少还能接受,要是依赖层级多了,这样一层一层嵌套下去,就像一个依赖地狱,不利于维护.
为了解决上述问题, npm3 与 yarn 都选择了扁平化结构,也就是说现在我们看到的 node_modules 里面的结构不再有依赖嵌套了,都是如下依赖结构:
node_modules
└─ 依赖A
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖C
├─ index.js
├─ package.json
└─ node_modules
└─ 依赖B
├─ index.js
├─ package.json
└─ node_modules
node_modules 下所有的依赖都会平铺到同一层级。由于require寻找包的机制,如果A和C都依赖了B,那么A和C在自己的node_modules中未找到依赖C的时候会向上寻找,并最终在与他们同级的node_modules中找到依赖包C。 这样 就不会出现重复下载的情况。而且依赖层级嵌套也不会太深。因为没有重复的下载,所有的A和C都会寻找并依赖于同一个B包。自然也就解决了实例无法共享数据的问题 。
由于这个扁平化结构的特点,想必大家都遇到了这样的体验,自己明明就只安装了一个依赖包,打开 node_modules 文件夹一看,里面却有一大堆.
这种扁平化结构虽然是解决了之前的嵌套问题,但同时也带来了另外一些问题:
这个怎么理解,为什么会产生这种问题呢?我们来仔细想想,加入有如下一种依赖结构:
A包与B包同时依赖了C包的不同版本, 由于同一目录下不能出现两个同名文件,所以这种情况下同一层级只能存在一个版本的包,另外一个版本还是要被嵌套依赖.
那么问题又来了,既然是要一个扁平化一个嵌套,那么这时候是如何确定哪一个扁平化哪一个嵌套的呢?
这两种结构都有可能,准确点说 哪个版本的包被提升,取决于包的安装顺序! 。
这就是为什么会产生依赖结构的 不确定 问题,也是 lock 文件 诞生的原因,无论是 package-lock.json (npm 5.x 才出现)还是 yarn.lock ,都是为了保证 install 之后都产生确定的 node_modules 结构.
尽管如此,npm/yarn 本身还是存在 扁平化算法复杂 和 package 非法访问 的问题,影响性能和安全.
前面说了那么多的 npm 与 yarn 的缺点,现在再来看看pnpm是如何解决这些尴尬问题的.
快速的,节省磁盘空间的包管理工具 。
就这么简单,说白了它跟 npm 与 yarn 没有区别,都是包管理工具。但它的独特之处在于:
从上图可以看出, pnpm 的包安装速度明显快于其它包管理工具。那么它为什么会比其它包管理工具快呢?
我们来可以来看一下各自的安装流程 。
resolving:首先他们会解析依赖树,决定要fetch哪些安装包.
fetching:安装去fetch依赖的tar包。这个阶段可以同时下载多个,来增加速度.
wrting:然后解压包,根据文件构建出真正的依赖树,这个阶段需要大量文件IO操作.
上图是pnpm的安装流程,可以看到针对每个包的三个流程都是平行的,所以速度会快很多。当然pnpm会多一个阶段,就是通过链接组织起真正的依赖树目录结构.
pnpm 内部使用 基于内容寻址 的文件系统来存储磁盘上所有的文件,这个文件系统出色的地方在于
hardlink
。 hardlink
,仅仅写入那 一个新增的文件
。 pnpm 与 npm/yarn 另外一个很大的不同就是支持了 monorepo,pnpm内置了对monorepo的支持,只需在工作空间的根目录创建pnpm-workspace.yaml和.npmrc配置文件,同时还支持多种配置,相比较lerna和yarn workspace,pnpm解决monorepo的同时,也解决了传统方案引入的问题.
monorepo 的宗旨就是用一个 git 仓库来管理多个子项目,所有的子项目都存放在根目录的 packages 目录下,那么一个子项目就代表一个 package .
pnpm使用的是npm version 2.x类似的嵌套结构,同时使用.pnpm 以平铺的形式储存着所有的包。然后使用Store + Links和文件资源进行关联。简单说pnpm把会包下载到一个公共目录,如果某个依赖在 sotre 目录中存在了话,那么就会直接从 store 目录里面去 hard-link,避免了二次安装带来的时间消耗,如果依赖在 store 目录里面不存在的话,就会去下载一次。通过Store + hard link的方式,使得项目中不存在NPM依赖地狱问题,从而完美解决了npm3+和yarn中的包重复问题.
我们分别用 npm 与 pnpm 来安装vite对比看一下 。
npm | pnpm |
---|---|
所有依赖包平铺在 node_modules 目录,包括直接依赖包以及其他次级依赖包 |
node_modules 目录下只有 .pnpm 和直接依赖包,没有其他次级依赖包 |
没有符号链接(软链接) | 直接依赖包的后面有符号链接(软链接)的标识 |
pnpm安装的 vite 所有的依赖都软链至了 node_modules/.pnpm/ 中的对应目录。 把 vite 的依赖放置在同一级别避免了循环的软链.
pnpm 是通过 hardlink 在全局里面搞个 store 目录来存储 node_modules 依赖里面的 hard link 地址,然后在引用依赖的时候则是通过 symlink 去找到对应虚拟磁盘目录下(.pnpm 目录)的依赖地址.
这两者结合在一起工作之后,假如有一个项目依赖了 A@1.0.0 和 B@1.0.0 ,那么最后的 node_modules 结构呈现出来的依赖结构可能会是这样的
node_modules
└── A // symlink to .pnpm/A@1.0.0/node_modules/A
└── B // symlink to .pnpm/B@1.0.0/node_modules/B
└── .pnpm
├── A@1.0.0
│ └── node_modules
│ └── A -> <store>/A
│ ├── index.js
│ └── package.json
└── B@1.0.0
└── node_modules
└── B -> <store>/B
├── index.js
└── package.json
node_modules 中的 A 和 B 两个目录会软连接到 .pnpm 这个目录下的真实依赖中,而这些真实依赖则是通过 hard link 存储到全局的 store 目录中.
pnpm 下载的依赖全部都存储到 store 中去了, store 是 pnpm 在硬盘上的公共存储空间.
pnpm 的 store 在Mac/linux中默认会设置到 {home dir}>/.pnpm-store/v3 ;windows下会设置到当前盘符的根目录下。使用名为 .pnpm-store的文件夹名称.
项目中所有 .pnpm/依赖名@版本号/node_modules/ 下的软连接都会连接到 pnpm 的 store 中去.
原文首发地址 点这里 ,欢迎大家关注公众号 「前端南玖」 ,如果你想进前端交流群一起学习, 请点这里 。
我是南玖,我们下期见!!! 。
最后此篇关于pnpm才是前端工程化项目的未来的文章就讲到这里了,如果你想了解更多关于pnpm才是前端工程化项目的未来的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
1. HTML 结构 1.1 HTML 文件基本结构 第一个html程序 hello world! html 标签是整个 h
文件上传三种方案:1. form表单上传,2. iframe,3. FormData,base64上传文件,二进制流上传文件,二进制流下载文件。异步上传,大文件上传--切片:拆分上传请求断点续传显示上
1. HTML 结构 1.1 HTML 文件基本结构 第一个html程序 hello world! html 标签是整个 h
uniapp作为开发移动端的前端框架,目前国内是非常流行的,使用HbuilderX开发工具基于uniapp框架开发的系统可以方便的转换为小程序、APP等移动端程序,大大降低了移动开发的成本。网络
今天我们来复盘一下前端中css伪元素的知识以及如何用css伪元素来减轻javascript的压力,做出一些脑洞大开的图形。 预备知识 伪元素 伪元素是一个附加至选择器末的
今天给大家分享一些实用的JS代码片段,有需要的朋友欢迎收藏! 1、获取浏览器的版 functiongetBrowser(){ varUserAgent=navigator.us
1 . Wappalyzer 全球用户数:1,000,000+ Wappalyzer可以帮助我们了解目标网站的构建方式。工作当中存在大量此类情况,客户需要我们参照某些网站
在管理后台中我们会使用大量的表格表单组件, 导入导出各种报表, 有些场景还需要对报表数据进行可视化分析, 动态生成可视化图表, 笔者将基于以上场景, 总结一些实用的 Table 组件开发技巧,
3D动画效果现在越来越普及,已经被广泛的应用到了各个平台,比如阿里云,华为云,webpack官网等。它可以更接近于真实的展示我们的产品和介绍,带来极强的视觉冲击感。所以说,为了让自己更加优秀,c
QShop商城-快速开始-前端 工具准备 NodeJs 前端环境为NodeJs,下载地址:http://nodejs.cn/download/current/ 。 默认会用版
1. 初始JavaScript 1.1 什么是 JavaScript JavaScript (简称 JS) 是世界上最流行的编程语言之一 是一个脚本语言, 通过解释器运行 主要在客户端(浏览器)上运行
1. WebAPI 背景知识 1.1 什么是 WebAPI JS 分成三个大的部分: ECMAScript: 基础语法部分 DOM API: 操作页面结构 BOM API: 操作浏览器 WebAPI
1. WebAPI 背景知识 1.1 什么是 WebAPI JS 分成三个大的部分: ECMAScript: 基础语法部分 DOM API: 操作页面结构 BOM API: 操作浏览器 WebAPI
1. 初始JavaScript 1.1 什么是 JavaScript JavaScript (简称 JS) 是世界上最流行的编程语言之一 是一个脚本语言, 通过解释器运行 主要在客户端(浏览器)上运行
有没有办法从页面访问 tomcat 服务器日志?如果有一些方法或实现可以做到这一点...... 最佳答案 PSI Probe可以列出您的 Tomcat 日志文件并显示它们的内容。您可以采用相同的方法,
我想知道是否有一些很好的免费网站性能分析工具,特别是前端。这主要是关于Javascript的。 现有工具(例如 Google Pagespeed)的问题在于它不适用于我的应用程序。在进入我的应用程序之
我曾经遇到一个 MySQL 前端应用程序,它在父行中显示外部链接行,例如,如果 Client 表有一个指向 Suburb 表的外键: (来源:vb123.com) 您知道可以执行此操作的任何前端吗?
我正在建立一个带有管理区域的网上商店来管理产品。在管理区域中,所有产品都是可见的,但在网上商店中,只有数据库表中标记为 active = 1 的产品是可见的。 我正在使用 Silex 并将存储库注册为
有可能在 C# 中制作 GUI,但在 C 或 C++ 中制作实际程序。 比如说我想制作一个聊天应用程序。我希望界面在 C# 中。但我想用 C 编写所有实际代码。这可能吗? 我找到了 http://ww
对于我自己的教育,我很好奇编译器使用哪个 C++ 前端和后端。您能告诉我以下技术在哪里使用以及它们有哪些标志/优势(如果有的话)? Open64 - 它是后端、前端还是两者兼而有之?哪些编译器使用它?
我是一名优秀的程序员,十分优秀!