# package.json配置

# 描述配置

# name

项目名称:第三方包可以通过npm install包名安装

"name":"yxzx"
1

# version

项目版本:项目版本号

"version" : "18.2.0"
1

# repository

仓库地址及版本控制信息

"repository": {
  "type": "git",
  "url": "https://github.com/xxx.git",
  "directory": "package"
}
1
2
3
4
5

# decription

项目描述:展示在npm官网,让别人能快速了解该项目

"description": "JavaScript"
1

# keyword

技术关键词,好的关键词可以帮助别人在 npm 官网上更好地检索到此项目,增加曝光率

"keywords": [
  "ant",
  "component",
  "components",
  "design",
  "framework",
  "frontend",
  "react",
  "react-component",
  "ui"
],
1
2
3
4
5
6
7
8
9
10
11

# homepage

项目主页的链接:通常是项目 github 链接,项目官网或文档首页

"homepage": "https://reactjs.org/"
1

# bugs

项目bug反馈地址:通常是github issue页面的链接

"bugs": "https://github.com/vuejs/core/issues"
1

# license

项目的开源许可证

"license": "MIT"
1

# author

项目作者

"author": "leijun"
1

# contributors

该项目包的贡献者

"contributors": [
  "xxxx <xxxxx@xx.com>",
  "xxxx <xxxxx@xx.com> "
]

"contributors": [
  {
    "name" : "xxxxx",
    "email" : "xxxxx@xx.com",
    "url" : "https://xxxxx"
  },
  {
    "name" : "xxxxx",
    "email" : "xxxxx@xx.com",
    "url" : "https://xxxxx"
  }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 文件配置

# files

项目在进行npm发布时,可以通过files指定需要跟随一起发布的内容来控制npm包的大小,避免安装时间太长,发布时默认会包括package.jsonlicenseREADMEmain字段里指定的文件。忽略node_moduleslockfile等文件,在此基础上,我们可以指定更多需要一起发布的内容。可以是单独的文件,整个文件夹,或者使用通配符匹配到的文件

"files": [
  "filename.js",
  "directory/",
  "glob/*.{js,json}"
]
1
2
3
4
5

# type

node支持ES模块后,要求ES模块采用.mjs后缀文件名。只要遇到.mjs文件,就认为它是ES模块。如果不想修改文件后缀,就可以在package.json文件中,指定type字段为module

"type": "module"
1

# main

项目发布时,默认会包括package.jsonlicenseREADMEmain字段里指定的文件,因为main字段里指定的是项目的入口文件,在browserNode环境中都可以使用,如果不设置main字段,那么入口文件就是根目录下的index.js

"main": "./index.js"
1

# browser

main字段里指定的入口文件在browserNode环境中都可以使用。如果只想在web端使用,不允许在server端使用,可以通过browser字段指定入口

"browser": "./browser/index.js"
1

# module

项目也可以指定ES模块的入口文件,这就是module字段的作用

"module": "./index.mjs"
1

当一个项目同时定义了mainbrowsermodule,像webpackrollup等构建工具会感知这些字段,并会根据环境以及不同的模块规范来进行不同的入口文件查找

# exports

node14.13支持在package.json里定义exports字段,拥有了条件导出的功能,exports字段可以配置不同环境对应的模块入口文件,并且当它存在时,它的优先级最高

"exports": {
  "require": "./index.js",
  "import": "./index.mjs"
}
1
2
3
4

这样的配置在使用import ‘xxx’require(‘xxx’)时会从不同的入口引入文件

上面的写法等同于

"exports": {
  ".": {
    "require": "./index.js",
    "import": "./index.mjs"
  }
}
1
2
3
4
5
6

exports除了支持配置包的默认导出,还支持配置包的子路径

"exports": {
  "./style": "./dist/css/index.css"
},
1
2
3
//原来的引入
import `packageA/dist/css/index.css`;
// 用户引入时
import `packageA/style`;
1
2
3
4

除了对导出的文件路径进行封装,exports还限制了使用者不可以访问未在“exports”中定义的任何其他路径。比如发布的dist文件里有一些内部模块dist/internal/module,被用户单独引入使用的话可能会导致主模块不可用。为了限制外部的使用,我们可以不在exports定义这些模块的路径,这样外部引入packageA/dist/internal/module模块的话就会报错。

# workspaces

项目的工作区配置,用于在本地的根目录下管理多个子项目。可以自动地在npm install时将workspaces下面的包,软链到根目录的node_modules中,不用手动执行npm link操作

"workspaces": [
  "workspace-a"
]
1
2
3

表示在workspace-a目录下还有一个项目,它也有自己的package.json

通常子项目都会平铺管理在packages目录下,所以根目录下workspaces通常配置为

"workspaces": [
  "packages/*"
]
1
2
3

# 脚本配置

# script

指定项目的一些内置脚本命令,这些命令可以通过npm run来执行。通常包含项目开发,构建等CI命令

"scripts": {
  "build": "webpack"
}
1
2
3

除了指定基础命令,还可以配合prepost完成命令的前置和后续操作

"scripts": {
  "build": "webpack",
  "prebuild": "xxx", // build 执行之前的钩子
  "postbuild": "xxx" // build 执行之后的钩子
}
1
2
3
4
5

执行npm run build命令时,会按照prebuild -> build -> postbuild的顺序依次执行上方的命令(pnpmyarn2已经废弃这种操作)

# config

设置scripts里的脚本在运行时的参数

# 设置端口号
"config": {
  "port": "3001"
}
# 在执行脚本时,我们可以通过 npm_package_config_port 这个变量访问到 3001
1
2
3
4
5

# 依赖配置

# dependencies

运行依赖,也就是项目生产环境下需要用到的依赖

"dependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0"
}
1
2
3
4

