前言
package.json作为项目的清单文件,记录了项目所依赖的各种包以及自定义的脚本、版本等信息,是现代前端项目中最为重要的文件之一。对一个项目快速上手,从package.json出发绝对是一个不错的选择。并且理解package.json各字段的作用和配置方式,对于我们提高项目构建、依赖管理及发布的技能至关重要。
生成package.json,使用npm init
,然后依次输入选项或者一直按回车,就可以自动化生成一个package.json
。如果觉得麻烦,运行npm init -y
就可以默认生成一个package.json。
{
"name": "project", // 项目名称
"version": "1.0.0", // 项目版本
"description": "", // 项目描述
"main": "index.js", // 项目入口文件
"scripts": { // 指定运行脚本命令的 npm 命令行缩写
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",// 作者
"license": "ISC" // 许可证
}
下面我将从项目的角度来划分package.json的不同字段,如有不对的地方请指出。
项目概况
name
和 version
如果你想要在npm发布一个包,”name”和”version”是必填的,并且将会是作为你的包的唯一id。
description
和 keywords
“description”是一个项目描述,接受一个字符串。
“keywords”是一个数组,数组里面可以放多个项目关键词。
两者都是为了方便让npm
搜索,也方便开发者更容易了解该项目的意义。
homepage
, repository
和 bugs
“homepage” 是这个项目的首页路径,方便开发者访问这个包的主页获取更多信息。
"homepage": "https://github.com/owner/project#readme"
“repository” 是这个项目的代码仓库,方便贡献者找到代码仓库。
"repository": "git+https://github.com/username/repo-name.git"
"repository": {
"type": "git",
"url": "git+https://github.com/username/repo-name.git"
}
“bugs” 是为了方便开发者对项目的bug提出建议或意见。
"bugs": { "url" : "https://github.com/owner/project/issues", "email" : "project@hostname.com" }
unpkg
和 jsdelivr
CDN方式下,引入当前npm包的链接。
"unpkg": "lib/index.iife.js",
"jsdelivr": "lib/index.iife.js",
项目环境
engines
package.json中的engines字段用于指定npm包运行所需的环境。它包含了node, npm, yarn等环境的版本要求。engines的格式是:
json
"engines": {
"node": ">=10.13.0",
"npm": ">=6.4.1",
"yarn": "^1.9.4"
}
engines字段主要是确保npm包在安装后可以正确运行所需的环境。如果环境版本不匹配,npm install时会显示警告信息。让其他开发者在使用该包之前可以确保拥有匹配的环境,避免因版本不兼容导致的错误或警告。
browserslist
browserslist字段是用来指定项目的目标浏览器范围的。它曾经是package.json的标准字段之一,但是从npm v5.5.0开始,browserslist被移除了。
以 Babel 为例,它是怎么判断项目是否需要做降级处理的呢,答案就是通过 browserslist 查询出需要支持的浏览器列表,然后根据这个列表来做判断。
browserslist 配置方式
这是因为browserslist现在可以通过以下几种方式指定:
- package.json中使用”browserslist” key:
"browserslist": ["> 1%", "last 2 versions"] // 查询全球市场占有率大于 1% 的浏览器最后两个版本
- 项目根目录下的.browserslistrc文件:
> 1%
last 2 versions
os
指定操作系统
{ "os": [ "darwin", "linux" ] } // 适用
{ "os": [ "!linux" ] } // 禁止
cpu
{ "cpu" : [ "x64", "ia32" ] } # 适用
{ "cpu" : [ "!arm", "!mips" ] } # 禁止
项目分析
main
“main” 定义了项目的入口文件,默认值是根目录的”index.js”。
module
性质等同于main
字段。module
用于ES6规范的模块,只要支持ES6,会优先使用module
入口。
这样,代码也可以启用tree shaking
机制。
"module": "es/index.mjs",
bin
很多包都有一个可执行命令,并且希望被安装到环境变量中。npm 安装依赖的时候, npm会通过node_modules/.bin 将 bin 里面的文件暴露出来,当你通过 npx myapp
的时候可以直接运行该命令。
{
"bin": {
"myapp": "./cli.js"
}
}
dependencies
和 devDependencies
两者的作用和区别
两者都是为了记录需要的依赖以及版本。
devDependencies
用于开发环境下依赖的模块,生产环境不需要被打入包内。运行命令行npm i xxx --save-dev
,会被安装到 “devDependencies”
dependencies
依赖的包不仅开发环境能使用,生产环境也能使用。运行命令行npm i xxx
,会被安装到 “devDependencies”
总结: 通常情况下, devDependencies
一般是放置一些代码规范工具、打包工具、编译器等,而dependencies
一般是放置组件库、框架等与页面相关的插件。其实依赖不管放在哪里对项目影响都不大,但是保持良好的习惯就会让人觉得项目很整洁。
指定不同版本
{
"dependencies": {
"foo": "1.0.0 - 2.9999.9999", // 1.0.1-2.9999.9999版本(和下面的表达差不多意思)
"bar": ">=1.0.2 <2.1.2", // 大于或等于1.0.2版本小于2.1.2版本
"baz": ">1.0.2 <=2.3.4", // 大于1.0.2版本小于等于2.3.4版本
"boo": "2.0.1", // 指定版本
"qux": "<1.0.0 || >=2.3.1 <2.4.5", // 小于1.0.0或者大于2.3.1且小于2.4.5
"til": "~1.2.3", // ~ 匹配1.2.x的所有小版本,但不会匹配到1.3.x
"elf": "^1.2.3", // 匹配1.x.x的所有大版本,但不会匹配2.x.x
"two": "2.x", // 匹配所有2.x开头版本
"thr": "3.3.x", // 匹配3.3.x版本
"lat": "latest", // 最新版本
"dyl": "file:../dyl"
}
}
指定url的包
开发过程中,有可能你需要直接使用本地的包或者git仓库的包进行调试,又不希望频繁上传到npm包管理器这么麻烦。
<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]
可以根据version
或者commit-ish
来进行精确下载。
git示例
{
"dependencies": {
"bar": "git+ssh://git@github.com:npm/cli.git#v1.0.27",
"foo": "git+ssh://git@github.com:npm/cli#semver:^5.0",
"baz": "git+https://isaacs@github.com/npm/cli.git",
"boo": "git://github.com/npm/cli.git#v1.0.27"
}
}
本地文件示例
{
"dependencies": {
"bar": "file:../foo/bar"
}
}
项目运行
scripts
scripts字段的作用
scripts
属性是一个字典,对象的属性名为可以通过 npm run
运行命令,属性值可执行命令。{"xxx": "vite"}
,在这里使用终端执行npm run xxx
。
如果你没有全局安装vite,直接去执行vite
命令行,终端是会报错的。但这里通过npm run xxx
执行命令并没有报错,是因为我们在安装依赖的时候,是通过npm i xxx 来执行的,例如 npm i vite
,npm 在 安装这个依赖的时候,就会node_modules/.bin/
目录中创建好vite
为名的几个可执行文件了(上面的bin
也提到了)。
.bin 目录,这个目录不是任何一个 npm 包。而是一个脚本。所以我们执行scripts里面的命令时,虽然在全局找不到对应的可运行命令,但也可以通过.bin文件夹下找到对应的脚本。
自定义脚本的写法
可以通过自定义脚本直接运行一些命令行提高自己的开发效率,或者运行脚本来打包配置项目。
{
"scripts": {
"clean": "rm -rf dist",
"update": "sh ./update.sh"
}
}
项目规范
husky
和 lint-staged
husky的作用
husky是一个可以给git hooks添加执行自定义脚本的工具。它可以在git事件触发时(commit, push, rebase等)自动执行我们所配置的脚本,从而实现lint校验,测试运行,构建打包等工作流程。
配合git事件触发脚本
husky的安装和配置也很简单,主要有以下几个步骤:
- 安装husky包:
npm install husky --save-dev
- 在package.json中添加git hooks脚本,如:”pre-commit”: “npm run lint”
- 添加husky配置到package.json,如:
"husky": { "hooks": { "pre-commit": "npm run lint"} }
- git commit触发pre-commit钩子,从而自动执行npm run lint进行lint校验。
所以,husky是一个比较方便的git hooks工具,可以让我们的开发工作流变得更加自动化和标准化。理解husky的作用和配置方式,可以大大提高我们的前端工程化实践水平。
lint-staged的作用
lint-staged是一个在git暂存文件(staged files)上运行代码格式规范的工具。它的主要作用是:
- 只校验暂存文件的改动(diff),而不是整个项目。这样可以提高lint效率,并且避免提交未修改的文件产生的lint错误。
- 支持在git pre-commit钩子中使用,结合husky可以实现commit前自动lint校验。
- 支持多种文件类型(JavaScript, CSS, Markdown 等)和多个linters。如ESLint, Stylelint, Prettier等。4. 提供了简单的配置方式,可以轻松地在package.json中完成配置。
lint-staged配合husky
- 安装lint-staged和相关的代码规范工具:
npm install lint-staged eslint prettier -D
- 在package.json中添加lint-staged配置:
"lint-staged": {"*.js": "eslint --fix",}
- 安装husky并配置pre-commit hook:
"husky": { "hooks": { "pre-commit": "npm run lint"} }
- git add 添加文件并commit,pre-commit钩子就会自动执行lint-staged lint校验。
所以,lint-staged是一个非常实用的工具,让我们的代码质量管理可以更加自动化。理解lint-staged的作用和配置方式,可以很好地提高我们的前端工程化水平。
types
项目如果是用TypeScript
写的,则需要types
字段,对外暴露相关的类型定义。
"types": "lib/index.d.ts",
项目打包配置
private
“private” 配置一个布尔值,当为true的时候,npm将会拒绝发布它。这个是防止私人储存库意外发布的情况。
sideEffects
“sideEffects” 用于告知打包工具(webpack),当前项目无副作用
,可以使用tree shaking
优化。
副作用
是指,该函数的调用过程中,是否对主函数(调用者)产生了附加影响,例如修改了函数外的变量或参数,我们就认为该函数是有副作用
的函数。
"sideEffects": [
"a.js",
"b.js"
],
exports
“exports” 允许在使用模块请求时声明应该使用哪个模块。当指定exports字段时,只有这些模块请求可用,请求其他模块将报错。
{
"exports": {
".": "./main.js",
"./sub/path": "./secondary.js",
"./prefix/": "./directory/",
"./prefix/deep/": "./other-directory/",
"./other-prefix/*": "./yet-another/*/*.js"
}
}
// 示例:
import _ from 'my-project' // 将会指向./main.js
import path from 'my-project/sub/path' // 将会指向./secondary.js
files
“files” 用于保留项目在npm发布时的文件或文件夹,在node_modules/下将会只留下files声明的文件或文件夹。你也可以提供一个.npmignore文件,让npm发布的时候规定哪些文件被忽略,就像.gitignore一样。
"files": [
"lib",
"bin",
"scripts"
],
package.json
,README
,LICENSE
/LICENCE
无法被忽略。
原文链接:https://juejin.cn/post/7233785645650264119 作者:simple_lau