Node工程的依赖包管理方式

京东云开发者
• 阅读 359

作者:京东零售 陈震

在前端工程化中,JavaScript 依赖包管理是非常重要的一环。依赖包通常是项目所依赖的第三方库、工具和框架等资源,它们能够帮助我们减少重复开发、提高效率并且确保项目可以正确的运行。

目前比较常见的前端包管理器有 npm 和 Yarn,npm 是 Node.js 自带的包管理器,它可以安装、共享和分发 node.js 模块。最近pnpm也挺火的,通过并行下载和安装依赖项,在执行安装、更新、删除等操作时也更快。

但无论使用哪个包管理器,都要通过 package.json 文件的版本控制功能,保证在不同开发环境中的一致性。那么,package.json是如何进行依赖包管理的呢?我们来一起深入了解一下package.json的配置方式。

一、分类管理

Node工程的依赖包管理方式
根据package.json规范,依赖包被大致分为以下几种:dependencies、devDependencies、optionalDependencies、peerDependencies和bundledDependencies总共5种。dependencies和devDependencies这两项是我们使用较为频繁的。

1、dependencies

工程在生产环境下也需要使用的依赖,例如react、antd等,使用npm安装插件时,会默认写入dependencies,也可以使用-P或--save-prod后缀。

2、devDependencies

工程只有开发环境需要,生产环境不需要的依赖,例如eslint、babel等,使用-D或--save-dev来写入devDependencies。

3、optionalDependencies

顾名思义,依赖是可选的,它们只有在运行时需要使用某些功能时才会被引入。通常用于实现某些可选的功能或优化。例如,一个包可能依赖于某个库来实现某种高级功能,但是这个库在某些环境下不存在或不可用。在这种情况下,可以将该库声明为可选依赖项,并在代码中检查该依赖项是否存在,然后根据情况来决定是否使用该高级功能。使用这个功能的工程比较少,使用-O或--save-optional来写入optionalDependencies。

4、peerDependencies

工程需要和这个依赖配套使用,一般用于解决插件依赖的核心库的版本和主项目依赖的核心库的版本不一致的问题,常见于开发配套插件。例如vuex@4.1.0声明了:

"peerDependencies": {
   "vue": "^3.2.0"
}

表明vuex@4.1.0需要和vue@^ 3.2.0一起安装和使用,否则可能会出现异常。使用-O或--save-optional来写入optionalDependencies。

5、bundledDependencies

工程依赖于某些特定的依赖项,并且希望在运行时不必再次下载它们,则可以使用该选项。npm pack会将这些依赖一同放入生成的包中,并且在npm install时本工程,这些依赖项也会被一同安装。使用-B或--save-bundle来写入bundledDependencies。

看到这里你可能会有点疑问,为什么npm没有提供类似--save-peer的指令来写入peerDependencies呢?原因是peerDependencies暗示本工程将会被其他主模块使用,但是主模块本身并不需要在项目代码中显式使用。因此官方没有支持这一指令。

二、版本管理

一般情况下,以上依赖配置(除了bundledDependencies)都需要指定依赖的版本号,版本号遵循semver语义化版本规范(Semantic Versioning)命名规则,可以用下图表示,如2.1.0、3.1.4-beta.2等。
Node工程的依赖包管理方式

  • 当发生不兼容的 API 修改时,更新major位
  • 当做了向下兼容的功能性新增时,更新minor位
  • 当做了向下兼容的问题修正时,更新patch位

可选的-tags即先行版本号,可以作为发布正式版之前的版本,格式是在修订版本号后面加上一个连接号(-),再加上一连串以点(.)分割的标识符,标识符可以由英文、数字和连接号([0-9A-Za-z-])组成。

在 npm 的依赖的规则中,还有~、>、<、=、>=、<=、-、||、x、X、*等符号来描述适用的版本范围;

  • ^ :表示只锁定major,不小于指定版本号的版本范围。例如^1.1.0,代表>=1.1.0 <2.0.0的版本范围。

  • ~ :表示锁定major和minor,不小于指定版本号的版本号。例如~1.1.0,代表>=1.1.0 <1.2.0的版本范围。

  • x、X、*:表示通配符。例如1.1.x,也代表>=1.1.0 <1.2.0的版本范围。

默认情况下,若指定了一个版本范围,npm会在范围内安装最新版本的依赖。当使用 npm install XX 时,会安装当前最新版本,并在版本号前默认加上 ^ 符号。因此在安装运行老项目时,很容易出现安装依赖后,项目启动报错的情况,原因就是某些依赖没有做到很好的向下兼容,导致重新安装的版本太高造成兼容性错误,此时需要定位错误依赖并回退版本。

三、npm install加载机制

Node工程的依赖包管理方式

npm install核心流程大致分为以下5步:

1、npm 向 registry 查询依赖压缩包的网址。
2、下载压缩包,存放在cache目录,供下次安装时使用。
3、解压压缩包到当前项目的node_modules目录。
4、把所有安装的包信息写入package-lock.json,供下次安装时使用。
5、继续处理依赖的依赖。

install的过程速度也和每一个步骤息息相关:
(1)共享工程package-lock.json,可以避免向registry查询的步骤,并且保证不同环境下安装包的一致性。
(2)使用下载速度快的registry镜像(例如jd镜像)。
(3)预先进行依赖关系分析构建依赖关系,然后最后再并行下载(例如yarn)。

希望以上的介绍能够帮助你更好的理解npm的依赖管理。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
PPDB:今晚老齐直播
【今晚老齐直播】今晚(本周三晚)20:0021:00小白开始“用”飞桨(https://www.oschina.net/action/visit/ad?id1185)由PPDE(飞桨(https://www.oschina.net/action/visit/ad?id1185)开发者专家计划)成员老齐,为深度学习小白指点迷津。
Wesley13 Wesley13
3年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Stella981 Stella981
3年前
Jenkins 插件开发之旅:两天内从 idea 到发布(上篇)
本文首发于:Jenkins中文社区(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fjenkinszh.cn)!huashan(https://oscimg.oschina.net/oscnet/f499d5b4f76f20cf0bce2a00af236d10265.jpg)
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_