package。json配置完全解读
package。json是前端每个项目都有的json文件,位于项目的根目录。许多脚手架在搭建项目时也会自动帮我们自动初始化好package。json。
package。json里面有许许多多的配置,与项目息息相关,了解它们有助于了解项目,提效开发,规范代码。今天主要介绍一些常见配置,我把它们分为了7大类:
描述配置
文件配置
脚本配置
依赖配置
发布配置
系统配置
第三方配置1。描述配置
主要是项目的基本信息,包括名称,版本,描述,仓库,作者等,部分会展示在npm官网上。
name
项目的名称,如果是第三方包的话,其他人可以通过该名称使用npminstall进行安装。name:react
version
项目的版本号,开源项目的版本号通常遵循semver语义化规范,具体规则如下图所示:
简单介绍一下:1代表主版本号Major,通常在涉及重大功能更新,产生了破坏性变更时会更新此版本号2代表次版本号Minor,在引入了新功能,但未产生破坏性变更,依然向下兼容时会更新此版本号3代表修订号Patch,在修复了一些问题,也未产生破坏性变更时会更新此版本号
除了X。Y。Z这样的标准版本号,还有Prerelease和Metadata来描述项目的测试版本,关于semver规范更多的内容,可以参考https:juejin。cnpost7122240572491825160。
回到package。json的version字段,nameversion能共同构成一个完全唯一的项目标识符,所以它两是最重要的两个字段。version:18。2。0
repository
项目的仓库地址以及版本控制信息。repository:{type:git,url:https:github。comfacebookreact。git,directory:packagesreact}
description
项目的描述,会展示在npm官网,让别人能快速了解该项目。description:ReactisaJavaScriptlibraryforbuildinguserinterfaces。
keywords
一组项目的技术关键词,比如AntDesign组件库的keywords如下:keywords:〔ant,component,components,design,framework,frontend,react,reactcomponent,ui〕,
好的关键词可以帮助别人在npm官网上更好地检索到此项目,增加曝光率。
homepage
项目主页的链接,通常是项目github链接,项目官网或文档首页。homepage:https:reactjs。org
bugs
项目bug反馈地址,通常是githubissue页面的链接。bugs:https:github。comvuejscoreissues
license
项目的开源许可证。项目的版权拥有人可以使用开源许可证来限制源码的使用、复制、修改和再发布等行为。常见的开源许可证有BSD、MIT、Apache等,它们的区别可以参考:如何选择开源许可证?https:www。ruanyifeng。comblog201105howtochoosefreesoftwarelicenses。htmllicense:MIT
author
项目作者。author:Lijiaxun,2。文件配置
包括项目所包含的文件,以及入口等信息。
files
项目在进行npm发布时,可以通过files指定需要跟随一起发布的内容来控制npm包的大小,避免安装时间太长。
发布时默认会包括package。json,license,README和main字段里指定的文件。忽略nodemodules,lockfile等文件。
在此基础上,我们可以指定更多需要一起发布的内容。可以是单独的文件,整个文件夹,或者使用通配符匹配到的文件。files:〔filename。js,directory,glob。{js,json}〕
一般情况下,files里会指定构建出来的产物以及类型文件,而src,test等目录下的文件不需要跟随发布。
type
在node支持ES模块后,要求ES模块采用。mjs后缀文件名。只要遇到。mjs文件,就认为它是ES模块。如果不想修改文件后缀,就可以在package。json文件中,指定type字段为module。type:module
这样所有。js后缀的文件,node都会用ES模块解释。使用ES模块规范nodeindex。js
如果还要使用CommonJS模块规范,那么需要将CommonJS脚本的后缀名都改成。cjs,不过两种模块规范最好不要混用,会产生异常报错。
main
项目发布时,默认会包括package。json,license,README和main字段里指定的文件,因为main字段里指定的是项目的入口文件,在browser和Node环境中都可以使用。
如果不设置main字段,那么入口文件就是根目录下的index。js。
比如packageA的main字段指定为index。js。main:。index。js
我们引入packageA时,实际上引入的就是nodemodulespackageAindex。js。
这是早期只有CommonJS模块规范时,指定项目入口的唯一属性。
browser
main字段里指定的入口文件在browser和Node环境中都可以使用。如果只想在web端使用,不允许在server端使用,可以通过browser字段指定入口。browser:。browserindex。js
module
同样,项目也可以指定ES模块的入口文件,这就是module字段的作用。module:。index。mjs
当一个项目同时定义了main,browser和module,像webpack,rollup等构建工具会感知这些字段,并会根据环境以及不同的模块规范来进行不同的入口文件查找。main:。index。js,browser:。browserindex。js,module:。index。mjs
比如webpack构建项目时默认的target为web,也就是Web构建。它的resolve。mainFeilds字段默认为〔browser,module,main〕。module。exports{。。。resolve:{mainFields:〔browser,module,main〕,},};
此时会按照browsermodulemain的顺序来查找入口文件。
exports
node在14。13支持在package。json里定义exports字段,拥有了条件导出的功能。
exports字段可以配置不同环境对应的模块入口文件,并且当它存在时,它的优先级最高。
比如使用require和import字段根据模块规范分别定义入口:exports:{require:。index。js,import:。index。mjs}}
这样的配置在使用importxxx和require(xxx)时会从不同的入口引入文件,exports也支持使用browser和node字段定义browser和Node环境中的入口。
上方的写法其实等同于:exports:{。:{require:。index。js,import:。index。mjs}}}
为什么要加一个层级,把require和import放在。下面呢?
因为exports除了支持配置包的默认导出,还支持配置包的子路径。
比如一些第三方UI包需要引入对应的样式文件才能正常使用。importpackageAdistcssindex。css;
我们可以使用exports来封装文件路径:exports:{。style:。distcssindex。css},
用户引入时只需:importpackageAstyle;
除了对导出的文件路径进行封装,exports还限制了使用者不可以访问未在exports中定义的任何其他路径。
比如发布的dist文件里有一些内部模块distinternalmodule,被用户单独引入使用的话可能会导致主模块不可用。为了限制外部的使用,我们可以不在exports定义这些模块的路径,这样外部引入packageAdistinternalmodule模块的话就会报错。
结合上面入口文件配置的知识,再来看看下方vite官网推荐的第三方库入口文件的定义,就很容易理解了。
workspaces
项目的工作区配置,用于在本地的根目录下管理多个子项目。可以自动地在npminstall时将workspaces下面的包,软链到根目录的nodemodules中,不用手动执行npmlink操作。
workspaces字段接收一个数组,数组里可以是文件夹名称或者通配符。比如:workspaces:〔workspacea〕
表示在workspacea目录下还有一个项目,它也有自己的package。json。package。jsonworkspaceapackage。json
通常子项目都会平铺管理在packages目录下,所以根目录下workspaces通常配置为:workspaces:〔packages〕3。脚本配置
scripts
指定项目的一些内置脚本命令,这些命令可以通过npmrun来执行。通常包含项目开发,构建等CI命令,比如:scripts:{build:webpack}
我们可以使用命令npmrunbuildyarnbuild来执行项目构建。
除了指定基础命令,还可以配合pre和post完成命令的前置和后续操作,比如:scripts:{build:webpack,prebuild:xxx,build执行之前的钩子postbuild:xxxbuild执行之后的钩子}
当执行npmrunbuild命令时,会按照prebuildbuildpostbuild的顺序依次执行上方的命令。
但是这样的隐式逻辑很可能会造成执行工作流的混乱,所以pnpm和yarn2都已经废弃掉了这种prepost自动执行的逻辑,参考pnpmissue讨论https:github。compnpmpnpmissues2891
如果需要手动开启,pnpm项目可以设置。npmrcenableprepostscriptstrue。enableprepostscriptstrue
config
config用于设置scripts里的脚本在运行时的参数。比如设置port为3001:config:{port:3001}
在执行脚本时,我们可以通过npmpackageconfigport这个变量访问到3001。console。log(process。env。npmpackageconfigport);30014。依赖配置
项目可能会依赖其他包,需要在package。json里配置这些依赖的信息。
dependencies
运行依赖,也就是项目生产环境下需要用到的依赖。比如react,vue,状态管理库以及组件库等。
使用npminstallxxx或则npminstallxxxsave时,会被自动插入到该字段中。dependencies:{react:18。2。0,reactdom:18。2。0}
devDependencies
开发依赖,项目开发环境需要用到而运行时不需要的依赖,用于辅助开发,通常包括项目工程化工具比如webpack,vite,eslint等。
使用npminstallxxxD或者npminstallxxxsavedev时,会被自动插入到该字段中。devDependencies:{webpack:5。69。0}
peerDependencies
同伴依赖,一种特殊的依赖,不会被自动安装,通常用于表示与另一个包的依赖与兼容性关系来警示使用者。
比如我们安装A,A的正常使用依赖B2。x版本,那么B2。x就应该被列在A的peerDependencies下,表示如果你使用我,那么你也需要安装B,并且至少是2。x版本。
比如React组件库AntDesign,它的package。json里peerDependencies为peerDependencies:{react:16。9。0,reactdom:16。9。0}
表示如果你使用AntDesign,那么你的项目也应该安装react和reactdom,并且版本需要大于等于16。9。0。
optionalDependencies
可选依赖,顾名思义,表示依赖是可选的,它不会阻塞主功能的使用,安装或者引入失败也无妨。这类依赖如果安装失败,那么npm的整个安装过程也是成功的。
比如我们使用colors这个包来对console。log打印的信息进行着色来增强和区分提示,但它并不是必需的,所以可以将其加入到optionalDependencies,并且在运行时处理引入失败的逻辑。
使用npminstallxxxO或者npminstallxxxsaveoptional时,依赖会被自动插入到该字段中。optionalDependencies:{colors:1。4。0}
peerDependenciesMeta
同伴依赖也可以使用peerDependenciesMeta将其指定为可选的。peerDependencies:{colors:1。4。0},peerDependenciesMeta:{colors:{optional:true}}
bundleDependencies
打包依赖。它的值是一个数组,在发布包时,bundleDependencies里面的依赖都会被一起打包。
比如指定react和reactdom为打包依赖:bundleDependencies:〔react,reactdom〕
在执行npmpack打包生成tgz压缩包中,将出现nodemodules并包含react和reactdom。
需要注意的是,这个字段数组中的值必须是在dependencies,devDependencies两个里面声明过的依赖才行。
普通依赖通常从npmregistry安装,但当你想用一个不在npmregistry里的包,或者一个被修改过的第三方包时,打包依赖会比普通依赖更好用。
overrides
overrides可以重写项目依赖的依赖,及其依赖树下某个依赖的版本号,进行包的替换。
比如某个依赖A,由于一些原因它依赖的包foo1。0。0需要替换,我们可以使用overrides修改foo的版本号:overrides:{foo:1。1。0patch}
当然这样会更改整个依赖树里的foo,我们可以只对A下的foo进行版本号重写:overrides:{A:{foo:1。1。0patch,}}
overrides支持任意深度的嵌套。
如果在yarn里也想复写依赖版本号,需要使用resolution字段,而在pnpm里复写版本号需要使用pnpm。overrides字段。5。发布配置
主要是和项目发布相关的配置。
private
如果是私有项目,不希望发布到公共npm仓库上,可以将private设为true。private:true
publishConfig
顾名思义,publishConfig就是npm包发布时使用的配置。
比如在安装依赖时指定了registry为taobao镜像源,但发布时希望在公网发布,就可以指定publishConfig。registry。publishConfig:{registry:https:registry。npmjs。org}6。系统配置
和项目关联的系统配置,比如node版本或操作系统兼容性之类。这些要求只会起到提示警告的作用,即使用户的环境不符合要求,也不影响安装依赖包。
engines
一些项目由于兼容性问题会对node或者包管理器有特定的版本号要求,比如:engines:{node:1416,pnpm:7}
要求node版本大于等于14且小于16,同时pnpm版本号需要大于7。
os
在linux上能正常运行的项目可能在windows上会出现异常,使用os字段可以指定项目对操作系统的兼容性要求。os:〔darwin,linux〕
cpu
指定项目只能在特定的CPU体系上运行。cpu:〔x64,ia32〕7。第三方配置
一些第三方库或应用在进行某些内部处理时会依赖这些字段,使用它们时需要安装对应的第三方库。
types或者typings
指定TypeScript的类型定义的入口文件types:。index。d。ts,
unpkg
可以让npm上所有的文件都开启CDN服务。
比如vuepackage。json的unpkg定义为distvue。global。jsunpkg:distvue。global。js,
当我们想通过CDN的方式使用链接引入vue时。
访问https:unpkg。comvue会重定向到https:unpkg。comvue3。2。37distvue。global。js,其中3。2。27是Vue的最新版本。
jsdelivr
与unpkg类似,vue通过如下的配置jsdelivr:distvue。global。js,
访问https:cdn。jsdelivr。netnpmvue实际上获取到的是jsdelivr字段里配置的文件地址。
browserslist
设置项目的浏览器兼容情况。babel和autoprefixer等工具会使用该配置对代码进行转换。当然你也可以使用。browserslistrc单文件配置。browserslist:〔1,last2versions〕
sideEffects
显示设置某些模块具有副作用,用于webpack的treeshaking优化。
比如在项目中整体引入AntDesign组件库的css文件。importantddistantd。css;orantddistantd。less
如果AntDesign的package。json里不设置sideEffects,那么webapck构建打包时会认为这段代码只是引入了但并没有使用,可以treeshaking剔除掉,最终导致产物缺少样式。
所以AntDesign在package。json里设置了如下的sideEffects,来告知webpack,这些文件具有副作用,引入后不能被删除。sideEffects:〔dist,esstyle,libstyle,。less〕
lintstaged
lintstaged是用于对git的暂存区的文件进行操作的工具,比如可以在代码提交前执行lint校验,类型检查,图片优化等操作。lintstaged:{src。{js,jsx,ts,tsx}:〔eslintfix,gitaddA〕}
lintstaged通常配合husky这样的githooks工具一起使用。githooks用来定义一个钩子,这些钩子方法会在git工作流程中比如precommit,commitmsg时触发,可以把lintstaged放到这些钩子方法中。8。结语
今天我们简单了解了package。json的常见配置。有了这些知识,我敢说绝大多数项目的package。json你都能毫无压力的阅读。
但package。json里的内容远不止如此,比如semver规范,入口文件,项目依赖等都还有很多值得深入的内容,认识他们只是第一步。9。参考
https:docs。npmjs。comcliv8configuringnpmpackagejson
https:zhuanlan。zhihu。comp548202395byWangHaoyu
https:juejin。cnpost7095903278084390948by摸鱼的春哥
https:juejin。cnpost7122240572491825160by摸鱼的春哥
https:zhuanlan。zhihu。comp29855253by风清洋
https:juejin。cnpost7023539063424548872byCUGGZ
https:segmentfault。coma1190000016365409bysenntyou
https:github。comSunshowerCblogissues8bySunshowerC
https:www。ruanyifeng。comblog202008hownodejsusees6module。htmlby阮一峰
羊群遍地,真为共和国的新生儿出生率捏把汗一对结婚2年的小夫妻,到现在没有添娃,问其原因,说:不敢,等疫情结束后再考虑。如果这样的情况存在很多,那么势必会影响我们国家的新生儿数量。但是,像这样的情况从心理上……
泰坦尼克号唯一幸存的日本人一生受尽唾骂,直到死才揭露真相在《泰坦尼克号》这部唯美的爱情电影中,罗丝和杰克两个人为了爱情,不顾等级的限制,不顾外人的眼光,他们只享受彼此带来的快乐。然而他们的幸福只有一天,夜晚来临之际,灾难接踵而至,他……
南京不是我开不起玩笑,是你们玩笑开太多了,老实人也会生气这里是刘小顺的旅行和生活研究所。说到长三角地区,被大家开玩笑开得最多的大城市,如果南京排第二,恐怕也没谁敢排第一了。南京这座城市在长三角的地位很特殊,各方面都很强,……
三餐该何时吃?专家曝最佳时间,可防心脏病衰老何时进食对健康的影响,近来成为关注焦点,日本专长时间营养的早稻田大学教授柴田重信表示,早餐在睡醒后立即吃是最理想的,否则最晚要在睡醒后2小时内吃完;午餐则在早餐后5小时后;晚餐……
投资290亿!京东方拟于北京建LTPO第6代新型半导体显示器10月30日晚间,京东方A发布公告称,公司下属控股子公司北京京东方创元科技有限公司拟在北京经济技术开发区投资建设应用LTPO技术的第6代新型半导体显示器件生产线项目,着力布局V……
hinova10正式开售大家好我是甜童!hinova10在10月20号开了发布会后,昨天才正式开售!其中Hinova10Pro采用了星耀工艺搭配星环设计,提供10号色、绮境森林、普罗旺斯、曜金黑……
灵动双眸设计,小米Civi2自拍更出彩前不久,小米Civi2正式发布,创新的灵动双眸设计带来小米史上最强的前置影像系统,配合全新的仿生双眸技术,在前置影像上带来优秀的表现。小米Civi2采用3200万像素超清……
魅族19系列新机曝光代号或为凤凰影像性能全面提升视频加载中。。。一个特立独行的品牌,一个不断创新却举步维艰的品牌。魅族手机,多少人心中的MX梦想手机。在学生时代的魅族MX2手机,我称其为魅族梦想2,初上手温润尔雅……
10后文学这是一个新奇的世界,等待了一个冬天的小花非常激动。当它还是一枚种子的时候,它就开始期待着美丽的春天,这种期待刻在它的基因里,成为一种执念。在一个风和日丽的午后,小花正在惬……
A股三大迹象表明,明天很可能会大幅下跌在股市里没有谁可以依靠,也不会有谁会出来帮助你,任何自封大师或者老师的人,一定是另有目的的,所以以后会多写点能启发大家思考的文章,下面我就给大家指出今天的三个迹象,大家自己思考……
10款Steam冬季特卖史低游戏推荐,自爆船战术让玩家心生畏可能是因为圣诞节的原因,冬季特卖成为了Steam一年中力度最大的游戏促销活动。下面我就来给大家推荐10款Steam冬季特卖里面的史低价游戏,它们有些能为玩家省下几百元,是每一个……
黑龙江游记之六十一哈尔滨篇依兰五国头城十六徽宗、钦宗在上京住了2个多月,于天会六年10月往南行,回到塞州一面城附近的韩州。12月26日,抵韩州(今辽宁昌图县八面城)。作为徽钦二宗二迁之地,与在那里的宋俘虏会合,韩州是个……