# devDependencies

开发依赖,项目开发环境需要用到而运行时不需要的依赖,用于辅助开发

"devDependencies": {
  "webpack": "^5.69.0"
}
1
2
3

# perDependencies

同伴依赖,一种特殊的依赖,不会被自动安装,通常用于表示与另一个包的依赖与兼容性关系来警示使用者。

比如我们安装AA的正常使用依赖B@2.x版本,那么B@2.x就应该被列在ApeerDependencies下,表示“如果你使用我,那么你也需要安装B,并且至少是2.x版本

"peerDependencies": {
  "react": ">=16.9.0",
  "react-dom": ">=16.9.0"
}
1
2
3
4

# optionalDependencies

可选依赖,顾名思义,表示依赖是可选的,它不会阻塞主功能的使用,安装或者引入失败也无妨。这类依赖如果安装失败,那么npm的整个安装过程也是成功的

"optionalDependencies": {
  "colors": "^1.4.0"
}
1
2
3

# peerDependenciesMeta

同伴依赖也可以使用peerDependenciesMeta将其指定为可选的

"peerDependencies": {
  "colors": "^1.4.0"
},
"peerDependenciesMeta": {
  "colors": {
    "optional": true
  }
}
1
2
3
4
5
6
7
8

# bundleDependencies

打包依赖。它的值是一个数组,在发布包时,bundleDependencies里面的依赖都会被一起打包

"bundleDependencies": [
  "react",
  "react-dom"
]
# 在执行 npm pack 打包生成 tgz 压缩包中,将出现 node_modules 并包含 react 和 react-dom
# 需要注意的是,这个字段数组中的值必须是在 dependencies,devDependencies 两个里面声明过的依赖才行
1
2
3
4
5
6

# overrides

注意这种方式在使用的过程中,发现有安装依赖报错,项目不能正常运行(可以尝试但是可能有问题)

overrides可以重写项目依赖的依赖,及其依赖树下某个依赖的版本号,进行包的替换

# 某个依赖 A,由于一些原因它依赖的包 foo@1.0.0 需要替换,我们可以使用 overrides 修改 foo 的版本号:
"overrides": {
  "foo": "1.1.0-patch"
}
# 当然这样会更改整个依赖树里的 foo,我们可以只对 A 下的 foo 进行版本号重写
"overrides": {
  "A": {
    "foo": "1.1.0-patch",
  }
}
1
2
3
4
5
6
7
8
9
10

# resolutions

是一个用于解决依赖项冲突的npm特殊字段

  • 在某些情况下,您的项目依赖项可能需要不同的版本,而这些版本之间可能存在冲突。这时候,您可以使用resolutions字段来指定应该使用哪个版本,以解决这些冲突。
  • 如果您的项目依赖于package-apackage-b,而这两个包都依赖于package-c,但它们依赖于package-c的不同版本,这会导致冲突。在这种情况下,您可以在package.json文件中使用resolutions字段来指定应该使用哪个版本。
{
  "dependencies": {
    "package-a": "^1.0.0",
    "package-b": "^2.0.0"
  },
  "resolutions": {
    "package-c": "^1.2.0"
  }
}
1
2
3
4
5
6
7
8
9

在这个示例中,我们指定了package-c的版本应该是^1.2.0。这意味着当npm安装依赖项时,它将使用1.2.x系列中的最新版本来解决package-apackage-b之间的冲突。

需要注意的是,resolutions字段只在您的项目依赖项中出现冲突时才需要使用。在大多数情况下,npm可以自动解决依赖项之间的冲突,而无需使用resolutions字段。

当某些安全扫描工具(例如sonar)扫描出项目依赖的子依赖版本需要升级的情况,也可以尝试使用此方法来解决。

