包版本
目录
1. 语义化版本号基础
版本一般写成:
MAJOR.MINOR.PATCH
例如:1.4.2
部分 | 名称 | 含义 | 示例变化 |
---|---|---|---|
MAJOR | 主版本号 | 有不兼容的 API 变更 | 1.x.x → 2.x.x |
MINOR | 次版本号 | 向下兼容地新增功能 | 1.4.x → 1.5.x |
PATCH | 补丁号 | 向下兼容的修复 | 1.4.2 → 1.4.3 |
2. 常见符号含义
符号 | 示例 | 含义 | 实际安装范围 |
---|---|---|---|
^ | ^1.4.2 | 允许 不变更主版本 的更新 | >=1.4.2 <2.0.0 |
~ | ~1.4.2 | 允许 不变更次版本 的更新 | >=1.4.2 <1.5.0 |
> | >1.4.2 | 必须大于指定版本 | >1.4.2 |
>= | >=1.4.2 | 大于或等于指定版本 | >=1.4.2 |
< / <= | <2.0.0 | 小于 / 小于等于指定版本 | <2.0.0 |
* | * | 任意版本都行 | 任何版本 |
无符号 | 1.4.2 | 只安装这个确切版本 | 仅 1.4.2 |
x 或 latest | 1.4.x / latest | 通配符 / 最新发布版本 | 对应范围 |
举例对比
语法 | 能安装哪些版本 |
---|---|
^1.2.3 | 1.2.3 ~ 1.x.x 之间的更新(不包含 2.0.0) |
~1.2.3 | 1.2.3 ~ 1.2.x 之间的更新(不包含 1.3.0) |
1.2.3 | 只安装 1.2.3 |
>=1.2.3 <2.0.0 | 1.2.3 到 2.0.0 之前的任意版本 |
* | 任意版本 |
locl 文件
当第一次安装项目依赖时,包管理器 会生成一个 lock 文件,记录了依赖的版本信息。
当再次安装项目依赖时,如果 lock 文件存在,则根据 lock 文件中的版本信息安装依赖。(即使某个包有了新的版本)
如果 lock 文件和 package.json 文件中的依赖不一致或者缺少什么包,包管理器会尝试修复错误
--frozen-lockfile
当使用 --frozen-lockfile
选项时,如果 lock 文件存在,则强制根据 lock 文件中的版本信息安装依赖。如果有问题,则报错
这个参数常用与持续集成环境
dependencies 和 devDependencies
dependencies 是生产环境依赖,devDependencies 是开发环境依赖
- 使用
npm install
安装依赖时,默认安装 dependencies 和 devDependencies - 使用
npm install --production
安装依赖时,只安装 dependencies(用于生产环境)
实际开发建议
场景 | 应该放在哪 |
---|---|
运行时需要(框架、库) | dependencies |
构建工具(Vite、Webpack、Rollup) | devDependencies |
代码检查/格式化(ESLint、Prettier) | devDependencies |
测试工具(Jest、Vitest、Mocha) | devDependencies |
类型声明文件(@types/* ) | devDependencies |
CLI 工具,仅本地使用 | devDependencies |
在 前端项目(比如 React/Vite) 中,大多数依赖其实都属于 devDependencies,因为最终打包后的产物已经不再依赖这些模块。(打包完直接 nginx 部署了)
依赖泄漏
这是最令人头疼的问题。举例来说,若安装包 A,而 A internally 依赖 B,npm 或 Yarn 会把 B 提升至 node_modules 根目录。结果,即使未在 package.json 中声明 B,代码中却可以直接引用 import B from 'B',甚至不会报错。 这种隐式依赖如同一颗定时炸弹:一旦某天包 A 不再依赖 B,项目就会莫名崩溃,且极难排查。
这个问题在 yarn 和 npm 中都存在(v1),pnpm 则没有这个问题。