【NPM 笔记(二)】package.json 与 package-lock.json 的作用

16 阅读6分钟

package.json

package.json 是 NPM 项目的核心配置文件。

  • 项目基本元信息:记录脚本命令、项目入口、执行环境等。
  • 管理项目依赖:记录项目运行时所需的第三方依赖包以及版本范围。
  • 支持开源项目发布:记录项目开源协议、开源目录、项目名称、项目版本等。

字段详解

{
  // 项目名称:小写,可含 @ 或斜杠(如 @username/project),用于标识项目
  "name": "npm-demo",
  // 项目版本:遵循语义化版本(X.Y.Z),开源发布时必填
  "version": "1.0.0",
  // 项目描述:简要说明项目用途,便于开源时被搜索和理解
  "description": "A demo project for NPM learning",
  // 作者信息:格式可为 "姓名 <邮箱>" 或 "组织名",开源项目常用
  "author": "Your Name <your@email.com>",
  // 开源协议:如 MIT、ISC 等,规定项目使用权限(开源项目必填)
  "license": "ISC",
  // 关键词:数组形式,用于开源项目被搜索时匹配(如 ["vue", "npm"])
  "keywords": ["npm", "package.json"],
  // 私有项目标识:设为 true 时,禁止发布到 NPM 仓库(本地项目建议开启)
  "private": true,
  // 入口文件:其他项目引用当前项目时(如 require('npm-demo'))的默认加载路径
  "main": "./src/index.js",
  // 副作用文件声明:告知打包工具(如 Webpack)哪些文件不可被“树摇”(删除未引用代码)
  "sideEffects": ["./src/utils/polyfill.js", "*.css"],
   // 开发环境提示:运行时需满足以下版本要求
   "engines": {
      "node": ">=18.0.0" // Node.js ≥ 18.0.0
   },
  // 自定义脚本命令:通过 npm run <命令名> 执行,简化开发流程
  "scripts": {
     // 示例:npm run start 启动项目
    "start": "node ./src/index.js", 
     // 示例:构建生产环境代码
    "build": "webpack --mode production" 
  },
  // 生产环境依赖:项目运行时必需的库(如 UI 框架、工具库)
  // 安装命令:npm install <包名> -S 或 npm install <包名> --save
  "dependencies": {
     // 版本规范见下方说明
    "element-plus": "^2.7.6" 
  },
  // 开发环境依赖:仅开发时需要的工具(如打包工具、测试框架)
  // 安装命令:npm install <包名> -D 或 npm install <包名> --save-dev
  "devDependencies": {
     // 版本规范见下方说明
    "webpack": "^5.92.1"
  },
  // peer 依赖:开源项目中声明的“同伴依赖”,需用户手动安装(避免重复依赖)
  // 例:Vue 组件库通常声明 peerDependencies: { "vue": "^3.0.0" }
  "peerDependencies": {
     // 版本规范见下方说明
    "vue": "^3.2.0"
  }
}

版本号规范

版本号各部分含义

在 NPM 生态中,所有包的版本号均遵循 语义化版本规范(SemVer),格式为 X.Y.Z,每个数字代表明确的更新含义。

  • X(主版本号,Major):当进行 不兼容的 API 变更 时,主版本号递增(如 1.2.32.0.0)。
  • Y(次版本号,Minor):当 新增功能但保持向后兼容 时,次版本号递增(如 1.2.31.3.0)。
  • Z(补丁版本号,Patch):当 仅修复 bug 且保持向后兼容 时,补丁版本号递增(如 1.2.31.2.4)。

注意:版本规则并非所有库都能严格遵守,具体取决于开发者的实现风格。

版本号前缀

package.json 中声明依赖时,版本号前可添加前缀,控制 npm install 时的更新范围,避免项目依赖版本意外升级导致的兼容性问题。

  • 无前缀:固定版本(如 1.2.3),仅安装指定版本。
  • ~:锁定 X 和 Y,允许 Z 更新(如 ~1.2.3 → 可更新至 1.2.9)。
  • ^:锁定 X,允许 Y 和 Z 更新(如 ^1.2.3 → 可更新至 1.9.9)。
  • *****:始终安装最新版本(不推荐,可能导致兼容性问题)。

