package.json 的剖析
如果您使用 JavaScript 代码,那么在每个项目中都会遇到一个package.json
文件。每次运行npm install
或yarn
那些包管理器时,都会查看该文件并获取所需的依赖项。然而,这些文件中充满了宝贵的信息和强大的功能,让我们深入了解一下!
我们将以这个例子作为参考点。
{
"name": "example-package",
"description": "A package that does a thing",
"version": "1.0.0",
"author": "laurieontech",
"repository": {
"type": "git",
"url": "https://github.com/some-project-here"
},
"dependencies": {
"react": "16.8.6"
},
"devDependencies": {
"prettier": "^1.18.2"
},
"keywords": ["react"],
"license": "MIT",
"main": "index.js",
"scripts": {
"test": "jest"
},
"bin": "./bin/executable.js"
}
元数据
中的前几项package.json
是描述性的。description
、repository
和author
(contributors
如果有多个)用于提供有关项目的背景信息。如果您在 npm 上发布软件包,则该信息会在软件包页面上提供。name
并version
执行更多操作。
name
是一个短横线命名的包名。这是你在npm中找到它的名称,也是你安装包时使用的名称,等等。如果你习惯使用包,那么你可能熟悉这样的语法"react": "16.8.6"
。这是一个名称和一个版本号。
大多数 JavaScript 项目都遵循semver规范,以便直观地增加软件包版本号。每次将软件包发布到 npm 时,版本号都会增加。第一个、最后一个还是中间的数字会递增,取决于变更的重要性及其对其他人的影响。
依赖项
依赖项是你的项目所依赖的运行时包的列表。它们会在你运行npm install
或类似命令时安装。
我们再来聊聊"react": "16.8.6"
。每个依赖项都以键值对的形式列出,其中包含包的名称和版本号。不过,你可以在版本号前面添加一些额外的字符。
~
:如果您添加波浪号,您的软件包管理器将安装您列出的版本或任何较新的补丁版本。例如,~16.8.6
表示您将获得 的最新版本16.8.x
,但不会获得16.9.0
。^
:如果您添加插入符号,您的软件包管理器将安装您列出的版本或任何较新的补丁或次要版本,但不会安装主要版本。例如,^16.8.6
表示您将获得 的最新版本16.x.y
,但不会获得17.0.0
。
还有一些其他支持的字符,允许您指定范围。所有这些都使用semver 包进行解析。这有点令人困惑,所以让我解释一下。Semver 是一套用于对软件包进行版本控制的指南。由于 npm 遵循它并将这些指南用作其包管理器的基础,因此它相应地命名了它使用的语义版本控制包。
开发依赖项
稍有不同devDependencies
。这些是开发人员使用该软件包所需的依赖项,例如测试库。但是,最终用户不需要它们,因此它们被单独包含。当您npm install
在 中运行时,它们会被包含example-package
,但当您在另一个项目中运行时则不会npm install example-package
。
peerDependencies
这又是一种依赖关系。它主要用于包作者在使用某个包时,防止其他依赖项也正在使用的包发生冲突。例如,确保包使用的是项目中的 Babel 版本,而不是可能不兼容的本地版本。
关键词
关键字是 npm 搜索功能的助手。
执照
此处必须注明“我不是律师”。许可证是一个有很多专家的话题,而我不是其中之一。列出的许可证是您使用该项目所依据的条款。您可以阅读更多关于各种许可证的信息。
主入口点
这是导入包时引用的文件。给定"main": "index.js"
,将从中const example = require("example-package")
抓取导出。example
index.js
脚本
到了这里,我们开始深入了解文件的核心部分。scripts 部分包含更多键值对。键是命令的名称,值是调用该命令时运行的命令行指令。
让我们从一个简单的例子开始。
{
"test": "npm run jest"
}
这更像是一个别名。它允许我们npm test
在命令行中运行,并且它确实会运行npm run jest
。
那么更复杂一点的情况怎么样?
{
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx ."
}
这将使用一些特定的标志对整个项目目录运行 eslint。
没有什么可以阻止您自己运行这些脚本。为您提供更短的命令和正确的配置只是为了获得更好的体验。
但是,有一些脚本用于构建项目,以便将其发布并作为包安装到其他项目中。有一些特殊的键可以在指定的时间执行脚本,但我们这里不打算深入探讨。
相反,我们将研究您可能会看到的几种类型的脚本,这些脚本捆绑了一个项目并准备进行安装。
Babel 示例
{
"build": "babel src --out-dir . --ignore \"**/__tests__\""
}
第一个脚本使用了babel。它使用项目根目录中的配置文件,获取目录中的所有文件src
并将它们编译到根目录中。它还包含一个标志,用于忽略 中的文件src/__tests__
。
微束示例
{
"build": "microbundle -i src/example.js"
}
此脚本使用microbundle来打包项目。在本例中,我们指定了 asrc/example.js
作为构建的入口点。
运行脚本
脚本是可运行的。我上面提到过 可以npm test
运行,npm jest
而且它确实可以运行。然而,那是因为test
是 的别名npm run test
。这里有一些这样的。
对于您指定的任何其他自定义脚本,用户需要运行npm run <script>
。
垃圾桶
还有一件有趣的事!除了npm
命令之外,现在还有一个npx
命令。npx
允许你无需先安装软件包即可运行命令。🤯
软件包作者通过使用文件bin
的部分来实现此功能package.json
。它可以写成键值对,也可以使用以下语法。
{
"bin": "./bin/executable.js"
}
在这种情况下,./bin
和 扩展名会被剥离,用户可以运行npx executable
。如果您决定编写一个实现此功能的包,请注意相对文件路径是基于项目的捆绑版本。这是合理的,因为它是直接从已发布的包中执行的。
沒有更多嗎?
是的,实际上还有很多。但这已经是一个不错的开始,所以我们就先到此为止吧。
文章来源:https://dev.to/laurieontech/the-anatomy-of-package-json-pi4