我们经常在项目中会看到package.json
文件,却很少关注里面的东西,那今天就来带你了解该文件的含义以及学会对它的配置。
作用
package.json
文件是一个用于描述和管理项目的配置文件。它包含了项目的元数据信息,例如项目名称、版本号、作者、许可证等。同时,它还包含了项目的依赖项信息,包括项目所依赖的第三方库、框架以及工具等。通过 package.json
文件,我们可以方便地管理项目的依赖关系,使得项目的构建、发布和维护更加简单和可靠。下面是我们经常用的 element-plus
包的package.json
{
"name": "element-plus",
"version": "2.3.12",
"description": "A Component Library for Vue 3",
"keywords": [
"element-plus",
"element",
"component library",
"ui framework",
"ui",
"vue"
],
"homepage": "https://element-plus.org/",
"bugs": {
"url": "https://github.com/element-plus/element-plus/issues"
},
"license": "MIT",
"main": "lib/index.js",
"module": "es/index.mjs",
"types": "es/index.d.ts",
"exports": {
".": {
"types": "./es/index.d.ts",
"import": "./es/index.mjs",
"require": "./lib/index.js"
},
"./es": {
"types": "./es/index.d.ts",
"import": "./es/index.mjs"
},
"./lib": {
"types": "./lib/index.d.ts",
"require": "./lib/index.js"
},
"./es/*.mjs": {
"types": "./es/*.d.ts",
"import": "./es/*.mjs"
},
"./es/*": {
"types": ["./es/*.d.ts", "./es/*/index.d.ts"],
"import": "./es/*.mjs"
},
"./lib/*.js": {
"types": "./lib/*.d.ts",
"require": "./lib/*.js"
},
"./lib/*": {
"types": ["./lib/*.d.ts", "./lib/*/index.d.ts"],
"require": "./lib/*.js"
},
"./*": "./*"
},
"unpkg": "dist/index.full.js",
"jsdelivr": "dist/index.full.js",
"repository": {
"type": "git",
"url": "git+https://github.com/element-plus/element-plus.git"
},
"publishConfig": {
"access": "public"
},
"style": "dist/index.css",
"sideEffects": [
"dist/*",
"theme-chalk/**/*.css",
"theme-chalk/src/**/*.scss",
"es/components/*/style/*",
"lib/components/*/style/*"
],
"peerDependencies": {
"vue": "^3.2.0"
},
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.0.6",
"@floating-ui/dom": "^1.0.1",
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
"@types/lodash": "^4.14.182",
"@types/lodash-es": "^4.17.6",
"@vueuse/core": "^9.1.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.3",
"escape-html": "^1.0.3",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-unified": "^1.0.2",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0"
},
"devDependencies": {
"@types/node": "*",
"csstype": "^2.6.20",
"vue": "^3.2.37",
"vue-router": "^4.0.16"
},
"vetur": {
"tags": "tags.json",
"attributes": "attributes.json"
},
"web-types": "web-types.json",
"browserslist": ["> 1%", "not ie 11", "not op_mini all"],
"gitHead": "89d4ec863ce55fc3de2f0513631e76f695f8e791"
}
基本字段
-
name
项目名称。该字段不能设置为空,它和版本号组成唯一的标识来代表整个项目,字母不能大写,可以使用
-
,_
符号,如果需要在 npm 平台发布,需要保证你的name
在平台是唯一的。 -
version
项目的版本号。需要发布 npm 平台的时候该字段为必输。
-
description
项目描述。该字段可以在 npm 平台搜索该包的时候起到作用。
-
keywords
关键词。在 npm 平台搜索的关键词,该字段为数组,可设置多个关键词。
-
homepage
项目的主页 URL。
-
bugs
项目提交问题的地址。
-
license
项目的许可证(软件的开源协议)。
-
main
npm 包的
CommonJS
入口文件。如果不设置则默认查找这个包根目录下的index.js
文件。当我们使用require
引入包的时候则会查找main
对应路径的文件进行引入。这个文件应该遵循CommonJS
模块规范,并且基于ES5
规范编写。 -
module
npm 包的
ESM
规范的入口文件。这样的文件可以使用ES6
的import/export
语法,并支持Tree Shaking
等特性。main
和module
字段在 package.json 中共同存在时,分别用于指定不同模块规范下的入口文件,以满足不同环境和工具的需求。平时我们引入三方包的时候例如
import ElementPlus from "element-plus";
,他会先找到这个包,然后在包里面的package.json
文件中找到module
对应的入口文件,等于你引入的就是这个 es 下的index.mjs
文件 -
types
TypeScript
类型定义文件的路径。 -
exports
定义包的子路径导出映射。
"exports": { ".": { "import": "./index.esm.js", // 当使用 ESM 语法导入包时,解析到这个文件 "require": "./index.cjs" // 当使用 require() 导入包时,解析到这个文件 }, "./feature": { "import": "./feature/esm/index.js", // 当导入特定的特性时,为 ESM 提供不同的入口点 "require": "./feature/cjs/index.js" // 当导入特定的特性时,为 CommonJS 提供不同的入口点 } },
-
unpkg
CDN 服务地址。
"unpkg": "dist/index.full.js" 相当于映射 "unpkg.com/element-plu…"
-
repository
包代码存放仓库地址。可以为字符串(仓库地址),可以为对象如上面的
element-plus
中的repository
-
publishConfig
npm 包的发布指定特定的配置。该配置将覆盖全局或用户级别的 npm 配置。这对于需要将包发布到私有 npm 仓库或具有特殊发布需求的场景特别有用。
publishConfig 是一个对象包含以下属性:
registry
:指定 npm 包的发布仓库地址。(私有 npm 仓库可以在这指定 url)access
:包的访问级别(默认public
公开,restricted
私有)tag
:为发布的 npm 包指定一个标签。默认情况下 npm 包会使用latest
标签发布,你可以手动指定为beta
-
style
该字段不是标准的 npm 字段,代表包中的样式文件路径。当 style 字段被设置时,某些工具(如 Webpack 的某些 loader 或构建脚本)可能会自动处理或包含这个样式文件。这通常用于那些希望将样式文件直接包含在其包中的前端库或组件。
-
sideEffects
用于告知打包工具(如 Webpack)哪些文件或模块在引入时具有副作用,从而影响 tree shaking 的行为。
在 package.json 中,sideEffects 字段是 Webpack v4 及更高版本引入的一个特性,用于标记项目中的某些文件或模块是否包含副作用(side effects)。这个字段对于 Webpack 的 tree shaking(树摇)优化至关重要。 通过正确配置 sideEffects,打包工具可以更有效地移除未使用的代码,减小最终打包文件的大小。
-
peerDependencies
对等依赖。
peerDependencies
字段用于声明一个 package 与依赖它的宿主应用程序所使用的其他 package 之间的兼容性限制。例如上面的element-plus
中的peerDependencies
是依赖的vue@3.2.0
的版本,也就是你当前项目的 vue 版本不能低于vue@3.2.0
,否则会出现兼容性报错。 -
dependencies
项目的生产环境中所必须的依赖包。
-
devDependencies
开发阶段需要的依赖包。比如 less、scss、eslint 等。
npm 安装包时常见的基本参数以及作用:
- 无参数 (npm install <包名>)
默认会添加到 package.json 文件中的
dependencies
中。 - --save 或者 -S 同上。
- --save-dev 或者 -D
添加到 package.json 文件中的
devDependencies
中,通常用于开发环境依赖的包。 - --global 或 -g 将包安装到全局环境,而不是当前项目的本地环境,这可以让这个包在任何项目使用,一般用于工具包。
- --production 仅安装到生产环境
- --no-save 安装的包但不会添加到 package.json 中的依赖项中。
- --no-package-lock 安装包时不生成 package-lock.json 文件。
- 无参数 (npm install <包名>)
默认会添加到 package.json 文件中的
-
browserslist
"> 1%":表示支持全球使用率超过 1% 的浏览器。 "not ie 11":不支持 ie11。 "not op_mini all":不支持所有版本的 Opera Mini 浏览器。
重要字段补充
除了 element plus
的 package.json
中的字段外,还有一些常见以及重要的,下面做一补充:
-
scripts
项目的脚本命令,这些命令可以通过
npm run <script-name>
来执行。 -
bin
指定命令以及对应执行文件路径。这些文件通常会有可执行权限,并且包含一些可以在命令行中运行的代码。例如:
{ "name": "my-tool", "version": "1.0.1", "bin": { "my-tool": "./bin/index.js" }, "scripts": { "start": "node index.js" } //... }
-
files
发布 npm 时指定需要上传的文件或者目录。如果你有少数不上传的文件,那可以创建一个.npmignore 文件(类似于.gitignore,但该文件不会上传 npm),去掉你不需要上传的文件,其余都上传。例如:
node_modules packages
-
engines
当前包或者项目依赖的环境。有些项目所以来的包跟 npm 的版本或者 node 版本有要求,不符合版本的时候项目经常启动不起来,该文件只是说明该项目所需要的 node 版本,并非起到限制作用。
package-lock.json(npm)、pnpm-lock.yaml(pnpm)
这些文件会在首次使用 npm
/pnpm
安装依赖的时候生成,用于锁定项目依赖的确切版本,包含主模块和所有依赖的子模块。主要用于避免由于依赖版本更新导致的不一致问题,保证是相同的依赖树。当我们更新某个包的版本的时候,同时也会修改 package-lock.json
。
依赖项的存储方式有所不同,pnpm
使用“硬链接”来存储依赖项,而 npm
和 yarn
则复制依赖项到每个项目的 node_modules
目录中。
依赖版本的管理
一般版本号遵循 semver 版本规范,版本通常由三位构成:x.y.z。分别对应主版本号、次版本号、修订号。
- 主版本号:该版本一般变化较大,可能不会兼容上个主版本的功能。
- 次版本号:在主版本的功能上进行更新,兼容同主版本的功能。
- 修订号:当修正了版本的 bug 之类
x.y.z
:安装指定的版本^x.y.z
:安装最新的次版本或者修订版本,只要次版本号或者修订号更新,就会安装最新的包~x.y.z
:安装最新的修订版本,只要修订号发生了变化,就会安装最新的包