package.json是配置和描述如何与程序交互和运行的中心。 npm CLI(和 yarn)用它来识别你的项目并了解如何处理项目的依赖关系。package.json文件使 npm 可以启动你的项目、运行脚本、安装依赖项、发布到 NPM 注册表以及许多其他有用的任务。 npm CLI 也是管理 package.json 的最佳方法,因为它有助于在项目的整个生命周期内生成和更新package.json文件。

package.json会在项目的生命周期中扮演多个角色,其中某些角色仅适用于发布到 NPM 的软件包。即使你没有把项目发布到 NPM 注册表中,或者没有将其公开发布给其他人,package.json对于开发流程仍然至关重要。

你的项目还必须包含package.json,然后才能从 NPM 安装软件包(npm install xxx)。

创建package.json文件

1. 使用命令行工具

npm init

根据提示配置即可。

请添加图片描述

如果想直接使用默认值生成,可以添加 --yes(-y缩写)标志

npm init -y

从当前目录中提取的信息生成默认值。

2. 手动创建

直接在项目根目录下新建一个package.json文件,按照json格式编写对应字段即可。

参数说明

描述配置项

主要是项目的基本信息,包括名称,版本,描述,仓库,作者等,部分会展示在 npm 官网上。

下图为npm官网上的react库展示:

请添加图片描述

如果打算把这个项目发布到npm中,最重要的两个字段就是 nameversion,它们都是必须的,如果没有,就无法正常执行 npm install 命令。npm 规定 package.json 文件是由名称和版本号作为唯一标识符的。

name

包的名称。它在 URL 中使用,在命令行中作为参数,并作为项目中node_modules目录下的目录名称。

https://registry.npmjs.org/[name]/-/[name]-[version].tgz

node_modules/[name]

npm install [name]

命名规范:

  • 名称必须小于或等于 214 个字符。
  • 名称不能以._开头。
  • 新包的名称中不得包含大写字母。
  • 该名称最终成为 URL 的一部分、命令行上的参数和文件夹名称。因此,名称不能包含任何非 URL 安全字符。

注意:如果要发布在npm上,名称不能和其他模块的名称重复。在发布前可以通过npm view 命令查询模块名是否重复,如果不重复就会提示 404,如果不打算发布在npm上,name字段不重要,不会影响项目的正常运行

npm view react

请添加图片描述

npm view qwdnioqwnigwudqhwdqw 提示404

请添加图片描述

version

项目版本号,开源项目的版本号通常遵循 semver 语义化规范。

可以通过以下命令来查看 npm 包的版本信息

// 查看最新版本号
npm view xxx version

// 查看所有版本
npm view xxx versions
description

可选字段,必须是字符串。当前包的描述信息,是一个字符串。它可以帮助开发者在使用npm搜索时找到这个包。

如果 package.json 中没有 description 信息,npm 使用项目中的 README.md 的第一行作为描述信息。这个描述信息有助于别人搜索你的项目。

keywords

一个字符串数组,其作用与描述相似。 NPM 注册表会为该字段建立索引,能够在搜索软件包时帮助找到它们。数组中的每个值都是与程序包关联的一个关键字。

repository

项目的仓库地址以及版本控制信息。

"repository": {
  "type": "git",
  "url": "https://github.com/xxx.git",
  "directory": "xxx"
}
homepage

项目主页的链接,通常是项目 github 链接,项目官网或文档首页。

bugs

项目 bug 反馈地址,通常是 github issue 页面的链接。

"bugs": "https://xxxx/issues"
author

项目作者,有两种形式:

  1. 字符串格式
"author": "XXX <xxxxx@xx.com> (https://XXX)"
  1. 对象
"author": {
  "name" : "xxx",
  "email" : "xxxxx@xx.com",
  "url" : "https://xxx"
}

emailurl可选。

contributors

项目贡献者,数组类型。格式与author类似

// 字符串格式
"contributors": [
	"XXX <xxxxx@xx.com> (https://XXX)",
	"XXX <xxxxx@xx.com> (https://XXX)"
]

// 对象格式
"contributors": [
	{
  		"name" : "xxx",
		"email" : "xxxxx@xx.com",
  		"url" : "https://xxx"
	},
	{
  		"name" : "xxx",
  		"email" : "xxxxx@xx.com",
  		"url" : "https://xxx"
	}
]
funding

赞助商

有两种方式:字符串 和 包含 typeurl 的 对象 或者多个赞助商的数组。可以通过 npm fund <projectName> 进行查看