注意:建议使用 “无前缀”,这样就能保证每个项目开发者本地依赖包版本号一致。当前也可以通过 package-lock.json 进一步固化版本号。

peerDependencies

项目所需的前置依赖应记录在 peerDependencies 中。这表明该项目依赖于外部已安装的特定版本依赖,而非自身携带该依赖,需由用户手动安装

element-plus 为例:

{
  "peerDependencies": {
    "vue": ">=3.2.0"
  }
}
  • 使用 element-plus 的项目必须自行安装 vue@>=3.2.0(否则 npm 会抛出版本不兼容警告)。

  • element-plus 不会将 vue 打包到自身代码中,而是在运行时直接引用项目中已安装的 vue 实例。

为什么需要 peerDependencies

避免重复安装:当多个依赖包(如 element-plusvue-routerpinia 等)均依赖 vue 时,若每个包在 dependencies 中单独声明 vuenpm install 会为每个包安装各自指定版本的 vue,导致 node_modules 中出现多个不同版本的 vue 依赖包。

通过 peerDependencies,所有依赖包会共享项目中安装的同一个 vue 版本,既减少磁盘空间占用。

控制依赖版本:依赖包可以通过 peerDependencies 明确声明兼容的外部依赖版本范围,例如 element-plus 声明 "vue": ">=3.2.0",意味着它只支持 Vue 3.2 及以上版本,若项目安装的 Vue 版本过低,可能导致组件运行异常。

这种机制将版本选择权交给项目开发者(可在兼容范围内选择具体版本),同时提前规避版本不兼容风险。

注意事项

  • 开发 第三方包 时,需严格区分 dependencies(用户运行时必需)和 devDependencies(仅开发者需要),避免冗余安装。
  • 本地项目建议设置 "private": true,防止误发布。

package-lock.json

package-lock.json 用于辅助package.json配置,确保团队协作依赖一致性。

  • 版本锁定:精确记录每个依赖(包括间接依赖)的安装版本,避免 npm install 时因版本范围(如 ^ ~)自动升级导致的兼容性问题;

  • 加速安装:通过 integrity 哈希值匹配本地缓存,无需重复从远程仓库下载;

  • 依赖可视化:清晰展示依赖树结构(直接依赖 → 间接依赖),便于排查版本冲突。

{ 
  // 项目名称
  "name": "npm",
  // 项目版本号
  "version": "1.0.0",
  // 项目package-lock.json的版本号
  "lockfileVersion": 3,
  // 项目的依赖关联采用的字段,如果是true,就会检验`dependencies`和`resolutions`两个字段
  "requires": true,
  // 项目的依赖
  "packages": {
    // 根依赖的入口
    "": {
      // 项目的名称
      "name": "npm",
      // 项目的版本号
      "version": "1.0.0",
      // 项目的开源协议
      "license": "ISC",
      // 根依赖的关联依赖
      "dependencies": {
        "less": "^4.2.0",
        "vue": "^2.7.7"
      }
    },
    "node_modules/vue": {
      // 依赖的版本号
      "version": "2.7.7",
      // 依赖的registry仓库的压缩包地址
      "resolved": "https://registry.npmmirror.com/vue/-/vue-2.7.7.tgz",
      // 当需要下载时,使用该字段的值和本地依赖缓存进行比对,如果相同就不在去registry仓库下载,而是直接使用本地缓存
      "integrity": "sha512-osfkncsGCWqtch+YWYxbqTNQ9hl/UQ6TFRkdmK/VqAjuMpxzr5QotFsYpmJ1AB1ez2LJeIKXDmtMkXUotMOTsA==",
      // deprecated 字段用于标记某个依赖项已经被废弃
      "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.",
      "dependencies": {
        "@vue/compiler-sfc": "2.7.7",
        "csstype": "^3.1.0"
      }
    }
  }
}

注意事项

  • 无需手动修改 package-lock.json,NPM 会自动维护其内容。
  • 团队协作时,需将其纳入版本控制(如 Git),确保所有人使用一致的依赖版本。