package.json文件里添加跟scriptsdependenciesevDependencies平级的resolutions,把想要强制升级的子依赖期望版本写入,scripts里添加配置"preinstall": "npx force-resolutions",最后像启动项目一样使用npm run preinstall运行下载,最后达成目的。

{
  "scripts": {
    "preinstall": "npx npm-force-resolutions || echo 1",
  },
  "dependencies": {
    # 用npm运行需要安装该插件,yarn则不需要
    "npm-force-resolutions": "^0.0.10",
  },
  "resolutions": {
    "async-validator": "^4.0.0",
    "lilconfig": "^3.1.1",
    "cross-spawn": "^7.0.5"
  },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 发布配置

# private

如果是私有项目,不希望发布到公共npm仓库上,可以将private设为true

"private": true
1

# publishConfig

npm包发布时使用的配置

# 比如在安装依赖时指定了 registry 为 taobao 镜像源,但发布时希望在公网发布,就可以指定 publishConfig.registry
"publishConfig": {
  "registry": "https://registry.npmjs.org/"
}
1
2
3
4

# 系统配置

# engines

一些项目由于兼容性问题会对node或者包管理器有特定的版本号要求

"engines": {
  "node": ">=14 <16",
  "pnpm": ">7"
}
1
2
3
4

# os

linux上能正常运行的项目可能在windows上会出现异常,使用os字段可以指定项目对操作系统的兼容性要求

"os": ["darwin", "linux"]
1

# cpu

指定项目只能在特定的CPU体系上运行

"cpu": ["x64", "ia32"]

1
2

# 第三方配置

# types/typings

types/typings: 指定TypeScript的类型定义的入口文件

"types": "./index.d.ts",
1

# unpkg

npm上所有的文件都开启CDN服务

"unpkg": "dist/vue.global.js"
# 当我们想通过 CDN 的方式使用链接引入 vue 时。访问 unpkg.com/vue 会重定向到 unpkg.com/vue@3.2.37/… 3.2.27 是 Vue 的最新版本。
1
2

# jsdelivr

unpkg类似

"jsdelivr": "dist/vue.global.js",
# 访问 cdn.jsdelivr.net/npm/vue 实际上获取到的是 jsdelivr 字段里配置的文件地址
1
2

# browserslist

设置项目的浏览器兼容情况,babelautoprefixer等工具会使用该配置对代码进行转换。当然你也可以使用.browserslistrc单文件配置

"browserslist": [
  "> 1%",
  "last 2 versions"
]
1
2
3
4

# sideEffects

显示设置某些模块具有副作用,用于webpacktree-shaking优化

比如在项目中整体引入Ant Design组件库的css文件。

import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
1

如果Ant Designpackage.json里不设置sideEffects,那么webapck构建打包时会认为这段代码只是引入了但并没有使用,可以tree-shaking剔除掉,最终导致产物缺少样式。

所以Ant Designpackage.json里设置了如下的sideEffects,来告知webpack,这些文件具有副作用,引入后不能被删除

"sideEffects": [
  "dist/*",
  "es/**/style/*",
  "lib/**/style/*",
  "*.less"
]
1
2
3
4
5
6

# lint-staged

用于对git的暂存区的文件进行操作的工具,比如可以在代码提交前执行lint校验,类型检查,图片优化等操作

"lint-staged": {
  "src/**/*.{js,jsx,ts,tsx}": [
    "eslint --fix",
    "git add -A"
  ]
}
1
2
3
4
5
6

lint-staged通常配合husky这样的git-hooks工具一起使用。git-hooks用来定义一个钩子,这些钩子方法会在git工作流程中比如pre-commitcommit-msg时触发,可以把lint-staged放到这些钩子方法中

# eslintConfig

eslint的配置可以写在单独的配置文件.eslintrc.json中,也可以写在package.json文件的eslintConfig配置项中

"eslintConfig": {
  "root": true,
  "env": {
    "node": true
  },
  "extends": [
    "plugin:vue/essential",
    "eslint:recommended"
  ],
  "rules": {},
  "parserOptions": {
    "parser": "babel-eslint"
  },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# babel

babel用来指定Babel的编译配置

"babel": {
  "presets": ["@babel/preset-env"],
  "plugins": [...]
}
1
2
3
4

# gitHooks

gitHooks用来定义一个钩子,在提交(commit)之前执行ESlint检查。在执行lint命令后,会自动修复暂存区的文件。修复之后的文件并不会存储在暂存区,所以需要用git add命令将修复后的文件重新加入暂存区。在执行pre-commit命令之后,如果没有错误,就会执行git commit命令

"gitHooks": {
  "pre-commit": "lint-staged"
}
1
2
3