{

{
  "funding": {
    "type" : "individual",
    "url" : "http://example.com/donate"
  },
  "funding": {
    "type" : "patreon",
    "url" : "https://www.patreon.com/my-account"
  },
  "funding": "http://example.com/donate",
  "funding": [
    {
      "type" : "individual",
      "url" : "http://example.com/donate"
    },
    "http://example.com/donateAlso",
    {
      "type" : "patreon",
      "url" : "https://www.patreon.com/my-account"
    }
  ]
}
license

项目的开源许可证。项目的版权拥有人可以使用开源许可证来限制源码的使用、复制、修改和再发布等行为。

文件配置项

main

项目入口文件,通常是用于启动项目的文件。在 browserNode 环境中都可以使用。如果我们将项目发布为 npm 包,那么当使用 require 导入 npm 包时,返回的就是 main 字段所列出的文件的 module.exports 属性。

默认值是模块根目录下面的index.js

比如packageAmain 字段指定为 index.js,当通过import或者require引入packageA时实际引入为node_modules/packageA/index.js

files

项目在进行 npm 发布时,可以通过 files 指定需要跟随一起发布的内容来控制 npm 包的大小,避免安装时间太长。

文件模式遵循与 .gitignore 类似的语法,无论如何设置都会始终包含和忽略某些文件
包含文件:

  • package.json
  • README
  • CHANGES / CHANGELOG / HISTORY
  • LICENSE / LICENCE
  • NOTICE
  • main 字段对应的文件

忽略文件:

  • .git
  • CVS
  • .svn
  • .hg
  • .lock-wscript
  • .wafpickle-N
  • …swp*
  • .DS_Store
  • ._*
  • .npmrc
  • npm-debug.log
  • node_modules
  • config.gypi
  • *.orig
  • package-lock.json

通过files字段可以指定更多需要一起发布的内容。可以是单独的文件,整个文件夹,或者使用通配符匹配到的文件。

"files": [
  "xxx.js",
  "xxx/",
  "xxx/*.{js,css}"
 ]
type

值为'module'则当作es模块处理;

// 使用 ES 模块规范
node index.js

值为'commonjs'则被当作commonJs模块处理,如果没有定义则默认commonJs规范处理。

当未设置type时,js文件按照commonjs规范解析,import方式会报错。
在这里插入图片描述
type设置成module,就是使用ES模块方式加载,require方式会报错

在这里插入图片描述

不管type定义什么值,.mjs的文件都按照es模块来处理,.cjs的文件都按照commonJs模块来处理。不过两种模块规范最好不要混用,会产生异常报错。

browser

main 字段里指定的入口文件在 browserNode 环境中都可以使用。如果只想在 web 端使用,不允许在 server 端使用,可以通过 browser 字段指定入口。

module

指定 ES 模块的入口文件。

"main": "./index.js", 
"browser": "./browser/index.js",
"module": "./index.mjs"
exports

node14.13 支持在 package.json 里定义 exports 字段,拥有了条件导出的功能。

exports 字段可以配置不同环境对应的模块入口文件,并且当它存在时,它的优先级最高。

比如使用 requireimport 字段根据模块规范分别定义入口:

"exports": {
  "require": "./index.js",
  "import": "./index.mjs"
 }
}

这样的配置在使用 import 'xxx'require('xxx') 时会从不同的入口引入文件,exports 也支持使用 browsernode 字段分别对应 browserNode 环境中的入口。

上方的写法其实等同于:

"exports": {
  ".": {
    "require": "./index.js",
    "import": "./index.mjs"
  }
 }
}

为什么要加一个层级,把 requireimport 放在 "." 下面呢?

因为 exports 除了支持配置包的默认导出,还支持配置包的子路径。

比如一些第三方 UI 包需要引入对应的样式文件才能正常使用。

import `packageA/dist/css/index.css`;

我们可以使用 exports 来封装文件路径:

"exports": {
  "./style": "./dist/css/index.css'
},

用户引入时只需:

import `packageA/style`;

除了对导出的文件路径进行封装,exports 还限制了使用者访问未在 "exports" 中定义的任何其他路径。

比如发布的 dist 文件里有一些内部模块 dist/internal/module ,被用户单独引入使用的话可能会导致主模块不可用。为了限制外部的使用,我们可以不在 exports 定义这些模块的路径,这样外部引入 packageA/dist/internal/module 模块的话就会报错。

结合上面入口文件配置的知识,再来看看下方 vite 官网推荐的第三方库入口文件的定义,就很容易理解了。

workspaces

项目的工作区配置,用于在本地的根目录下管理多个子项目。可以自动地在 npm install 时将 workspaces 下面的包,软链到根目录的 node_modules 中,不用手动执行 npm link 操作

workspaces 字段接收一个数组,数组里可以是文件夹名称或者通配符。比如:

"workspaces": [
  "workspace-a"
]

表示在 workspace-a 目录下还有一个项目,它也有自己的 package.json

package.json

workspace-a
  └── package.json

通常子项目都会平铺管理在 packages 目录下,所以根目录下 workspaces 通常配置为:

"workspaces": [
  "packages/*"
]

脚本配置项

script

指定项目的一些内置脚本命令,这些命令可以通过 npm run 来执行。

"script": {
    "start": "node index.js"
}

可以使用npm run start 或者 yarn start 运行,当执行npm run start的时候,自动创建了一个Shell,在这个Shell里面执行指定node index.js命令。

config

config 用于设置 scripts 里的脚本在运行时的参数。比如设置 port8080

"config": {
  "port": "8080",
  "xxx": "xxxx"
}

