package.json最新最全指南

708 阅读12分钟

前言

package.json 是 Node.js 项目的配置文件,搞前端的小伙伴应该没有不知道的,本文着重介绍一些大家可能会忽略掉的细节。

基本属性

name

项目的名称,它是一个字符串。在给 name 字段命名时,需要注意以下几点:

  • 名称的长度必须小于或等于 214 个字符,不能以 “.” 和“_”开头,不能包含大写字母(这是因为当软件包在 npm 上发布时,会基于此属性获得自己的 URL,所以不能包含非 URL 安全字符);

  • 名称可以作为参数被传入 require (""),用来导入模块,所以应当尽可能的简短、语义化;

  • 名称不能和其他模块的名称重复,可以使用 npm view 命令查询模块名是否重复,如果不重复就会提示 404。

  • 如果你的包名与现有的包名太相近导致你不能发布这个包,那么推荐将这个包发布到你的作用域下

    • 例如:@babel/core包的@babel就是作用域。

version

表示该项目包的版本号。在每次项目改动后,即将发布时,都要同步的去更改项目的版本号。版本号的使用规范如下:

  • 版本号的命名遵循语义化版本 2.0.0 规范,格式为:「主版本号. 次版本号. 修订号」 ,通常情况下,修改主版本号是做了大的功能性的改动,修改次版本号是新增了新功能,修改修订号就是修复了一些 bug;

  • 如果某个版本的改动较大,并且不稳定,可能无法满足预期的兼容性需求,就需要发布先行版本,先行版本通过会加在版本号的后面,通过 “-” 号连接以点分隔的标识符和版本编译信息:内部版本(alpha)、公测版本(beta)和候选版本(rc,即 release candiate)

    • 内部版本(alpha):在版本号后面加上 -alpha.x,其中 x 是内部版本的编号。例如,1.0.0-alpha.1 表示第一个内部版本。
    • 公测版本(beta):在版本号后面加上 -beta.x,其中 x 是公测版本的编号。例如,1.0.0-beta.1 表示第一个公测版本。
    • 候选版本(rc,即 release candiate):在版本号后面加上 -rc.x,其中 x 是候选版本的编号。例如,1.0.0-rc.1 表示第一个候选版本。

点击了解更多包版本相关

description

description用于添加模块的描述信息,方便别人了解你的模块。

keywords

keywords用于给你的模块添加关键字。

他们还有一个非常重要的作用,就是利于模块检索。当你使用 npm search 检索模块时,会到description 和 keywords 中进行匹配。写好 description 和 keywords 有利于你的模块获得更多更精准的曝光

private

private:一个布尔值,如果设置为 true,表示这是一个私有项目,不应该被发布到公共 npm 仓库。

homepage

homepage 用于指定该模块的主页。

例如:eslint 的主页为 "homepage": "https://eslint.org",

repository

repository 用于指定模块的代码仓库。

如:

    "repository": {
        "type": "git",
        "url": "https://github.com/Microsoft/TypeScript.git",
        "directory": "packages/replace" // 指定子目录
    },

bugs

bugs 指定一个地址或者一个邮箱,对你的模块存在疑问的人可以到这里提出问题。

如:

"bugs": {"url": "https://github.com/user/my-project/issues"}

"bugs": "https://github.com/eslint/eslint/issues/",

main

main 字段用于指定主要的入口模块,该模块通常是项目的主要代码入口,用于导出项目的主要功能或逻辑。

在 Node.js 环境中,当通过 require 函数导入一个模块时,Node.js 会默认查找并加载指定的 main 模块作为入口。main 字段通常用于 CommonJS 模块规范,用于指定 CommonJS 模块的入口点。

"main": "src/main.js"

module

module 字段用于指定 ES6 模块规范中的入口模块。这个字段通常用于支持现代 JavaScript 模块化开发,允许你指定项目在 ES6 模块系统下的入口点。

