一、简介
CommonJS 的出现,使 node 环境下的 JS 代码可以用模块更加细粒度的划分。一个类、一个函数、一个对象、一个配置等等均可以作为模块,这种细粒度的划分,是开发大型应用的基石。
为了解决在开发过程中遇到的常见问题,比如加密、提供常见的工具方法、模拟数据等等,一时间,在前端社区涌现了大量的第三方库。这些库使用 CommonJS 标准书写而成,非常容易使用。
这些库通常以NPM包的形式提供依赖,而且在使用时需要进行版本管理。因此需要一个包管理库来统一管理这些依赖库,来避免版本冲突和管理繁琐。
模块(module):通常以单个文件形式存在的功能片段,入口文件通常称之为入口模块或主模块。
库(library,简称lib):以一个或多个模块组成的完整功能块,为开发中某一方面的问题提供完整的解决方案
包(package):包含元数据的库,这些元数据包括:名称、描述、git主页、许可证协议、作者、依赖等等
常用的包管理工具包括:
NPM:NPM(Node Package Manager)是Node.js自带的包管理工具,也是最常用的包管理工具之一。可以方便地安装、升级、卸载依赖包,还可以发布自己的包到NPM仓库。
Yarn:Yarn是Facebook推出的包管理工具,具有速度快、缓存机制好等优点。与NPM相比,Yarn可以更快地下载依赖包,并且支持离线模式。
PNPM:PNPM(Permissive NPM)是一款新兴的包管理工具,采用了类似于软连接的方式,将依赖包安装到每个项目的 node_modules 目录下,从而避免了大量的重复安装。
二、NPM
目前所有的包管理器都是基于 npm 的,npm本身就是一个包管理器。
运行在 node 环境中,让开发者可以用简单的方式完成包的查找、安装、更新、卸载、上传等操作。
npm 由三部分组成:
registry:入口
可以把它想象成一个庞大的数据库
第三方库的开发者,将自己的库按照 npm 的规范,打包上传到数据库中
使用者通过统一的地址下载第三方包
查询包
注册、登录、管理个人信息
CLI:command-line interface 命令行接口
安装好 npm 后,通过 CLI 来使用 npm 的各种功能
- 本地安装:使用命令npm install 包名或npm i 包名即可完成本地安装,本地安装的包出现在当前目录下的node_modules目录中。
4.包配置:
(1)配置文件:npm将每个使用npm的工程本身都看作是一个包,包的信息通过一个名称固定的配置文件来描述。
该文件为:package.json。
配置文件中可以描述大量的信息,包括:
name:包的名称,该名称必须是英文单词字符,支持连接符
version:版本
版本规范:主版本号.次版本号.补丁版本号
主版本号:仅当程序发生了重大变化时才会增长,如新增了重要功能、新增了大量的API、技术架构发生了重大变化
次版本号:仅当程序发生了一些小变化时才会增长,如新增了一些小功能、新增了一些辅助型的API
补丁版本号:仅当解决了一些 bug 或 进行了一些局部优化时更新,如修复了某个函数的 bug、提升了某个函数的运行效率
description:包的描述
homepage:官网地址
author:包的作者,必须是有效的 npm 账户名,书写规范是 account ,例如:zhangsan zhangsan@gmail.com,不正确的账号和邮箱可能导致发布包时失败
repository:包的仓储地址,通常指 git 或 svn 的地址,它是一个对象
type:仓储类型,git 或 svn
url:地址
main:包的入口文件,使用包的人默认从该入口文件导入包的内容
keywords: 搜索关键字,发布包后,可以通过该数组中的关键字搜索到包
(2)保存依赖关系
package.json文件最重要的作用,是记录当前工程的依赖
dependencies:生产环境的依赖包
devDependencies:仅开发环境的依赖包
通过这样的方式,移植代码时,只需要移植源代码和package.json文件,不用移植node_modules目录,然后在移植之后通过命令即可重新恢复安装
5.语义版本:
当x.y.z的情况下:表示是一个明确的版本号当^x.y.z的情况下:表示是x版本保持不变,y和z永远是最新的当~x.y.z的情况下:表示的是x和y是保持不变的,z永远是最新的
当希望使用包的人使用指定包和版本时,需要在配置文件中描述具体的依赖规则,通过语义版本来实现,规则如下。
符号 描述 示例 示例描述
大于某个版本 >1.2.1 大于1.2.1版本
= 大于等于某个版本 >=1.2.1 大于等于1.2.1版本
< 小于某个版本 <1.2.1 小于1.2.1版本
<= 小于等于某个版本 <=1.2.1 小于等于1.2.1版本
- 介于两个版本之间 1.2.1 - 1.4.5 介于1.2.1和1.4.5之间
:
补丁版本号可增 ~1.3.4 保证主版本号是1,次版本号是3,补丁版本号大于等于4
^ 此版本和补丁版本可增 ^1.3.4 保证主版本号是1,次版本号可以大于等于3,补丁版本号可以大于等于4
- 最新版本 * 始终安装最新版本
三、Yarn
1.npm存在的问题:
(1)依赖目录嵌套层次深
(2)串行下载,无法完全利用带宽资源,多个相同版本的包被重复下载
(3)控制台输出大量的信息
(4)存在工程移植问题,版本依赖可以是模糊的,可能会导致工程移植后,依赖的确切版本不一致
2.如何解决上述问题:
(1)使用扁平的目录结构
(2)并行下载,使用本地缓存
(3)控制台仅输出关键信息
(4)使用yarn-lock文件记录确切依赖
3.优化:
增加了某些功能强大的命令
让既有的命令更加语义化
本地安装的CLI工具可以使用 yarn 直接启动
将全局安装的目录当作一个普通的工程,生成package.json文件,便于全局安装移植
4.新增了 yarn.lock 文件。
它是 yarn 在安装依赖包时,自动生成的一个文件,作用是记录 yarn 安装的每个 package 的版本,保证"package.json"依赖安装的版本和实际的版本是一致。后来 npm 也新增了作用相同的 package-lock.json
五、pnpm
1.pnpm全称:performant npm ,意味"高性能的npm"
优势:
目前,安装效率高于npm和yarn的最新版
极其简洁的node_modules目录
避免了开发时使用间接依赖的问题
能极大的降低磁盘空间的占用
2.原理
(1)使用缓存来保存已经安装过的包,以及使用 pnpm-lock.yaml 来记录详细的依赖版本
(2)使用符号链接和硬链接(类似于快捷方式)的做法来放置依赖,从而规避了从缓存中拷贝文件的时间,使得安装和卸载的速度更快
(3)由于使用了符号链接和硬链接,pnpm可以规避windows操作系统路径过长的问题,因此,它选择使用树形的依赖结果,有着几乎完美的依赖管理。也因为如此,项目中只能使用直接依赖,而不能使用间接依赖
3.硬链接: 硬连接指通过索引节点来进行连接。
软链接:另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
参考:
https://zhuanlan.zhihu.com/p/542738352
https://blog.csdn.net/qq_43750501/article/details/107523394
https://blog.csdn.net/weixin_42575028/article/details/127349060