所谓包的说明文件,也就是 package.json,当我们使用 npm init 去初始化一个项目的时候,就会自动的生成一个package.json 文件。
关于 package.json,官网是有详细的配置项说明的:https://docs.npmjs.com/cli/v9/configuring-npm/package-json
包的说明信息相关的配置
-
name:包的名字,必须是唯一的
-
version:包的版本号,一般由三个数字组成,格式为 x.y.z
- x 代表主版本号(Major Version),一般是你的软件包发生了重大变化或者不兼容的升级,那么需要增加主版本号
- y 代表次版本号(Minor Version),当你的软件包增加了新的功能或者新的特性,需要增加次版本号
- z 代表修订号(Patch Version),当你的软件包进行 bug 的修复,性能的优化,较小的改动,需要增加修订号
-
description:包的描述信息
-
keyword:包的关键词,用于搜索和分类的
{...keyword: ['good', 'tools']
}
- author:作者信息
"author": {"name": "John Doe","email": "john.doe@example.com","url": "https://example.com/johndoe"
}
- contributors:包的贡献者名单
- license:包的许可证信息,指定包的开源类型
- repository:包的源代码仓库信息,可以再提供一个 git 地址
"repository": {"type": "git","url": "https://github.com/username/my-awesome-package.git"
}
- engines:用来指定项目需要的 node 版本以及 npm 版本,从而避免用户在使用你的包的时候出现一些因为版本不支持而产生的问题。
"engines": {"node": ">=12.0.0","npm": ">=6.0.0"
},
包执行相关配置
-
main:代表包的入口文件
-
browser:该选项表示如果是在浏览器环境下,可以替换一些特定模块或者文件。
- 指定浏览器的入口文件
{"main": "index.js","browser": "browser.js" }
上面的配置表面在 node 环境下,index.js 为入口文件,如果是浏览器环境,使用 browser.js 作为入口文件
- 替换特定的模块
{"browser": {"./node-version.js": "./browser-version.js"} }
- 排除某些模块
{"browser": {"fs": false} }
-
scripts:配置你的可执行命令
"scripts": {"start": "node index.js","test": "jest","build": "webpack","lint": "eslint src","format": "prettier --write src" }
脚本是可以配置生命周期钩子方法,使用到的关键词为 pre 和 post,pre 代表在执行某个脚本之前,post 代表在执行某个脚本之后
"scripts": {"prestart": "npm run build","start": "node index.js","test": "mocha","build": "webpack","lint": "eslint src","format": "prettier --write src","posttest": "npm run lint && npm run format" }
- prestart:代表在执行 start 之前,先运行 build
- posttest:代表在执行了 test 之后,同时运行 lint 以及 format
包的依赖信息相关配置
-
dependencies:包的依赖列表,最终打包的时候,是会将这一部分依赖打包进去。比如你的项目用到了 lodash,最终你对项目进行打包的时候,你就应该把 lodash 打包进去,所以 lodash 就应该记入到 dependencies
-
devDependencies:这个代表开发依赖,开发的时候我会用到,但是最终打包的时候不需要打包进去,webpack、eslint、typescript、sass,这一部分依赖就应该记入到 devDependencies
-
控制依赖版本的范围:有一些符号(^ ~)是专门用来控制依赖的版本范围的,这些符号用来指定依赖在更新的时候能够更新的范围
- (脱字符):表示允许更新到相同主版本号的最新版本,也就是说次版本可以变,补丁版本可以变,但是主版本不能变。举个例子:1.2.3 更新的时候,允许的范围就是 >= 1.2.3 且 < 2.0.0
- ~(波浪字符):表示主版本号和次版本号都必须相同,也就是说能够更新的只有补丁号。举个例子:~1.2.3 更新的时候,允许的范围为 >= 1.2.3 且 < 1.3.0
- 关于版本范围的符号,其实远远不止上面两个,这个是有一套详细规则,可以参阅:https://docs.npmjs.com/cli/v9/configuring-npm/package-json#dependencies
-
peerDependencies:该配置项通常用于开发插件或者库的时候,表示需要与项目(这里的项目指的是使用我们插件或者库的项目)一起使用的依赖,确保这些依赖有一个合适的版本。
- 假设你现在在开发一个 react 插件,你在开发 react 的时候肯定会涉及到使用 react 的环境,如果此时你将 react 记入到 dependencies,那么则意味着别人项目在使用你的插件的时候,也会去下载 react。这里就会存在两个问题
- 别人既然使用你这个插件,那么说明别人也是在做 react 的开发,别人的项目自然而然已经安装了react
- 如果不记入到 dependencies 里面,那么又会存在因为版本不一致可能出现的兼容问题
- peerDependencies 就是用来解决这个问题,例如我现在在开发一个 react 的插件,用到了 react 以及 react-dom
{"name": "my-react-plugin","version": "1.0.0","peerDependencies": {"react": "^17.0.0","react-dom": "^17.0.0"} }
回头别人在使用你这个插件的时候,它就必须确保安装符合版本要求的依赖。否则 npm 是会给出警告。
讲到这里,有的同学会有这样的疑问,我在开发插件的时候,直接将所有用到的依赖全部声明为 peerDependencies,如果你这么做,则意味着用户在使用你这个插件的时候,用户需要手动的去安装众多的依赖,假设你的插件有几十个依赖,那么用户就需要手动的去安装几十个依赖,这显然也是不合适的。
因此 peerDependencies 只会记入一个插件的主要依赖(angular、react、vue)。
下面有一些建议,可以帮助你做出决策:
- 考虑你的插件的目标受众。如果你认为大部分使用你插件的项目都已经在使用你所依赖的库(例如 lodash),那么将这些库声明为 peerDependencies 可能是合适的。
- 考虑插件与依赖项之间的紧密程度。如果你的插件仅依赖于依赖项的一个小功能,而且这个功能在未来版本中不太可能发生变化,那么你可以将这个依赖项声明为 dependencies。
- 如果你决定将某些库声明为 peerDependencies,请确保在插件的文档中明确提醒用户需要安装这些库。
- 假设你现在在开发一个 react 插件,你在开发 react 的时候肯定会涉及到使用 react 的环境,如果此时你将 react 记入到 dependencies,那么则意味着别人项目在使用你的插件的时候,也会去下载 react。这里就会存在两个问题