一些工具和打包器(如 Webpack、Rollup)可以使用 module 字段来优化模块加载,如静态分析和树摇(Tree Shaking),并允许使用 ES6 模块语法。

"module": "src/main.esm.js"

了解更多静态分析相关

files

files 属性用于描述你 npm publish 后推送到 npm 服务器的文件列表,如果指定文件夹,则文件夹内的所有内容都会包含进来。

如:

  • "files": ["dist/", "*.js"]

scripts

自定义命令,可以通过 npm run <script> 执行。

  "scripts": {
    "build": "rollup -c",
  },

exports

用于定义模块的导出行为,特别是在使用 Node.js 和 ES 模块时。它可以控制哪些模块可以被其他文件导入,提供更细粒度的模块导出管理。

{
  "name": "your-package",
  "version": "1.0.0",
  "exports": {
    ".": "./src/index.js",
    ".": {
      "require": "./dist/bundle.cjs",
      "import": "./dist/bundle.js",
      "types": "./dist/types/index.d.ts"
    },
    "./feature": "./src/feature.js",
    "./subdir": {
      "import": "./src/subdir/index.mjs",
      "require": "./src/subdir/index.js"
    }
  }
}

作用:

  • 定义导出路径,明确哪些模块可以被导入。
  • 支持条件导出,根据导入方式(import 或 require)选择不同的实现。

路径定义:

  • ".": 指定包的主入口。
  • 可以为不同的子模块定义路径。
  • 支持 ES 模块和 CommonJS 的条件导出,通过不同的键(如 import 和 require)来指定。

当指定 "exports" 时,"main""module" 会被忽略。

type

用于指示 JavaScript 文件的模块类型。它主要用于区分 CommonJS 模块和 ES 模块,影响模块的解析和导入方式。

"type": "module"

可选值:

  • "module": 表示该包使用 ES 模块语法(import 和 export)。
  • "commonjs": 表示该包使用 CommonJS 模块语法(require 和 module.exports)。如果未指定,默认使用 CommonJS。

在 Node.js 12 及以上版本中支持。

当 type 设置为 "module" 时,文件扩展名 .js 被视为 ES 模块,而 .cjs 则被视为 CommonJS 模块;相反亦然。

types

用于指定 TypeScript 类型定义文件的路径。

"types": "./dist/types/index.d.ts"

license

license 属性在 package.json 中指定包的许可证类型。它告知用户如何合法地使用、修改和分发该包。常见的许可证包括:

  1. MIT: 简单且宽松,允许几乎所有使用。
  • 特点: 简单、宽松,允许任何人使用、复制、修改和分发。
  • 要求: 需要保留原作者的版权声明和许可证文本。
  • 适用场景: 适合大多数项目,尤其是希望广泛传播的开源项目。
  1. Apache-2.0: 包括对专利的明确许可,适合开源项目。
  • 特点: 允许使用、复制、修改和分发,包含专利权的条款。
  • 要求: 需要在分发时包含版权声明、许可证文本以及对修改的说明。
  • 适用场景: 适合需要保护专利权的项目,特别是在企业环境中。
  1. GPL-3.0: 强制使用相同许可证分发衍生作品。
  • 特点: 强制性开源,任何派生作品也必须以 GPL 许可证发布。
  • 要求: 如果分发修改版,必须提供源代码,并且保留 GPL 许可证。
  • 适用场景: 适合希望保持软件自由的项目,防止代码闭源。
  1. ISC: 与 MIT 类似,但更简洁。
  • 如果你希望允许用户自由使用、修改和分发,并且希望尽量减少法律限制,可以使用ISC。
"license": "ISC"

要获取许可证文件,可以从从官方网站获取模板手动创建,或者使用 npm init 命令生成,或者复制其他项目的 LICENSE 文件。

author

author 属性用于指定包的作者信息。

"author": {
  "name": "John Doe",
  "email": "john.doe@example.com",
  "url": "https://example.com"
}

