这个文件用来描述项目及项目所依赖的模块信息,可以称得上是前端项目的大管家,从这个文件中,你可以看到很多有用的信息.可做到的事情如下
- 版本控制
- 依赖管理
- 运行的任务
- 等等
下面是一个字段信息比较全的package.json文件
perl
{
"name": "package-test-demo",
"version":"0.0.1",
"description": "this is a demo",
"keywords":["node.js","vue", "js"],
"homepage": "https://baidu.com",
"bugs":{"url":"http://path/to/bug","email":"xx@xxxx.com"},
"license": "ISC",
"author": "zpp",
"contributors":[{"name":"zpp","email":"xx@xxxx.com"}],
"files": "",
"main": "./dist/default.js",
"bin": "",
"man": "",
"directories": "",
"repository": {
"type": "git",
"url": "https://path/to/url"
},
"scripts": {
"start": "webpack serve --config webpack.config.dev.js --progress"
},
"config": { "port" : "8080" },
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.4",
"@babel/preset-react": "^7.13.13",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
"glob": "^7.1.7",
"less": "^3.9.0",
"less-loader": "^9.0.0",
"style-loader": "^2.0.0",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0",
"webpack-dev-server": "^3.11.2"
},
"peerDependencies": {
"tea": "2.x"
},
"bundledDependencies": [
"renderized", "super-streams"
],
"engines": {"node": "0.10.x"},
"os" : [ "win32", "darwin", "linux" ],
"cpu" : [ "x64", "ia32" ],
"private": false,
"publishConfig": {}
}
配置说明脑图
配置解析
必须属性和描述信息
name
就是项目的名称
规则
-
name
必须小于等于214个字符 -
不能以
.
或_
开头,不能有大写字母 -
因为名称最终成为URL的一部分因此不能包含任何非URL安全字符
不安全的URL字符
- 空格
" "
- 大于小于号
<>
- 方括号
[]
- 花括号
{}
- 竖线
|
- 反斜杠``
- 插入号
^
- 百分比
%
- 空格
实际上,我们平时开发的很多项目并不会发布在npm上,所以这个名称是否标准可能就不是那么重要,它不会影响项目的正常运行。如果需要发布在npm上,name字段一定要符合要求。
version
version
字段用于定义版本号。一般的格式是x.x.x
, 并且需要遵循该规则
该标识符被认为是完全唯一的。每次发布时version
不能与已存在的一致。
description
它是一个字符串, 用于描述当前项目的概况,方便用户直接了解包的功能。
keywords
keywords
是标签,是一个字符串组成的数组, 用于标记当前项目的重点词汇。同时,可以作为搜索关键词,提供给资源平台使用,进行索引。
和description一样, 作用类似于做seo的时候增加权重,曝光率的
author
作者信息,支持两种形式,一种是字符串,一种是对象
json
"author": "you name"
// or
"author": {
"name" : "you name",
"email" : "xxxxx@xx.com",
"url" : "xxxx"
}
contributors
表示该项目包的贡献者,是一个数组,数组字符串或者数据对象,描述贡献者信息
homepage
homepage就是项目的主页地址了,它是一个字符串。
bugs
bugs表示项目提交问题的地址,该字段是一个对象,可以添加一个提交问题的地址和反馈的邮箱:
"bugs": {
perl
"url" : "[https://github.com/facebook/react/issues](https://github.com/facebook/react/issues)",
"email" : "[xxxxx@xx.com](mailto:xxxxx@xx.com)"
}
最常见的bugs就是Github中的issues页面,如上就是react的issues页面地址。
依赖配置
一般情况, 我们开发项目都会依赖多个外部依赖包,根据依赖包的不同用途,可以给他们配置到不同的属性下面,有五个相关属性, 它们的值都是一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
dependencies
声明的是项目的生产环境中所必须的依赖包
通常在安装依赖的时候 使用---save
或者-S
则表述将该依赖写入dependencies属性中
json
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
},
版本号再后面会说到,此处先不讲
devDependencies
devDependencies中声明的是开发阶段需要的依赖包,如Webpack、Eslint、Babel等,用于辅助开发。它们不同于 dependencies,因为它们只需安装在开发设备上,而无需在生产环境中运行代码。当打包上线时并不需要这些包,所以可以把这些依赖添加到 devDependencies 中,这些依赖依然会在本地指定 npm install 时被安装和管理,但是不会被安装到生产环境中。
使用---save--dev
或者-D
则表述将该依赖写入devDependencies属性中
peerDependencies
直观表述。如果你安装我,那么你最好也安装X,Y和Z.
最典型的场景就是插件,比如A模块是B模块的插件。用户安装的B模块是1.0版本,但是A插件只能和2.0版本的B模块一起使用。这时,用户要是将1.0版本的B的实例传给A,就会出现问题。因此,需要一种机制,在模板安装的时候提醒用户,如果A和B一起安装,那么B必须是2.0模块。
peerDependencies字段就是用来供插件指定其所需要的主工具的版本。
例子:下方是一个myless库的package.json文件, 表示使用myless模块必须依赖less模块的3.9.x版本.
json
"name": "myless",
"peerDependencies": {
"less": "3.9.x"
}
然后,你宿主环境的node_modules里面 其实是
arduino
YouProject
|- node_modules
|- myless
|- less
// 而不是这样
YouProject
|- node_modules
|- myless
|- node_modules
|- less
peerDependencies
的目的是提示宿主环境去安装满足插件peerDependencies所指定依赖的包,然后在插件import或者require所依赖的包的时候,永远都是引用宿主环境统一安装的npm包,最终解决插件与所依赖包不一致的问题。
注意,从npm 3.0版开始,peerDependencies
不再会默认安装了。就是初始化的时候不会默认带出。
比如,在npm3.0的时候,你安装myless, 宿主环境下他不会强制强制安装less, 而是会给你一个警告, 大致如下
less是一个需要的依赖,但是没有被安装。
还有个问题, 就是如果myless的peerDependencies
所依赖的less升级版本了, 你需要手动去更新, 这个时候 启动项目的时候在控制台会有警告, 大概说是
css
npm Error. myless requires a peer xxx.@xxx. ...之类的
optionalDependencies
如果需要在找不到包或者安装包失败时,npm仍然能够继续运行,则可以将该包放在optionalDependencies对象中,optionalDependencies对象中的包会覆盖dependencies中同名的包,所以只需在一个地方进行设置即可。 需要注意,由于optionalDependencies中的依赖可能并为安装成功,所以一定要做异常处理,否则当获取这个依赖时,如果获取不到就会报错
bundledDependencies
上面的几个依赖相关的配置项都是一个对象,而bundledDependencies配置项是一个数组,数组里可以指定一些模块,这些模块将在这个包发布时被一起打包。
需要注意,这个字段数组中的值必须是在dependencies, devDependencies两个里面声明过的包才行。
engines
engines
字段指明了该模块运行的平台,比如Node
或者npm
的某个版本或者浏览器。
json
{ "engines" : { "node" : ">=0.10.3 <0.12", "npm" : "~1.0.20" } }
脚本配置
scripts
是 package.json中内置的脚本入口,用来执行脚本命令,简化输入,提高开发效率
config
config字段用来配置scripts运行时的配置参数,如下所示:
yaml
"config": {
"port": 3000
}
钩子
npm钩子
npm run 为每条命令提供了 pre- 和 post- 两个钩子(hook)。以 npm run test 为例,如果我们的 scripts 字段规定了 pretest 和 posttest,两个钩子的含义分别是预执行、后执行
prepublish:在打包和发布包之前运行,在npm install没有任何参数的本地运行
postpublish:发布包后运行
preinstall:包安装之前运行
postinstall:包安装后运行
preuninstall:在包卸载之前运行
postuninstall:在包卸载之后运行
preversion:在升级包版本之前运行
postversion:在升级包版本之后,提交之后运行
pretest:单元测试之前
posttest:测试之后
prestop:项目停止前
poststop:停止运行后
prestart:启动前
poststart:启动后
prerestart:重启前
postrestart:重启后
脚本执行顺序
arduino
//并行执行 &
npm run hello.js & npm run world.js
//串行执行,前一个成功才能执行后一个 &&
npm run hello.js && npm run world.js
通过npm_package_前缀,npm 脚本可以拿到package.json里面的字段
arduino
{
"name": "package.json",
"version": "1.0.0",
"repostitory":{
"type":"git"
}
"script":{
"view":"echo $npm_package_repository_type"//bash获得打印出来
}
}
//通过环境变量procss.env对象,拿到package.json的字段值
console.log(process.env.npm_package_name) //packages.json
console.log(process.env.npm_package_version) //1.0.0
console.log(process.env.npm_package_repository_type) // git
文件&目录
main
main 字段用来指定加载的入口文件,在 browser 和 Node 环境中都可以使用。如果我们将项目发布为npm包,那么当使用 require 导入npm包时,返回的就是main字段所列出的文件的module.exports 属性。如果不指定该字段,默认是项目根目录下的index.js。如果没找到,就会报错。
值是一个字符串
browser
browser字段可以定义 npm 包在 browser 环境下的入口文件。如果 npm 包只在 web 端使用,并且严禁在 server 端使用,使用 browser 来定义入口文件。
"module": "./src/index.js"
module
module字段可以定义 npm 包的 ESM 规范的入口文件,browser 环境和 node 环境均可使用。如果 npm 包导出的是 ESM 规范的包,使用 module 来定义入口文件。
"module": "./src/index.mjs"
需要注意, .js 文件是使用 commonJS 规范的语法(require('xxx')), .mjs 是用 ESM 规范的语法(import 'xxx')。
上面三个的入口入口文件相关的配置是有差别的,特别是在不同的使用场景下。在Web环境中,如果使用loader加载ESM(ES module),那么这三个配置的加载顺序是browser→module→main,如果使用require加载CommonJS模块,则加载的顺序为main→module→browser。
Webpack在进行项目构建时,有一个target选项,默认为Web,即构建Web应用。如果需要编译一些同构项目,如node项目,则只需将webpack.config.js的target选项设置为node进行构建即可。如果在Node环境中加载CommonJS模块,或者ESM,则只有main字段有效。
bin
bin字段用来指定各个内部命令对应的可执行文件的位置:
json
"bin": {
"someTool": "./bin/someTool.js"
}
主要适用于开发脚手架或者开发包的时候,用于命令指令的配置
files
files配置是一个数组,用来描述当把npm包作为依赖包安装时需要说明的文件列表。当npm包发布时,files指定的文件会被推送到npm服务器中,如果指定的是文件夹,那么该文件夹下面所有的文件都会被提交。