熟悉又陌生的package.json
前言
随着前端的不时开展,package.json
可谓是在前端项目中无处不在,它不只在项目根目录会有,而且在 node_modules 中也存在。那么这个文件到底是干嘛的,又有什么作用?很多人对它的认识是不是只停留在dependencies
、devDependencies
项目依赖列表,或者是script
项目的各种脚本指令等,实践上它能做的事情远不止这些。
创立package.json
现往常当你运用脚手架生成一个根本的项目时,它会自动帮你生成package.json
。
当我们手动创立项目时,能够运用npm init
,然后依据提示一步步输入相应的内容完成后即可自动创立,当然你也能够运用npm init -y
跳过交互直接生成
npm init
生成的根底package.json
文件内容如下:
这样看着十分简单,事实上,它所包含的功用属性远不止这些。
常见属性
name
它表示项目称号,该字段决议了你发布的包在 npm 的名字,也就是平常装置依赖的包名
一些规则:
称号必需小于或等于 214 个字符。这包括范围包的范围。
作用域包的称号能够以点或下划线开头。假如没有范围,这是不允许的。
新包的称号中不得包含大写字母。
该称号最终成为 URL、命令行参数和文件夹称号的一局部。因而,称号不能包含任何非 URL 平安字符。
version
它表示项目的版本号,该"version"
属性必需采用major.minor.patch
格式的方式。
{ "version": "1.0.0"}
普通来讲假如你方案发布包,则package.json
中最重要的内容就是name和version,由于它们是必需的。称号和版本一同构成一个标识符,假定该标识符是完整独一的。对包的更改应该随同着对版本的更改。假如你不打算发布包,则name和version字段是可选的。
description
它表示项目的描绘信息,该内容会直接展现在npm
官网,它主要是为了让其别人快速理解的项目
keywords
它表示项目的关键字,它是一个数组,它能够便当其别人更好的搜索
{ "keywords": ["songyao", "songyao-cli", "cli"]}
比方这个我之前写的脚手架,在npm
上的检索信息
author
它表示项目的作者信息,它既能够是一个字符串,又能够是一个对象
{ "author": "nanjiu"}{ "author": { "name": "nanjiu", "email": "xxx@163.com", "url": "https://bettersong.github.io/nanjiu/" }}
其中email
、url
是可选的
repository
它表示项目的仓库地址
简单写法:
{ "repository": "https://github.com/***"}
版本控制写法:
{ "repository": { "type": "git", "url": "http://github.com/***", "directory": "nanjiu" }}
contributors
它表示项目的奉献者,该字段是一个数组
{ "contributors": [ { "name" : "nanjiu", "email" : "nanjiu@xx.com", "url" : "https://bettersong.github.io/nanjiu/" }, ]}
script
它表示项目的可执行脚本命令
{ "script": { "start": "node ./build/cli.js start", "dev": "vue-cli-service serve --mode dev", "build:oa": "vue-cli-service build --mode oa", "build:oa-legacy": "vue-cli-service build --mode oa --modern", "build:pre": "vue-cli-service build --mode pre --modern", }}
执行时运用npm run
对应的key
就能够,比方npm run start
每个 npm script 有 pre 和 post 两个钩子, pre 钩子在脚本执行前将被触发, post 则是在脚本执行后触发
### dependencies
它表示项目消费环境中所需的依赖,当运用npm
装置时,依赖会默许插入该字段中
{ "dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/core": "^10.0.0", "@nestjs/mapped-types": "*", "@nestjs/platform-express": "^10.0.0", "@types/cors": "^2.8.13", "cors": "^2.8.5", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", }}
在装置依赖时也能够运用--save
参数,表示依赖是消费环境所需
npm install--save
或者运用-S
简写
npm i-S
devDependencies
它表示项目开发环境所需的依赖,比方webpack
、vite
、babel
等工程化依赖包。这些依赖表示只需求在开发环境装置,无需在消费环境装置。
{ "devDependencies": { "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", }}
想要将依赖制定装置在devDependencies
下,能够运用如下命令:
npm i--save-dev
或者
npm i-D
browserslist
它表示打包时需求支持哪些阅读器,普通babel
、autoperfixer
会运用该字段停止配置
{ "browserslist": [ "> 1%", "last 2 versions", "iOS >= 9.3", "Android >= 6.0" ],}
babel
它表示babel
的配置项,用来指定babel
的编译配置
{ "babel": { "presets": ["@babel/preset-env"] }}
不过引荐做法还是运用babel
单独配置文件:babel.config.js
等
gitHooks
它表示git
定制化脚本程序,能够用来配置代码提交检测等
比方:
{ "scripts": { "lint:diff": "node ./models/pre_commit.js" }, "gitHooks": { "pre-commit": "npm run lint:diff" },}
hook类型有很多种:
commit-msg: 钩子在启动提交信息编辑器之前,默许信息被创立之后运转。
post-update: 仅在一切的ref被push之后执行一次。它与post-receive很像,但是不接纳旧值与新值。主要用于通知。
pre-applypatch: 实践上的调用机遇是应用补丁之后、变卦commit之前。
pre-commit: 钩子在键入提交信息前运转。
prepare-commit-msg: 钩子在启动提交信息编辑器之前,默许信息被创立之后运转。
pre-push: 钩子会在 git push 运转期间, 更新了远程援用但尚未传送对象时被调用。
pre-rebase: 钩子运转于变基之前,以非零值退出能够中止变基的过程。
post-checkout: 更新工作树后调用checkout时调用,或者执行 git clone后调用。主要用于考证环境、显现变卦、配置环境。
等...
生疏属性
以上这些属性想必是每个package.json
文件中常见的属性,但它除了以上这些属性之外还有许多同样十分重要的属性。
bugs
它表示项目问题的提交地址,这个普通在开源项目中见的多
{ "bugs": { "url" : "http://github.com/***/issues", "email" : "nanjiu@xx.com" }}
peerDependencies
它表示项目对等依赖,运用npm install --save-peer
装置
这个其真实我们工作中用的并不多,普通用于开发插件,避免项目在装置该插件时,屡次装置相同的依赖
{ "peerDependencies": { "react": ">=16.9.0", "react-dom": ">=16.9.0" },}
需求留意的是在 npm 2
中,当我们下载 ant-design@3.x
时,peerDependencies
中指定的依赖会随着 ant-design@3.x
一同被强迫装置,所以我们不需求在宿主项目的 package.json
文件中指定 peerDependencies
中的依赖,但是在 npm 3
中,不会再强迫装置 peerDependencies
中所指定的包,而是经过正告的方式来提示我们,此时就需求手动在 package.json
文件中手动添加依赖
optionalDependencies
它表示可选依赖项
当你希望某些依赖即便下载失败或者没有找到时,项目仍然能够正常运转或者 npm 继续运转的时,就能够把这些依赖放在 optionalDependencies
对象中,但是 optionalDependencies
会掩盖 dependencies
中的同名依赖包,所以不要把一个包同时写进两个对象中。
需求留意,由于optionalDependencies中的依赖可能并为装置胜利,所以一定要做异常处置,否则当获取这个依赖时,假如获取不到就会报错。
try { var axios = require('axios') var fooVersion = require('axios/package.json').version } catch (er) { // 报错}
bundledDependencies
它表示捆绑依赖项
与其他几种依赖项不同,他不是一个键值对的对象,而是一个数组,数组里是包名的字符串,例如:
{ "bundleDependencies": [ "axios", "lodash" ] }
engines
它表示声明node环境
与依赖关系一样,假如不指定版本(或者指定“ *”作为版本) ,那么任何版本的节点都能够。
{ "engines": { "node": ">=0.10.3 <15" }}
main
它表示项目的入口文件,假如不指定该字段,默许是根目录下的index.js
{ "main": "./src/index.js",}
从 Node.js 12.20.0 版本开端,"main" 字段也能够指定 ES 模块的入口文件
browser
它表示UMD模块的入口文件
UMD:兼容 CommonJS 和 AMD 的模块,既能够在 node 环境中被 require
援用,也能够在阅读器中直接用 CDN 被script
标签 引入
main 字段里指定的入口文件在 browser 和 node 环境中都能够运用。假如只想在 web 端运用,制止在 server 端运用,能够经过 browser 字段指定入口。
{ "browser": "./src/index.js" }
module(非官方字段)
它表示ES模块入口文件,阅读器环境和 node环境均可运用
{ "module": "./src/index.js" }
在Web环境中,假如运用loader加载ESM(ES module),那么这三个配置的加载次第是browser→module→main
,假如运用require加载CommonJS模块,则加载的次第为main→module→browser
。
main
、browser
、module
三个字段都是用于 npm 包的,假如项目不是作为 npm 包发布,这三个字段不需求写。
导出包只在 web 端运用,并且制止在 server 端运用,运用
browser
导出包只在 server 端运用,运用
main
导出 ESM 标准的包,运用
module
导出包在 web 端和 server 端都允许运用,运用
module
和main
exports(非官方字段)
它表示当打包工具支持exports
字段时,main/browser/module
的配置将被疏忽,而运用该字段
{ "exports": { "require": "./index.js", "import": "./index.mjs" }}
type(非官方字段)
它表示指定运用那种模块方式,默许值为commonjs
比方指定运用ES Module
:
{ "type":"module"}
files
它表示指定哪些文件能够被上传到npm上,有点相似.gitignore
,但功用与之相反
{ "files": [ "index.js", "dist" ],}
无论设置如何,一直包含某些文件:
package.json
README
LICENSE
/LICENCE
main
字段中的文件
os
它表示该模块只能在那个操作系统上运转
{ "os" : [ "darwin", "linux", "win32" ]}
还能够阻止而不是允许操作系统,只需在被阻止的操作系统前面加上!
{ "os": [ "!win32" ]}
cpu
它表示指定项目只在某些CPU架构上运转
{ "cpu": [ "x64", "ia32" ]}
与os
相似,它同样能够运用!
{ "cpu": [ "!arm", "!mips" ]}
private
它表示该项目是私有的,能够避免我们将私有项目发布到npm
上
{ "private": true}
preferGlobal
当设置 preferGlobal
字段为 true 时,它表示你的包更合适以全局方式装置,而不是作为项目的依赖项停止本地装置。
<button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="{ "preferGlobal": true }" aria-label="复制" data-bs-original-title="复制">
{ "preferGlobal": true}