大家好,我是小杜杜,在如今的前端项目中,都会有一个 package.json
文件,那么大家会不会很好奇这个文件是干嘛的?为什么每个项目都会有这个文件呢?它的作用是什么?有哪些字段呢?解下来将逐步讲解一下
package.json 究竟是什么?
当我们打开任意一个项目的时候,都会发现在根目录中有一个 package.json
的文件,从这个文件的后缀名.json
就可以看出它是一个json文件
那么这个文件是用来干什么的呢?
实际上package.json
这个文件会描述当前项目的所有配置信息(如名称、版本等)以及所有NPM包的信息
接下来,我通过开水果店
来讲解下package.json
(PS:不知道比喻的形象不,请大家多多支持)
在正式开始前我们先看看package.json
的配置信息,并将以此为例:
{
"name": "domesy",
"version": "1.0.0",
"description": "Domesy的水果店,这里有着新鲜的水果",
"keywords": ["react", "antd", "antdpro"],
"main": "index.js",
"scripts": {
"start" : "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Domesy",
"bugs": {
"url": "https://github.com/DomeSy",
"email": "domesy@xx.com"
},
"files": [],
"license": "ISC",
"licenses": [
{
"type": "",
"url": ""
}
],
"config": {
"port" : "8088"
},
"engines": {
"node": ">=0.10.3 <0.12"
},
"os": [ "linux", "win64" ],
"cpu" : [ "x64", "ia32" ],
"private": true,
"publishConfig": {
"tag": "1.0.0",
"registry": "https://www.npmjs.com/package/domesy-cli",
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/DomeSy",
"directory": "描述话语"
},
"preferGlobal": false,
"dependencies": {},
"devDependencies": {},
"peerDependencies": {},
"optionalDependencies": {},
"bundledDependencies": true,
"browserslist": {
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
复制代码
创建 package.json
要想开个水果店,首先要盘个店面,只要有店面了,才能进行下一步,这里有两种方式来创建
-
手动创建:亲力亲为,自己在根目录下创建个
package.json
文件 -
自动创建:找个小弟,给小弟说
npm init
, 再告诉些有关的信息,让他自动创建
这里需要注意一点,我们所用的信息必须规整,以防后面有人查你,所以这里的格式必须是严格的JSON格式
属性介绍
name 和 version
当我们盘下自己的店面后,首先这个店需要有一个自己的店名(name)
,其次需要记录下这个店的编号(version)
,这样才能通过名字和编号记录下来
name
和 version
会形成一个特有的标识符,同时也是构成npm
平台的唯一表示,防止他人找错店,购买了盗版水果
如果你的店名和其他店的店名重复,那么npm这个平台不允许你存在(也就是不能发布)
所以name
和version
就成了 package.json 中最重要的两个字段,也是必填字段
我们想要在这里开店,就必须遵循这个社区的规则
-
name: 必须小于等于214个字符,并且不能以
.
、_
或大写字母
开头,原因是最终我们的名称会变为URL的一部分,故不能包含任何非URL安全字符,同时官方希望我们不要使用核心模块的名称,如js
、node
等 -
version: 格式为
x.x.x
,如:1.0.0,如果在npm中发包中,每次发布的版本号不能一致
description 和 keywords
当我们开好店之后,我们需要想一些词,来告诉顾客我们点的水果有多新鲜,比如说,香甜可口等
-
description:描述信息,字符串,同时也会在
npm search
的返回结果中显示,用来提示顾客,这家店满足你的所需 -
keywords:关键词,数组,它的作用与
description
类似,将描述的关键词提取出来,也可以通过npm search
找到
homepage
我们需要告诉顾客我们的店面在哪,在什么地方
homepage:项目的主页地址
用过 React
的小伙伴应该知道,当我们使用npx创建一个项目时,在打包会发现找不到地址,原因是React
使用懒加载打包后服务器只能找到buildle.[hash].js
,所以这是我们就需要配置"homepage": "."
,让他指向跟路径
author 、contributors 和 maintainers
当我们开了这家店,就会有一个创办者(author)
和一些股东(contributors)
,同时也会有人来帮你维护这家店的维护者(maintainers)
- auto: 作者,string | object
- contributors:贡献者列表,Array
- maintainers:维护者列表,Array
注:他们都是整个水果店的共享者,同时每个人都是一个对象或者是字符串,具有姓名(name)
、地址(url)
和邮箱(email)
三个字段,其中name为必选
,url和email为可选
这里以 author
为例:
// 为对象时
”author": {
"name": "Domesy",
"email": "domesy@xx.com",
"url": "http://doemsy.cm"
}
// 为字符串时
"author": "Domesy domesy@xx.com (http://doemsy.cm)"
复制代码
bugs
作为一个店面,肯定会有顾客所不满的地方,我们要给顾客们个地址,用来反馈所存在的问题
bugg: 用于项目反馈的issue地址或者邮箱
"bugs": {
"url": "https://github.com/DomeSy",
"email": "domesy@xx.com"
}
复制代码
license 和 licenses
开店之后我们需要一些组织的认可,比如说卫生之类的证书
- lincense:包的开源协议名称
- lincense:多个包的开源协议名称,数组,包含
type
和url
字段
main、module 和 browser
这个字段可以理解为我们进入店的入口,只有经过这个入口才能进店
- main:指定加载的入口文件,
require
导入的时候就会加载这个文件,通常默认为根目录下的index.js
文件,browser
环境和node
环境下均可使用 - module:定义了
npm
包的 ESM 规范的入口文件,browser
环境和node
环境下均可使用 - browser:定义 npm 包在 browser 环境下的入口文件
dependencies和devDependencies
当我们的水果店盘下来之后,我们就要选定水果,devDependencies
可以认为是我们自己吃的,而dependencies
是给顾客卖的水果
当我们使用npm install
安装node_module
时,就相当于在给我们的水果店进货
- devDependencies:制定项目开发所需的模块,命令
--save-dev
=>-D
- dependencies:制定项目运行所需的模块,命令
--save
==>-S
注:它们都是对象,通过键值对表示,有属性名
和版本号
构成
版本号的规则:
- 固定版本:如:7.3.1,那么安装的版本就为 7.3.1
- 波浪号:如:~7.3.1,那么安装7.3.x的最新版本(但不低于7.3.1),不会安装7.4.x,也就是说:安装时,不改变
大版本号
和次要版本号
- 插入号:如:^7.3.1,那么安装7.x.x的最新版本(但不低于7.3.1),不会安装8.x.x,也就是说:安装时,不改变
大版本号
peerDependencies 、bundledDependencies 和 optionalDependencies
当我们有了水果后,我们可以尝试用混合水果做成饮料,
- peerDependencies:代表条件比较苛刻,我必须用南京的西瓜作为原料,苏州的西瓜也不行,但我们的水果店主要买的就是苏州的西瓜,但我们这是还想做出这杯饮料,就必须用到南京的西瓜。
简单地说就是,整个项目依赖A模块和B模块的1.0,但A本身依赖B的2.0
,也就是说要想使用 A 和 B模块,就必须是2.0版本的B
而 peerDependencies 的作用就是供插件指定其工具的版本,并且在npm 3.0之后,就不会磨人安装peerDependencies
了
-
bundledDependencies:可以认为是佐料,不管什么饮料都要加点,也就是说,指定发布的时候会被一起打包出来
-
optionalDependencies:可以认为是可有可无的小料,就算没有也不会导致整个饮料失败。也就是说,在此下的依赖,就算安装失败,也不会导致
npm install
失败
files
当剩下一些水果,我们有舍不得扔,但我们会将起与好的水果分开
files:模块下的文件名或文件夹名,数组,但这个字段通常很少使用,可以通过 .npmignore
这个文件实现相同的用法,这点和.gitignore
的使用类似
bin
有些水果非常畅销,我们可以说一些暗号来代表这些水果缺货了,非常畅销,来进行指令操作
bin:用来指定内部命令对应的可执行文件的位置。这个字段还是非常有用的,尤其是用cli
这块,就用到了这个命令。
在这里,有兴趣的可以看看 10分钟,打造一个专属于你的cli
"bin": { "domesy": "bin/domesy.js" },
复制代码
当我们执行 domesy
命令的时候就会执行 bin/domesy.js
文件中的代码
如果我们的包以依赖
的方式被安装时,如果有bin
,就会在node_modules/.bin/
生成对应的文件,然后建立符号链接
所有node_modules/.bin/
目录下的命令都可以使用npm run [命令]
的格式下运行。(可以按tab查看命令)
directories
接下来我们将水果进行分类,用于告诉顾客你可以在哪买到对应的水果
directories: 用来展示项目的目录结构信息,可以告诉用户每个目录在什么位置
repository
我们可以将我们的水果店的地理位置告诉他们
repository: 包的存放地址,主要包含类型(type)
、地址(url)
、描述(directory)
三个字段,可以想对你代码贡献的人有所帮助
"repository": {
"type": "git",
"url": "https://github.com/DomeSy",
"directory": "描述话语"
}
复制代码
script
这个就相当于买水果的方式,有线下,网上,或者测试水果的品质,
script:指定运行脚本的命令,也就是npm
命令的缩写,比如说 start
命令
"scripts": {
"start": "cross-env UMI_ENV=dev umi dev",
}
复制代码
注:scripts
可以直接使用node_modules中安装的模块,与直接运行的npx
有所区别,如:
- npm使用:
npm run start
- npx使用:
npx cross-env UMI_ENV=dev umi dev
config
我们不能只放水果,我们的店面也需要装修一下,让我们的店更加整洁,舒适
config:用于添加命令行的环境变量
比如说:
{
"name": "domesy",
"config": {
"port": "8088"
},
"script": {
"start" : "node server.js"
}
}
复制代码
我们在 server.js 打印下对应的值 process.env.npm_package_config_port
之后运行 npm run start
就能看到打印的值为 8088
engines
当我们开启水果店,就会有营业时间,不可能会全天营业
engines:字段指明了该模块的运行平台,比如限制node的版本
{
"engines": {
"node": ">=0.10.3 <0.12"
},
}
复制代码
os 和 cpu
我们的水果店可以有多个发售的平台,比如说淘宝、京东之类的
os: 可以指定在那个操作系统上运行
cpu: 限制模块只能在某种架构的cpu
下运行
{
"os": [ "linux", "win64" ],
"cpu" : [ "x64", "ia32" ],
}
复制代码
private
水果店在一些特定的平台上发布,可以防止其他人无意将其挂到其他平台上售卖
private: 如果为true
,在npm
平台上将会拒绝发布,目的是为了防止一个私有模块发出去
{
"private": true,
}
复制代码
publishConfig
在售卖水果的时候,每个平台要的水果种类需求不同,比如在美团上要的西瓜多点,在饿了么平台上冬瓜要的多点,这时我们可以为两个平台单独提供不同的水果
publishConfig:特定的模块发布到特定的npm
库,常常会和private
联合使用,并有tag
、registry
、access
三个字段
{
"publishConfig": {
"tag": "1.0.0",
"registry": "https://www.npmjs.com/package/domesy-cli",
"access": "public"
}
}
复制代码
preferGlobal
水果店的各个模块内都可以有相同的装饰品
preferGlobal: 表示用户不将此模块设置为全局的模块,要不要发出警告,表示该模块应该是全局模块,与--global
类似
{
"preferGlobal": false,
}
复制代码
browserslist
每个平台的规则不同,我们需要满足各个平台上的需求所做一些符合条件的水果
browserslist:在项目中提供共享的浏览器支持信息,比如说我们通常会使用babel
等,提供对应的浏览器信息后,他们会针对浏览器信息采取不同的编译
{
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
复制代码
End
至此,有关 package.json
的相关配置就弄完了,这次以开水果店讲解,不知道形象不,如果能帮到你,希望点个赞??支持下吧(● ̄(エ) ̄●)
参考文献:
其他文章: