概述
在一个 JavaScript 项目中,package.json
是一个必须的文件,它的作用是管理项目中使用到的外部依赖包,同时它也是 NPM 命令的入口文件。
package.json
包含描述一个特定程序包唯一的设置所需的所有内容。
如果项目使用工作空间功能,则项目将包含多个
package.json
文件,因为每个工作空间都是通过其自己的package.json
来描述的。请注意,可以通过
initFields
字段设置来设置这些字段的默认值。
????name
package.json
中最重要的属性是 name
和 version
两个属性,这两个属性是必须要有的,否则模块就无法被安装,这两个属性一起形成了一个 npm 模块的唯一标识
name
是 package(包)的名称。名称的第一部分(如@scope/
是可选的,用作名称空间)。
当我们的包发布到 NPM 网站,其他人才能通过搜索name
来安装使用
{
"name": "@scope/name"
}
name 规范
- 最好取简短而语义化的值
- 不能以
,
.
开头 - 不能有大写字母/空格/下滑线!
- 不能和 NPM 网站中已有的包名字重名!
????version
version
是 package(包)的版本,通常,它不会对你的项目产生任何影响,
除非它是一个工作空间(workspaces)-其版本必须与指定的范围相匹配,才能选择该工作空间作为解决方案的候选对象。
当我们的包有了新的迭代,并需要发布到 NPM 网站时,必须升级此版本号才能正常发布
{
"version": "1.2.3"
}
version 规范
version
具体体现为::“x.y.z”
- 修复 bug,小改动,增加 z
- 增加了新特性,但仍能向后兼容,增加 y
- 有很大的改动,无法向后兼容,增加 x
详细内容参考语义化版本 2.0.0
使用 npm version <update_type>
自动升级版本号
update_type
为patch
, minor
, major
其中之一,分别表示补丁
,小改
,大改
npm version patch
npm version minor
npm version major
在 CI(持续集成)的脚本中可以用到此命令
????description
一个描述,方便别人了解你的模块作用,搜索的时候也有用。
{
"description": "An enterprise-class UI design language and React components implementation"
}
????keywords
一个字符串数组,方便别人搜索到本模块
{
"keywords": [
"ant",
"component",
"components",
"design",
"framework",
"frontend",
"react",
"react-component",
"ui"
]
}
当我们使用 npm
检索模块时,会对模块中的 description
字段和 keywords
字段进行匹配,写好 package.json
中的 description
和 keywords
将有利于增加我们模块的曝光率。
????homepage
项目主页 url
,默认值为/
一般来说,我们打包的静态资源会部署在 CDN
上,为了让我们的应用知道去哪里加载资源,则需要我们设置一个根路径,这时可以通过 package.json
中的 homepage
字段设置应用的根路径。
{
"homepage": "https://ant.design"
}
????bugs
填写一个 bug 提交地址或者一个邮箱,被你的模块坑到的人可以通过这里吐槽,例如:
{
"bugs": {
"url": "https://github.com/ant-design/ant-design/issues"
}
}
????license
你应该为你的开源代码模块制定一个开源协议,让用户知道他们有何权限来使用你的模块,以及使用该模块有哪些限制
MIT
是最少约束的选择。GPL
是最多约束的。
如果是个人随意作品,建议 MIT
许可。如果是公司或者需要严格保护的开源产品,GPL
。
{
"license": "MIT"
}
详细内容参考
- 如何选择开源许可证?阮一峰
- 各种开源协议介绍
- Simple description of popular software licenses
???? 和用户相关的属性: author, contributors
{
"author": "某某技术公司",
"contributors": ["小王", "小李", "校长"]
}
???? funding
在开源领域,资金是一个长期存在的问题.
funding
命令的作用是让维护 npm 的开发人员(为 Node.js 创建包)声明元数据,为有意愿的捐赠者指明捐赠平台。
在 package.json
文件中添加了一个funding
字段, 可指向在线捐赠服务的 url,如 Patreon
、Open Collective
、GitHub Sponsors
、License Zero
或者其他支付网站。
{
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/ant-design"
}
}
????files
描述了将软件包作为依赖项安装时要包括的条目,默认值为[“*”]
,这意味着它将包括所有文件。
如果需要把打包后的代码也发布到 NPM 仓库
{
"files": ["dist/**/*", "lib/**/*"]
}
你还可以在包的根目录或子目录中提供.npmignore
文件,以防止某些文件被发布。
.npmignore
文件的工作原理与.gitignore
一样。
如果存在.gitignore
文件,而缺少.npmignore
,则将改用.gitignore
的内容。
files
字段内容会覆盖.npmignore
和.gitignore
的内容。
????main
main
字段是 package.json
中的另一种元数据功能,它可以用来指定加载的入口文件。
假如你的项目是一个 npm
包,当用户安装你的包后,require('my-module')
返回的是 main
字段中所列出文件的 module.exports
属性。
当不指定main
字段时,默认值是模块根目录下面的 index.js 文件。
{
"main": "lib/index.js"
}
????browserslist
指定该模板供浏览器使用的版本。Browserify 这样的浏览器打包工具,通过它就知道该打包那个文件。
{
"browserslist": [
"> 0.5%",
"last 2 versions",
"Firefox ESR",
"not dead",
"IE 11",
"not IE 10"
]
}
????bin
用于将某些可执行 Javascript 文件公开给父包的字段。 此处列出的所有条目都可以通过$ PATH
获得。
通俗点理解就是我们全局安装, 我们就可以在命令行中执行这个文件, 本地安装我们可以在当前工程目录的命令行中执行该文件。
"bin": {
"my-bin": "./dist/my-bin.js",
}
dist/my-bin.js
#!/usr/bin/env node
console.log("cool");
????repository
{
"repository": {
"type": "git",
"url": "https://github.com/ant-design/ant-design"
}
}
????scripts
该字段用于列出在运行 yarn run
时将要执行的小型 shell 脚本。
请注意,包含:(冒号)的脚本是项目的全局变量,无论你当前的工作空间如何,都可以调用它们。
最后,请注意,脚本总是相对于最近的工作空间(而不是 cwd)执行。
"scripts": {
"test": "jest",
"build:dev": "webpack-cli --config ./webpack.dev.config.js",
"build:test": "webpack-cli --config ./webpack.test.config.js",
"build:pro": "webpack-cli --config ./webpack.pro.config.js"
}
NPM 脚本的原理
npm
脚本的原理非常简单。每当执行 npm run
,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。
比较特别的是,npm run
新建的这个 Shell,会将当前目录的 node_modules/.bin
子目录加入 PATH
变量,执行结束后,再将 PATH
变量恢复原样。
这意味着,当前目录的 node_modules/.bin
子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha
,只要直接写 mocha test
就可以了。
"test": "mocha test"
而不用写成下面这样。
"test": "./node_modules/.bin/mocha test"
由于 npm
脚本的唯一要求就是可以在 Shell 执行,因此它不一定是 Node 脚本,任何可执行文件都可以写在里面。
npm
脚本的退出码,也遵守 Shell 脚本规则。如果退出码不是0
,npm
就认为这个脚本执行失败。
????config
{
"name": "foo",
"config": {
"port": "8080"
}
}
当执行npm start
命令,就会引用 npm_package_config_port
环境变量,
如上面的配置npm start
时,就会通过端口8080
启动
但是用户可以通过执行例如 npm config set foo:port 8001
来覆盖config
配置。
????dependencies
应用依赖,或者叫做业务依赖/生产环境依赖,这是我们最常用的依赖包管理对象!它用于指定应用依赖的外部包,这些依赖是应用发布后正常执行时所需要的,但不包含测试时或者本地打包时所使用的包
{
"dependencies": {
"react": "^16.9.0",
"react-dom": "^16.9.0"
}
}
放置生产环境依赖包的地方,即执行项目的 npm run build
时需要的依赖包。因此不要把开发环境的依赖包放在这里,比如
- eslint
- typesctipt
- webpack-dev-server
- ……
因为会增加生产环境安装依赖的时间
????devDependencies
与dependencies
字段类似,但这些依赖项仅在本地开发环境中安装,而不会由软件包的使用者(生产环境)安装。
开发环境依赖,仅次于dependencies的使用频率!它的作用和dependencies一样,只不过它里面的包只用于开发环境,不用于生产环境,这些包通常是单元测试或者打包工具等,例如gulp, webpack, moca等
{
"devDependencies": {
"webpack": "^4.40.2",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.1"
}
}
放置开发环境依赖包的地方,即执行项目的 npm start
时需要的依赖包。因此不要把生产环境的依赖包放在这里
????peerDependencies
peerDependencies 的目的是提示宿主环境去安装满足插件 peerDependencies 所指定依赖的包,然后在插件 import 或者 require 所依赖的包的时候,永远都是引用宿主环境统一安装的 NPM 包,最终解决插件与所依赖包不一致的问题。
举个例子,ant-design UI 组件库要求宿主环境安装指定的 React 版本。具体可以看它的 package.json配置
{
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
}
????optionalDependencies
除非你依赖于 fsevents
软件包,否则通常不需要此字段。
如果仅在使用特定功能时才需要包,请使用可选的对等依赖项。
{
"optionalDependencies": {
"fsevents": "^5.0.0"
}
}
????engines
engines
字段指明了该模块运行的平台,比如 Node 的某个版本或者浏览器
该字段也可以指定适用的 npm 版本。
{
"engines": {
"node": ">=12.18.3",
"npm": ">7.0.0"
}
}
????private
如果为 true
,则该程序包被视为私有程序,Yarn/NPM
会在任何情况下均拒绝发布该程序包。这防止私人存储库意外发布
{
"private": true
}
????publishConfig
此字段包含各种设置,仅当从本地来源生成包时才考虑这些设置(通过 yarn pack 或像 yarn npm publish 这样的发布命令之一)。
publishConfig.access
定义将程序包发布到 npm 注册表时要使用的程序包访问级别。 有效值是公开的并且是受限制的,但是受限制的通常需要注册付费计划(这取决于你使用的注册表)。
publishConfig.bin
如果存在,则在打包打包以将其运送到远程注册表之前,清单中的顶级 bin 字段将被设置为此新值。 这不会修改真正的清单,只会修改存储在 tarball 中的清单。
publishConfig.browser
与publishConfig.bin
属性的原理相同; 生成工作空间 tarball 时,将使用此值代替顶级浏览器字段。
publishConfig.executableFiles
默认情况下,出于可移植性的原因,在 bin 字段中列出的文件之外的文件都不会在结果包归档文件中标记为可执行文件。 executeFiles 字段使你可以声明必须设置了可执行标志(+ x)的其他字段,即使不能通过 bin 字段直接访问它们也是如此。
publishConfig.main
与publishConfig.bin
属性相同的原理; 生成工作空间 tarball 时,将使用此值代替顶级“ main”字段。
publishConfig.module
与publishConfig.bin
属性相同的原理; 生成工作空间 tarball 时,将使用此值代替顶级“ module”字段。
publishConfig.registry
如果存在,当将包推送到远程位置时,将替换配置中定义的任何注册表。
可能的值
- https://registry.npmjs.org/
- https://npm.pkg.github.com
{
"publishConfig": {
"access": "public",
"bin": "./build/bin.js",
"browser": "./build/browser.js",
"executableFiles": ["./dist/shim.js"],
"main": "./build/index.js",
"module": "./build/index.mjs",
"registry": "https://npm.pkg.github.com"
}
}
????workspaces
工作区是 monorepos
用来将一个大型项目拆分为半独立子项目的一项可选功能,每个子项目都列出了自己的一组依赖关系。 工作区字段是全局模式列表,这些模式与应成为应用程序工作区的所有目录匹配。
{
"workspaces": ["packages/*"]
}
????type
可能的值
commonjs
(默认值),适用于 Node.js 环境(服务端)module
,即 ES Module 语法,适用于浏览器环境(客户端)
无论使用什么值,当使用
PnP
时,Yarn 3+
都会生成一个.pnp.cjs
文件。
{
"type": "commonjs"
}
main
字段通常用于指向 UMD 版本的库/包,一般指定为 webpack/rollup 打包 UMD 版本后的路径
UMD 是什么呢?
- CommonJS + AMD 的组合(即 CommonJS 的语法 + AMD 的异步加载)
- 可以用于 AMD/CommonJS 环境
- UMD 还支持全局变量定义。因此,UMD 模块能够在 客户端和服务器 上工作。
main
字段还可以在发布时通过使用 publishConfig.main
字段来修改。
????module
与 ES6 兼容的环境尝试通过其名称访问程序包时将使用的路径。
module
字段用于指向 ES 版本的库/包,一般指定为 webpack/rollup 打包 ES 版本后的路径
{
"module": "es/index.js"
}
????unpkg
unpkg
是一个内容源自 npm 的全球快速 CDN
配置unpkg
字段后,发布到 npmjs.com
中的包会自动同步到 unpkg.com 上,一般为 umd 格式。
{
"unpkg": "dist/antd.min.js"
}
????typings
{
"typings": "lib/index.d.ts"
}
????sideEffects
与 webpack 相关的字段,声明该模块是否包含 sideEffects
(副作用),从而可以为 tree-shaking
提供更大的优化空间。
{
"sideEffects": ["dist/*", "es/**/style/*", "lib/**/style/*", "*.less"]
}
参考文档
- yarn 官方文档
- NPM 官方文档
最后
本文介绍了 package.json
的多种常见的配置字段及作用,并通过例子加深大家对 package.json
这些字段的理解。
以上内容如有遗漏错误,欢迎留言 ✍️ 指出,一起进步 ????????????
如果觉得本文对你有帮助,请留下你宝贵的 ????
最后
以上就是勤奋裙子为你收集整理的前端开发者需要知道的 package.json的全部内容,希望文章能够帮你解决前端开发者需要知道的 package.json所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复