你不知道的package.json

engines

描述模块的兼容性如:

指定模块运行的node版本

{
  "engines": {
    "node": ">=0.10.3 <15"
  }
}

指定模块运行的npm版本

{
  "engines": {
    "npm": "~1.0.20"
  }
}

禁止使用yarn

{
  "engines": {
    "yarn": "please use npm"
  }
}

files

指定发布到npm中的文件,默认是所有文件["*"] 你也可以通过.npmignore防止某些文件被包含在内,它不会覆盖files字段,但会覆盖其子目录。 如果不存在.npmignore将使用.gitignore替代

一般来说npm上我们只需要发布打包好的文件,对于git则恰好相反我们只需要提交源代码

bin

安装可执行文件 如果你的包都有一个或多个想要安装到 PATH 中的可执行文件,请在package.json中提供一个bin字段,它是命令名到本地文件名的映射。当这个包被全局安装时,该文件将被链接到全局bin所在的位置,因此它可以按名称运行。当这个包作为另一个包的依赖项安装时,该文件将被链接到该包可以直接通过 npm exec 或通过 npm run-script 调用它们时在其他脚本中的名称, 以typescript举例,在package.json文件中存在

{
  "bin": {
      "tsc": "./bin/tsc",
      "tsserver": "./bin/tsserver"
  },
}

全局安装

所以通过全局安装npm install -g typescript 我们可以在命令行中使用tsc命令, 通过which tsc 我们可以查看可执行文件在/Users/chenkai/.nvm/versions/node/v14.17.1/bin/tsc $PATH中定义了/Users/chenkai/.nvm/versions/node/v14.17.1/bin目录,所以我们可以直接运行tsc命令

作为另一个包的依赖项安装

此时我们不能作为全局命令使用tsc, 但是在node_modules/.bin中多了tsc文件指向node_modules/typescript/bin/tsc,我们可以在scripts中调用tsc

{
  "scripts": {
    "build": "tsc index.ts"
  }
}

dependencies

设置包的依赖项,dependencies设置的依赖包也会被默认安装到node_modules。 一般用来存放代码运行中实际依赖的包。

devDependencies

设置包的依赖项,和dependencies不同的是,只有在该包根目录执行npm link或者npm install时才会被安装到node_modules。当你把该包作为一个依赖时,devDependencies设置的依赖包*不会被安装到node_modules。 一般用来存放打包(rollup、esbuild、webpack)、构建(typescript)、测试(jest)等只有在开发环境依赖的包。

peerdependencies

设置包的依赖项, peerdependencies设置的依赖包表达您的包与主机工具或库的兼容性, 如你开发了一个vue组件库需要指定在vue 3.x版本中使用,可以这样设置

{
  "peerdependencies": {
    "vue": "^3.0"
  }
}

如果用户安装了该组件库,并且安装peerdependencies设置的依赖包与用户安装的依赖包指定的版本不一致时,npm会提示vue版本不兼容的信息

npm v7开始如果用户没有安装peerdependencies设置的依赖包, peerdependencies设置的依赖包会被默认安装到node_modules

workspaces

它支持从单个顶级根包中管理本地文件系统中的多个包,避免手动使用 npm link 来添加对应符号链接到当前 node_modules 文件夹的包的引用。如 当前工作目录中,包含一个名为 workspace-a 的文件夹,其中本身包含一个 package.json

.
+-- package.json
`-- workspace-a
   `-- package.json

在当前工作目录中运行 npm install 后, 文件夹 workspace-a 将符号链接到当前工作目录的 node_modules 文件夹

.
+-- node_modules
|  `-- workspace-a -> ../workspace-a
+-- package-lock.json
+-- package.json
`-- workspace-a
   `-- package.json

其他

module

指定模块入口文件,不同于main字段,将指向一个具有 ES2015 模块语法的模块入口文件,你可以与main字段同时命名,当你用es6语法导入时,打包工具(rollup,webpack)会优先使用该字段对应的入口文件,

{
  "name": "my-package",
  "version": "0.1.0",
  "main": "dist/my-package.umd.js",
  "module": "dist/my-package.esm.js"
}

type

type字段定义了 Node.js 用于所有以 package.json 文件作为其最近父级的 .js 文件的模块格式。 当最近的父 package.json 文件包含值为“module”的顶级字段type时,以 .js 结尾的文件将作为 ES 模块加载。

exports

exports 字段允许定义包的入口点,当通过 node_modules 查找或对其自身名称的自引用加载的名称导入时。 Node.js 12+ 支持它作为“main”的替代方案,

{
  "name": "a-package",
  "exports": {
    ".": "./main.mjs",
    "./foo": "./foo.js"
  }
}

并且exports还支持按条件导出

{
  "type": "module",
  "main": "./index.cjs",
  "exports": {
    "import": "./wrapper.mjs",
    "require": "./index.cjs"
  }
}