可以在执行脚本中通过process.env.npm_package_config_port(npm_package_config_xxx)进行访问。

依赖配置项

项目可能会依赖其他包,需要在 package.json 里配置这些依赖的信息。

dependencies

运行依赖,也就是项目生产环境下需要用到的依赖。比如 reactvue,状态管理库以及组件库等。

使用 npm install xxx 或则 npm install xxx --save 时,会被自动插入到该字段中。

"dependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0"
}
devDependencies

开发依赖,项目开发环境需要用到而运行时不需要的依赖,用于辅助开发,通常包括项目工程化工具比如 webpackviteeslint 等。

使用 npm install xxx -D 或者 npm install xxx --save-dev 时,会被自动插入到该字段中。

"devDependencies": {
  "webpack": "^5.69.0"
}
peerDependencies

同伴依赖,一种特殊的依赖,不会被自动安装,通常用于表示与另一个包的依赖与兼容性关系来警示使用者。

比如我们安装 A,A 的正常使用依赖 B@2.x 版本,那么 B@2.x 就应该被列在 A 的 peerDependencies 下,表示“如果你使用我,那么你也需要安装 B,并且至少是 2.x 版本”。

比如 React 组件库 Ant Design,它的 package.json 里 peerDependencies 为

"peerDependencies": {
  "react": ">=16.9.0",
  "react-dom": ">=16.9.0"
}

表示如果你使用 Ant Design,那么你的项目也应该安装 reactreact-dom,并且版本需要大于等于 16.9.0。

optionalDependencies

可选依赖,顾名思义,表示依赖是可选的,它不会阻塞主功能的使用,安装或者引入失败也无妨。这类依赖如果安装失败,那么 npm 的整个安装过程也是成功的。

比如我们使用 colors 这个包来对 console.log 打印的信息进行着色来增强和区分提示,但它并不是必需的,所以可以将其加入到 optionalDependencies,并且在运行时处理引入失败的逻辑。

使用 npm install xxx -O 或者 npm install xxx --save-optional 时,依赖会被自动插入到该字段中。

“optionalDependencies”: {
“colors”: “^1.4.0”
}

peerDependenciesMeta

同伴依赖也可以使用 peerDependenciesMeta 将其指定为可选的。

“peerDependencies”: {
“colors”: “^1.4.0”
},
“peerDependenciesMeta”: {
“colors”: {
“optional”: true
}
}

bundleDependencies

打包依赖。它的值是一个数组,在发布包时,bundleDependencies 里面的依赖都会被一起打包。

比如指定 reactreact-dom 为打包依赖:

“bundleDependencies”: [
“react”,
“react-dom”
]

在执行 npm pack 打包生成tgz 压缩包中,将出现 node_modules 并包含 reactreact-dom

需要注意的是,这个字段数组中的值必须是在 dependenciesdevDependencies 两个里面声明过的依赖才行。

普通依赖通常从 npm registry 安装,但当你想用一个不在 npm registry 里的包,或者一个被修改过的第三方包时,打包依赖会比普通依赖更好用。

overrides

overrides 可以重写项目依赖的依赖,及其依赖树下某个依赖的版本号,进行包的替换。

比如某个依赖 A,由于一些原因它依赖的包 foo@1.0.0 需要替换,我们可以使用 overrides 修改 foo 的版本号:

“overrides”: {
“foo”: “1.1.0-patch”
}

当然这样会更改整个依赖树里的 foo,我们可以只对 A 下的 foo 进行版本号重写:

“overrides”: {
“A”: {
“foo”: “1.1.0-patch”,
}
}

overrides 支持任意深度的嵌套。

如果在 yarn 里也想复写依赖版本号,需要使用 resolution 字段,而在 pnpm 里复写版本号需要使用 pnpm.overrides 字段。

发布配置项

主要是和项目发布相关的配置。

private

如果是私有项目,不希望发布到公共 npm 仓库上,可以将 private 设为 true

publishConfig

npm 包发布时使用的配置。

比如在安装依赖时指定了 registrytaobao 镜像源,但发布时希望在公网发布,就可以指定 publishConfig.registry

"publishConfig": {
  "registry": "https://registry.npmjs.org/"
}

系统配置项

和项目关联的系统配置,比如 node 版本或操作系统兼容性之类。这些要求只会起到提示警告的作用,即使用户的环境不符合要求,也不影响安装依赖包。

engines

一些项目由于兼容性问题会对 node 或者包管理器有特定的版本号要求,比如:

"engines": {
  "node": ">=14 <16",
  "pnpm": ">7"
}

要求 node 版本大于等于 14 且小于 16,同时 pnpm 版本号需要大于 7。

os

linux 上能正常运行的项目可能在 windows 上会出现异常,使用 os 字段可以指定项目对操作系统的兼容性要求。

"os": ["darwin", "linux"]

在操作系统前加一个!可以禁止该系统运行项目

"os": [!"win32"]
cpu

指定项目只能在特定的 CPU 体系上运行。

"cpu": ["x64", "ia32"]

os一样加!也可以禁止某CPU

"cpu": ["!arm"]
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