package.json 文件,它是项目的配置文件,常见的配置有配置项目启动、打包命令,声明依赖包等。package.json 文件是一个 JSON 对象,该对象的每一个成员就是当前项目的一项设置。
{
"name": "monorepo_frame",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"install:all": "sh script/installAll.sh",
"doc:api": "sh script/api_doc.sh",
"build:ui": "pnpm --filter @web/ui run build ",
"test:ui": "pnpm --filter @web/ui test ",
"test:core": "pnpm --filter @web/core test ",
"dev:exproject": "pnpm --filter @@zqxx/exproject dev ",
"build:demo": "rimraf docs/demo && pnpm --filter @web/demo build ",
"dev:rest": "pnpm --filter @web/rest dev ",
"build:rest": "rimraf docs/rest && pnpm --filter @web/rest build ",
"build:all": "pnpm run build:demo",
"publish": " sh script/publish.sh",
"prettier": "prettier --write ."
},
"workspaces": [
"packages/*"
],
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@element-plus/icons": "^0.0.11",
"@element-plus/icons-vue": "^2.0.10",
"@types/lodash-es": "*",
"@types/node": "^17.0.45",
"@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0",
"@vue/compiler-sfc": "^3.2.45",
"element-plus": "2.3.3",
"eslint": "^8.27.0",
"minimist": "^1.2.7",
"mockjs": "^1.1.0",
"sass": "^1.56.1",
"typescript": "^4.9.3",
"unplugin-auto-import": "^0.12.0",
"unplugin-vue-components": "^0.22.11",
"vite": "^4.0.0",
"vite-plugin-dts": "^1.7.1",
"vite-plugin-mock": "2.9.6",
"vite-plugin-top-level-await": "^1.2.4",
"vue": "^3.2.45",
"vue-router": "^4.1.6",
"vue-tsc": "^0.32.1"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.10",
"@element-plus/utils": "^0.0.5",
"@kangc/v-md-editor": "^2.3.15",
"@vueuse/core": "^8.9.4",
"codemirror": "^5.65.9",
"crypto-js": "^4.1.1",
"echarts": "^5.4.0",
"highlight.js": "^11.7.0",
"ismobilejs": "^1.1.1",
"mockjs": "^1.1.0",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"pinia": "^2.0.35",
"pinia-plugin-persistedstate": "^3.1.0",
"terser": "^5.16.3",
"vite-plugin-inspect": "^0.7.7",
"vue-i18n": "9.1.10",
"vuex": "^4.1.0"
}
}
当我们克隆一个新的项目到本地时,需要执行 npm install(yarn install)命令来安装项目所需的依赖文件。当执行该命令时,就会根据 package.json 文件中的配置信息来自动下载所需的模块,也就是配置项目所需的运行和开发环境。
package.json 中最重要的两个字段就是 name 和 version,它们都是必须的,如果没有,就无法正常执行 npm install 命令。npm 规定 package.json 文件是由名称和版本号作为唯一标识符的。
name 很容易理解,就是项目的名称,它是一个字符串。在给 name 字段命名时,需要注意以下几点:
名称的长度必须小于或等于 214 个字符,不能以 “.” 和“_”开头,不能包含大写字母(这是因为当软件包在 npm 上发布时,会基于此属性获得自己的 URL,所以不能包含非 URL 安全字符(non-url-safe));
名称可以作为参数被传入 require(""),用来导入模块,所以应当尽可能的简短、语义化;
名称不能和其他模块的名称重复,可以使用 npm view 命令查询模块名是否重复,如果不重复就会提示 404:
如果 npm 包上有对应的包,则会显示包的详细信息:
实际上,我们平时开发的很多项目并不会发布在 npm 上,所以这个名称是否标准可能就不是那么重要,它不会影响项目的正常运行。如果需要发布在 npm 上,name 字段一定要符合要求。
version 字段表示该项目包的版本号,它是一个字符串。在每次项目改动后,即将发布时,都要同步的去更改项目的版本号。版本号的使用规范如下:
版本号的命名遵循语义化版本 2.0.0 规范,格式为:「主版本号. 次版本号. 修订号」,通常情况下,修改主版本号是做了大的功能性的改动,修改次版本号是新增了新功能,修改修订号就是修复了一些 bug;
如果某个版本的改动较大,并且不稳定,可能如法满足预期的兼容性需求,就需要发布先行版本,先行版本通过会加在版本号的后面,通过 “-” 号连接以点分隔的标识符和版本编译信息:内部版本(alpha)、公测版本(beta)和候选版本(rc,即 release candiate)。
package.jaon 中有五个和项目包描述信息相关的配置字段,下面就分别来看看这些字段的含义。
description 字段用来描述这个项目包,它是一个字符串,可以让其他开发者在 npm 的搜索中发现我们的项目包。
keywords 字段是一个字符串数组,表示这个项目包的关键词。和 description 一样,都是用来增加项目包的曝光率的。下面是 eslint 包的描述和关键词:
author 顾名思义就是作者,表示该项目包的作者。它有两种形式,一种是字符串格式:
"author": "CUGGZ (https://juejin.cn/user/3544481220801815)"
另一种是对象形式:
"author": {
"name" : "CUGGZ",
"email" : "[email protected]",
"url" : "https://juejin.cn/user/3544481220801815"
}
contributors 表示该项目包的贡献者,和 author 不同的是,该字段是一个数组,包含所有的贡献者,它同样有两种写法
"contributors": [
"CUGGZ0 (https://juejin.cn/user/3544481220801815)",
"CUGGZ1 (https://juejin.cn/user/3544481220801815)"
]
"contributors": [
{
"name" : "CUGGZ0",
"email" : "[email protected]",
"url" : "https://juejin.cn/user/3544481220801815"
},
{
"name" : "CUGGZ1",
"email" : "[email protected]",
"url" : "https://juejin.cn/user/3544481220801815"
}
]
homepage 就是项目的主页地址了,它是一个字符串。
repository 表示代码的存放仓库地址,通常有两种书写形式。第一种是字符串形式
通常情况下,我们的项目会依赖一个或者多个外部的依赖包,根据依赖包的不同用途,可以将他们配置在下面的五个属性下:dependencies、devDependencies、peerDependencies、bundledDependencies、optionalDependencies 。下面就来看看每个属性的含义。
dependencies 字段中声明的是项目的生产环境中所必须的依赖包。当使用 npm 或 yarn 安装 npm 包时,该 npm 包会被自动插入到此配置项中:
npm install
yarn add
当在安装依赖时使用 --save 参数,也会将新安装的 npm 包写入 dependencies 属性。
npm install --save
该字段的值是一个对象,该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
},
这里每一项配置都是一个键值对(key-value), key 表示模块名称,value 表示模块的版本号。版本号遵循「主版本号. 次版本号. 修订号」的格式规定:
「固定版本:」 上面的 react-scripts 的版本 4.0.3 就是固定版本,安装时只安装这个指定的版本;
「波浪号:」 比如~ 4.0.3,表示安装 4.0.x 的最新版本(不低于 4.0.3),也就是说安装时不会改变主版本号和次版本号;
「插入号:」 比如上面 react 的版本 ^17.0.2,表示安装 17.x.x 的最新版本(不低于 17.0.2),也就是说安装时不会改变主版本号。如果主版本号为 0,那么插入号和波浪号的行为是一致的;
latest:安装最新的版本。
需要注意,不要把测试或者过渡性的依赖放在 dependencies,避免生产环境出现意外的问题。
devDependencies 中声明的是开发阶段需要的依赖包,如 Webpack、Eslint、Babel 等,用于辅助开发。它们不同于 dependencies,因为它们只需安装在开发设备上,而无需在生产环境中运行代码。当打包上线时并不需要这些包,所以可以把这些依赖添加到 devDependencies 中,这些依赖依然会在本地指定 npm install 时被安装和管理,但是不会被安装到生产环境中。
当使用 npm 或 yarn 安装软件包时,指定以下参数后,新安装的 npm 包会被自动插入到此列表中:
npm install --save-dev
yarn add --dev
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1"
}
有些情况下,我们的项目和所依赖的模块,都会同时依赖另一个模块,但是所依赖的版本不一样。比如,我们的项目依赖 A 模块和 B 模块的 1.0 版,而 A 模块本身又依赖 B 模块的 2.0 版。大多数情况下,这不是问题,B 模块的两个版本可以并存,同时运行。但是,有一种情况,会出现问题,就是这种依赖关系将暴露给用户。
最典型的场景就是插件,比如 A 模块是 B 模块的插件。用户安装的 B 模块是 1.0 版本,但是 A 插件只能和 2.0 版本的 B 模块一起使用。这时,用户要是将 1.0 版本的 B 的实例传给 A,就会出现问题。因此,需要一种机制,在模板安装的时候提醒用户,如果 A 和 B 一起安装,那么 B 必须是 2.0 模块。
peerDependencies 字段就是用来供插件指定其所需要的主工具的版本。
"name": "chai-as-promised",
"peerDependencies": {
"chai": "1.x"
}
上面代码指定在安装 chai-as-promised 模块时,主程序 chai 必须一起安装,而且 chai 的版本必须是 1.x。如果项目指定的依赖是 chai 的 2.0 版本,就会报错。
需要注意,从 npm 3.0 版开始,peerDependencies 不再会默认安装了。
如果需要在找不到包或者安装包失败时,npm 仍然能够继续运行,则可以将该包放在 optionalDependencies 对象中,optionalDependencies 对象中的包会覆盖 dependencies 中同名的包,所以只需在一个地方进行设置即可。
需要注意,由于 optionalDependencies 中的依赖可能并未安装成功,所以一定要做异常处理,否则当获取这个依赖时,如果获取不到就会报错。
上面的几个依赖相关的配置项都是一个对象,而 bundledDependencies 配置项是一个数组,数组里可以指定一些模块,这些模块将在这个包发布时被一起打包。
需要注意,这个字段数组中的值必须是在 dependencies, devDependencies 两个里面声明过的包才行。
当我们维护一些旧项目时,可能对 npm 包的版本或者 Node 版本有特殊要求,如果不满足条件就可能无法将项目跑起来。为了让项目开箱即用,可以在 engines 字段中说明具体的版本号:
"engines": {
"node": ">=8.10.3 <12.13.0",
"npm": ">=6.9.0"
}
需要注意,engines 只是起一个说明的作用,即使用户安装的版本不符合要求,也不影响依赖包的安装。