package.json 详解(转载)

Node 项目在项目根目录中名为 package.json 的文件中跟踪依赖关系和元数据。这是你项目的核心。它包含名称、描述和版本之类的信息,以及运行、开发以及有选择地将项目发布到 NPM 所需的信息。
在本教程中,我们将:

  • 了解 package.json 与项目之间的关系
  • 确定重要字段和元数据
  • 了解如何管理 package.json

目标

了解什么是 package.json 文件,它与你项目的关系以及需要了解的常见属性。

了解 package.json

如果你以前用过 Node.js,则可能会遇到 package.json 文件。它是一个 JSON 文件,位于项目的根目录中。你的 package.json 包含关于项目的重要信息。它包含关于项目的使人类可读元数据(如项目名称和说明)以及功能元数据(如程序包版本号和程序所需的依赖项列表)。

package.json 示例如下所示:

{
  "name": "my-project",
  "version": "1.5.0",
  "description": "Express server project using compression",
  "main": "src/index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon",
    "lint": "eslint **/*.js"
  },
  "dependencies": {
    "express": "^4.16.4",
    "compression": "~1.7.4"
  },
  "devDependencies": {
    "eslint": "^5.16.0",
    "nodemon": "^1.18.11"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/osiolabs/example.git"
  },
  "author": "Jon Church",
  "contributors": [
    {
      "name": "Amber Matz",
      "email": "example@example.com",
      "url": "https://www.osiolabs.com/#team"
    }
  ],
  "keywords": [
    "server",
    "osiolabs",
    "express",
    "compression"
  ]
}

package.json 的用途是什么?

项目的 package.json 是配置和描述如何与程序交互和运行的中心。 npm CLI(和 yarn)用它来识别你的项目并了解如何处理项目的依赖关系。package.json 文件使 npm 可以启动你的项目、运行脚本、安装依赖项、发布到 NPM 注册表以及许多其他有用的任务。 npm CLI 也是管理 package.json 的最佳方法,因为它有助于在项目的整个生命周期内生成和更新 package.json 文件。
package.json 会在项目的生命周期中扮演多个角色,其中某些角色仅适用于发布到 NPM 的软件包。即使你没有把项目发布到 NPM 注册表中,或者没有将其公开发布给其他人,那么 package.json 对于开发流程仍然至关重要。
你的项目还必须包含 package.json,然后才能从 NPM 安装软件包。这可能是你在项目中需要它的主要原因之一。

package.json 中的常见字段

让我们看一下 package.json 中包含的一些最常见和重要的字段,以更好地了解如何使用和管理这个基本文件。有些用来发布到 NPM,而其他一些则可以帮助 npm CLI 运行应用程序或安装依赖项。

实际的字段比我们所介绍的要多,你可以在它的文档中了解其余字段,但以下的是必须要了解的 package.json 属性。

name

package.json 中最重要的属性是 nameversion 两个属性,这两个属性是必须要有的,否则模块就无法被安装,这两个属性一起形成了一个 npm 模块的唯一标识。

name是 package(包)的名称。名称的第一部分(如@scope/是可选的,用作名称空间)。当我们的包发布到 NPM 网站,其他人才能通过搜索name来安装使用

{
  "name": "@scope/name"
}

name 规范

  • 最好取简短而语义化的值
  • 不能以,.开头
  • 不能有大写字母/空格/下滑线!
  • 不能和 NPM 网站中已有的包名字重名!

version

version是 package(包)的版本,通常,它不会对你的项目产生任何影响,

除非它是一个工作空间(workspaces)-其版本必须与指定的范围相匹配,才能选择该工作空间作为解决方案的候选对象。

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": "xxxx"
}

keywords

一个字符串数组,方便别人搜索到本模块

{
  "keywords": [
    "ant",
    "component",
    "design"
  ]
}

当我们使用 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"
}

详细内容参考

和用户相关的属性: author, contributors

{
  "author": "iikonan",
  "contributors": [
    "zhangsan",
    "lisi"
  ]
}

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如果存在,当将包推送到远程位置时,将替换配置中定义的任何注册表。

可能的值

{
  "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"]
}



作者:ikonan
链接:https://www.jianshu.com/p/c86d511d99fd
来源:简书

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值