网上很多文章介绍前端包/依赖管理的几个工具,我们这里从软件工程的角度,说一下他们的主要功能。
1. 软件工程
程序员实现某个功能,不会从零开始开发,都要基于大量第三方已经写好的功能模块,进行组装、扩展。
有了开源的协作力量,大量重复的有用的功能,被分成一个个单独的小模块(包),程序员之间可以进行共享,共同维护,测试、更新、添加更多新的功能。
常用编程语言的包管理工具:
- Java 语言有 Maven 仓库、Gradle;
- Go 语言有 dep 和 glide;
- Python 语言有 pip;
- Ruby 语言有 Gem 与 Bundler;
- PHP 语言有 (据说是最好的编程语言)Composer;
- Node.js 有多个包管理工具 NPM 仓库、Yarn、PNPM 等。
但是,论造轮子的能力,还是前端最强,
Atwood's Law:
Any application that can be written in JavaScript, will eventually be written in JavaScript.
任何可以用 JavaScript 来写的应用,最终都将用 JavaScript 来写。
其他语言有的,都会用 JS/TS 再实现一遍,其他人用 JS 写的,也会有多人多种方式实现,比如 jQuery 和 Zepto、Underscore 和 Lodash 等。
在编程语言之上,从应用的维度,也有包/依赖管理,那就是 Docker hub,在封装好的操作系统的基础上(Docker 容器),可以包含数据库、应用服务器等多种依赖,整体打包成 Docker 镜像。
2. 依赖管理的实现
首先要给每个包一个唯一的标识:
- 分组
- 包名
- 语义版本控制(semver):主版本号.次版本号.补丁版本号
- 主版本号: 当API发生改变,并与之前的版本不兼容的时候
- 次版本号: 当增加了功能,但是向后兼容的时候
- 补丁版本号:当做了向后兼容的缺陷修复的时候
- 修饰符:^ ~ -latest alpha bate 等
- 唯一值(hash 编码等)
然后有统一托管的地方:
- 中央仓库
- Maven 中央仓库有 Sonatype 维护:search.maven.org
- NPM 官方仓库:www.npmjs.com
- 镜像仓库
- 私有仓库
- Mavan 私有仓库可以用 Nexus 来搭建
- NPM 私有仓库可以用 verdaccio、nexus-npm 等来搭建
本地项目开发时,需要:
- 依赖配置文件(一般作为项目的入口文件)
- Maven 采用 pom.xml,
- Gradle 采用 build.gradle
- PHP composer 采用 composer.json
- Python pip 采用 requirements.txt
- 前端项目(Node 或 web 项目等)采用 package.json
- 本地缓存(用户 home 目录,系统根目录等)
- 项目目录下缓存
3. 包管理的难点
-
网络原因,访问国外官方镜像、或 Github 等第三方地址时,请求超时
-
嵌套层数太深,A 依赖 B,B 依赖 C、C 依赖 D,安装时很耗时
-
依赖冲突,A 依赖 B 的 1.0.0,而 C 依赖 B 的 2.0.0
-
通配符,A 依赖 B 的 1.0.0,而 C 依赖 B 的 1.0.2,那么 A 和 C 都可以使用较新的 1.0.2 版本的 B
-
磁盘空间占用大,之前 npm 多层嵌套后,目录路径可能会很长。对于 Windows 来说,有很多程序无法处理超过260个字符的文件路径名。
node_modules
- package-A -- node_modules --- package-B ----- node_modules ------ package-C -------- some-really-really-really-long-file-name-in-package-c.js 复制代码
4. 前端包管理工具
下面说说几个前端包管理工具 npm、yarn、pnpm、ni 的不同
约定的修饰符:
^(插入符号) 大版本下面的任意一个版本即可,第一位要相同,默认安装最新的版本。次版本号的变化并不会影响向后兼容性。因此,安装最新版的依赖库应该是能正常工作的,一般是的重要错误和安全方面的修复。~(波浪符号)次版本下面的任意一个版本即可,前两位要相同,默认安装最新的版本。
NPM 是 Node.js 安装时默认的包管理工具。NPM 团队做了很多的工作,以确保向后兼容,并在不同的环境中保持一致。(题外话:npmjs.com 被 GitHub 收购,而 GitHub 被微软收购)
Yarn 采取了不同的做法。每个 yarn 安装都会生成一个yarn.lock文件,解决由于语义版本控制而导致的npm安装的不确定性问题,而且它是默认创建的,lock 文件还包含要安装的内容的校验和,以确保使用的库的版本相同。
pnpm 运行起来非常的快,超过了npm和yarn,采用了一种巧妙的方法,利用硬链接和符号链接来避免复制所有本地缓存源文件,这是 Yarn 最大的性能弱点之一。
ni 是在 npm、yarn 之上又封装了一层:
-
根据锁文件猜测用哪个包管理器,假设你的项目中有锁文件
yarn.lock/pnpm-lock.yaml/package-lock.json,那么它最终会执行 相应的yarn install/pnpm i/npm i命令。 -
同时安装了其他命令:
nr- runnx- executenu- upgradenci- clean installnrm- remove
-
ni相关的命令,都可以在末尾追加?,表示只打印,不是真正执行,会输出真正要执行的命令 -
假设项目目录下没有锁文件,默认就会让用户从
npm、yarn、pnpm选择,然后执行相应的命令。但如果在~/.nirc文件中设置了全局默认的配置,则使用默认配置执行对应命令
作者:千寻位置前端团队
链接:juejin.cn/post/706180…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。