contributors

contributors 属性用于指定包的贡献者信息。

"contributors": [
  {
    "name": "Jane Doe",
    "email": "jane.doe@example.com",
    "url": "https://example.com"
  }
]

engines

engines 属性用于指定项目支持的 Node.js 版本。

"engines": {
  "node": ">=14.17"
}

"engines": {
 "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}

packageManager

packageManager 字段用于指定项目所使用的包管理器及其版本。

{ "packageManager": "pnpm@8.0.0" }

publishConfig

publishConfig 属性用于指定发布包时的配置。

"publishConfig": {
  "registry": "https://registry.npmjs.org/",
  "access": "public", // 指定发布的包的访问权限,默认为 "restricted",支持 "public"
  "tag": "latest" // 指定发布的包的标签,默认为 "latest", "latest"、"next"、"beta"、"alpha" 等
}

dependencies

dependencies 属性用于指定项目运行时所需的依赖包。

"dependencies": {
    "boo" : "2.0.1", // 指定特定版本
    "foo": "^2.0.1" // 指定范围版本
    "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0", // 指定范围版本
    "bar": "latest" // 指定最新版本
    "baz": "*" // 指定任何版本
    "thr": "", // 任意版本
    "xyz" : "git+ssh://git@github.com:npm/npm.git#v1.0.27", // git 地址
    "boo": "file:../boo" // 指定本地包
    "boo": "https://github.com/user/boo/archive/v1.0.0.tar.gz" // 指定远程包
    "bar" : ">=1.0.2 <2.1.2", // 指定范围版本

}

peerDependencies

peerDependencies 属性用于指定项目运行时所需的依赖包。

用于指定一个包与另一个包之间的兼容关系。它的主要作用是在安装时确保某个包的特定版本被安装,以避免版本冲突。

当用户安装你的包时,如果项目中没有满足 peerDependencies 的版本,npm 会发出警告,提示用户需要手动安装相关依赖。

  • peerDependencies 不会自动安装依赖。用户需要手动安装满足版本要求的包。

  • 从 npm 7 开始,peerDependencies 会在安装时自动安装相关依赖,但仍然推荐用户自行管理其版本。

  • 适合使用 peerDependencies 的情况包括库和框架的开发,而不适合普通的应用程序开发。

"peerDependencies": {
  "react": "^16.0.0"
}

devDependencies

devDependencies 属性用于指定项目开发时所需的依赖包。

devDependencies有一些包有可能你只是在开发环境中用到,例如你用于检测代码规范的 eslint ,用于进行测试的 jest ,用户使用你的包时即使不安装这些依赖也可以正常运行,反而安装他们会耗费更多的时间和资源,所以你可以把这些依赖添加到 devDependencies 中,这些依赖照样会在你本地进行 npm install 时被安装和管理,但是不会被安装到生产环境。

"devDependencies": {
  "eslint": "^16.0.0"
}

当我们只开发应用,不对外开源的话,包随意放在 dependencies 或 devDependencies 是不影响的,因为被用到的模块不管你再哪个依赖里面都会被打包。

但是如果开发的是库文件,是开源的,已经上传到 npm 仓库的,这个你就得严格区分 dependencies 和 devDependencies 依赖了。因为当你在安装第三方包的时候,只会同步下载第三方包 dependencies 里面的依赖,所以,当你第三方包的某依赖写到 devDependencies 中,被别人下载后没下载到该依赖是会报错运行不了的。

optionalDependencies

某些场景下,依赖包可能不是强依赖的,这个依赖包的功能可有可无,当这个依赖包无法被获取到时,你希望 npm install 继续运行,而不会导致失败,你可以将这个依赖放到 optionalDependencies 中,注意 optionalDependencies 中的配置将会覆盖掉 dependencies 所以只需在一个地方进行配置,不要在两个地方都写。

当然,引用 optionalDependencies 中安装的依赖时,一定要做好异常处理,否则在模块获取不到时会导致报错。

bin

bin 用于指定包中可执行文件的路径。当你安装该包时,npm 会根据这个字段在 node_modules/.bin 目录中创建符号链接,使得这些可执行文件可以直接在命令行中使用。

用法

{
  "name": "your-package",
  "version": "1.0.0",
  "bin": {
    "your-command": "./path/to/your-executable.js"
  }
}

说明:

  • 键: 表示命令的名称,当用户在命令行中运行该命令时使用。
  • 值: 指向可执行文件的相对路径,可以是 JavaScript 文件、Shell 脚本等。

示例

创建 CLI 工具: 如果你在开发一个命令行工具,可以通过 bin 字段指定主命令,例如:


{
  "name": "my-cli",
  "version": "1.0.0",
  "bin": {
    "my-cli": "./bin/cli.js"
  }
}

用户在安装你的包后,可以直接运行 my-cli 命令。

多命令支持: 可以定义多个命令:


{
  "bin": {
    "start": "./bin/start.js",
    "build": "./bin/build.js"
  }
}

注意事项:

  • 在 bin 字段中指定的可执行文件应具有执行权限。
  • 可执行文件应支持在命令行中直接运行,通常第一行应该指向适当的解释器(例如 #!/usr/bin/env node)。
  • 如果 bin 字段未定义,npm 不会创建任何可执行命令。

funding

funding 属性用于指定捐赠信息,帮助用户了解如何支持项目的开发和维护。

"funding": {
  "type": "patreon",
  "url": "https://www.patreon.com/user"
}

说明

  • type: 可选,指示资助的类型,例如 individual、organization 等。
  • url: 指向资助页面的链接,用户可以通过这个链接支持项目。

unpkg

unpkg 是一个公共 CDN,允许用户通过简单的 URL 访问 npm 包中的文件。它直接与 npm 仓库集成,提供 npm 包的内容,而无需单独发布到 unpkg。

unpkg 的工作原理:

  • 开发者在 npm 上发布包,使用命令 npm publish。
  • 发布时,包的内容(如代码、资源等)会存储在 npm 的服务器上。
  • unpkg 会实时访问 npm 的注册表。当用户请求某个包时,unpkg 会根据请求的包名和版本,从 npm 获取相关文件。
  • unpkg 支持访问特定版本或最新版本的文件,例如:
https://unpkg.com/<package-name>@<version>/<path>

例如,访问 lodash 的特定版本:

https://unpkg.com/lodash@4.17.21/lodash.js

如果不指定版本,默认访问最新版本:

https://unpkg.com/lodash/lodash.js

browser

browser 属性用于指定包在浏览器环境下的入口文件。

"browser": "./path/to/browser-entry.js"

说明

  • 当用户在浏览器环境中使用包时,会自动使用指定的文件。
  • 当使用构建工具(如 Webpack 或 Rollup)时,这些工具会优先使用 browser 字段。
  • 如果未指定 browser,npm 会使用 package.json 中的 main 字段。

OS & CPU

"os""cpu" 字段用于指定包或项目支持的操作系统和处理器架构。这些字段可以限制包的安装,确保它只在特定的系统或架构上使用。

{ 
    "os": [ "darwin" ],
    "cpu": [ "arm64" ]
    // 排除某些平台
    "os": [ "!win32" ], "cpu": [ "!x64" ]
}
  • "os": ["darwin"] :这个字段表示该包只能在 macOS(darwin 是 macOS 的操作系统标识符)上安装或运行。如果尝试在其他操作系统(如 Windows 或 Linux)上安装这个包,npm 或 yarn 会报错并拒绝安装。

  • "cpu": ["arm64"] :这个字段表示该包只能在 ARM64 架构的处理器上运行。如果你在其他 CPU 架构(例如 x64)上尝试安装,安装也会失败。