package.json 是前端每个项目都有的 json 文件,位于项目的根目录。许多脚手架在搭建项目时也会自动帮我们自动初始化好 package.json。
package.json 里面有许许多多的配置,与项目息息相关,了解它们有助于了解项目,提效开发,规范代码。
今天主要介绍一些常见配置,我把它们分为了 7 大类:
主要是项目的基本信息,包括名称,版本,描述,仓库,作者等,部分会展示在 npm 官网上。

项目的名称,如果是第三方包的话,其他人可以通过该名称使用 npm install 进行安装。
"name": "react"
复制
项目的版本号,开源项目的版本号通常遵循 semver 语义化规范,具体规则如下图所示:

简单介绍一下:
1 代表主版本号 Major,通常在涉及重大功能更新,产生了破坏性变更时会更新此版本号2 代表次版本号 Minor,在引入了新功能,但未产生破坏性变更,依然向下兼容时会更新此版本号3 代表修订号 Patch,在修复了一些问题,也未产生破坏性变更时会更新此版本号除了 X.Y.Z 这样的标准版本号,还有 Pre-release 和 Metadata 来描述项目的测试版本,关于 semver 规范更多的内容,可以参考https://juejin.cn/post/7122240572491825160 。
回到 package.json 的 version 字段,name + version 能共同构成一个完全唯一的项目标识符,所以它两是最重要的两个字段。
"version": "18.2.0"
复制
项目的仓库地址以及版本控制信息。
"repository": {
"type": "git",
"url": "<https://github.com/facebook/react.git>",
"directory": "packages/react"
}
复制
项目的描述,会展示在 npm 官网,让别人能快速了解该项目。
"description": "React is a JavaScript library for building user interfaces."
复制
一组项目的技术关键词,比如 Ant Design 组件库的 keywords 如下:
"keywords": [
"ant",
"component",
"components",
"design",
"framework",
"frontend",
"react",
"react-component",
"ui"
],
复制
好的关键词可以帮助别人在 npm 官网上更好地检索到此项目,增加曝光率。
项目主页的链接,通常是项目 github 链接,项目官网或文档首页。
"homepage": "<https://reactjs.org/>"
复制
项目 bug 反馈地址,通常是 github issue 页面的链接。
"bugs": "<https://github.com/vuejs/core/issues>"
复制
项目的开源许可证。项目的版权拥有人可以使用开源许可证来限制源码的使用、复制、修改和再发布等行为。常见的开源许可证有 BSD、MIT、Apache 等,它们的区别可以参考:如何选择开源许可证?https://www.ruanyifeng.com/blog/2011/05/how_to_choose_free_software_licenses.html
"license": "MIT"
复制
项目作者。
"author": "Li jiaxun",
复制
包括项目所包含的文件,以及入口等信息。
项目在进行 npm 发布时,可以通过 files 指定需要跟随一起发布的内容来控制 npm 包的大小,避免安装时间太长。
发布时默认会包括 package.json,license,README 和main 字段里指定的文件。忽略 node_modules,lockfile 等文件。
在此基础上,我们可以指定更多需要一起发布的内容。可以是单独的文件,整个文件夹,或者使用通配符匹配到的文件。
"files": [
"filename.js",
"directory/",
"glob/*.{js,json}"
]
复制
一般情况下,files 里会指定构建出来的产物以及类型文件,而 src,test 等目录下的文件不需要跟随发布。
在 node 支持 ES 模块后,要求 ES 模块采用 .mjs 后缀文件名。只要遇到 .mjs 文件,就认为它是 ES 模块。如果不想修改文件后缀,就可以在 package.json文件中,指定 type 字段为 module。
"type": "module"
复制
这样所有 .js 后缀的文件,node 都会用 ES 模块解释。
# 使用 ES 模块规范
$ node index.js
复制
如果还要使用 CommonJS 模块规范,那么需要将 CommonJS 脚本的后缀名都改成.cjs,不过两种模块规范最好不要混用,会产生异常报错。
项目发布时,默认会包括 package.json,license,README 和main 字段里指定的文件,因为 main 字段里指定的是项目的入口文件,在 browser 和 Node 环境中都可以使用。
如果不设置 main 字段,那么入口文件就是根目录下的 index.js。
比如 packageA 的 main 字段指定为 index.js。
"main": "./index.js"
复制
我们引入 packageA 时,实际上引入的就是 node_modules/packageA/index.js。
这是早期只有 CommonJS 模块规范时,指定项目入口的唯一属性。
main 字段里指定的入口文件在 browser 和 Node 环境中都可以使用。如果只想在 web 端使用,不允许在 server 端使用,可以通过 browser 字段指定入口。
"browser": "./browser/index.js"
复制
同样,项目也可以指定 ES 模块的入口文件,这就是 module 字段的作用。
"module": "./index.mjs"
复制
当一个项目同时定义了 main,browser 和 module,像 webpack,rollup 等构建工具会感知这些字段,并会根据环境以及不同的模块规范来进行不同的入口文件查找。
"main": "./index.js",
"browser": "./browser/index.js",
"module": "./index.mjs"
复制
比如 webpack 构建项目时默认的 target 为 'web',也就是 Web 构建。它的 resolve.mainFeilds 字段默认为 ['browser', 'module', 'main']。
module.exports = {
//...
resolve: {
mainFields: ['browser', 'module', 'main'],
},
};
复制
此时会按照 browser -> module -> main 的顺序来查找入口文件。
node 在 14.13 支持在 package.json 里定义 exports 字段,拥有了条件导出的功能。
exports 字段可以配置不同环境对应的模块入口文件,并且当它存在时,它的优先级最高。