前端是时候正式认识一下package.json了

4 篇文章 0 订阅
4 篇文章 0 订阅

package.json天天见,知道个scriptsdependencies,但真的还不算认识它!这两天因为想分享一些小工具,发个包啥的,所以就整理了关于package.json的一些基础知识,现在我反正是正儿八经的认识package.json了,如果像以前的我一样跟它不是很熟的朋友可以看下。

package.json字段

包的描述性配置

name(必须属性)

表示发布后的包名

至于以@xxx/开头的name字段,表示这是一个作用域包,原因是为了防止包名重复的一种解决方案,类似于创建了一个命名空间,不同的命名空间,可以使用相同的包名,作用域的命名不是随便起的,只有两种可以使用:自己的用户名、自己创建的组织名。举个具体的例子,@vue/cli这个包说明使用了vue这个npm账号或者组织发布了该包。

version(必须属性)

表示包的版本号。

如果项目是为发布npm包,则必须包含此字段。如果是普通的项目,则此字段是可选的。

每次发布的version,必须是唯一的,之前发布的时候没使用过的。

description

值即对此包的概述。

keywords

功能类似于description,npm平台上展示的关于此包的一些关键词

"keywords": [
  "vue",
  "react",
  "next"
]

homepage / repository

项目的官网主页地址 / 项目的源码地址。

也算是描述性信息罢了。

author

作者信息。

"author": {
    "name": "leon",
    "email": "582104384@qq.com",
    "url": "https://wangxiaokai.vip"
}

contributors

协作者信息。

格式是一个对象数组。对象内容和author一致。

"contributors": [{
    "name": "hanmeimei",
    "email": "hanmeimei@qq.com"
},{
    "name": "lihua",
    "email": "lihua@qq.com"
}]

license

这个表示此开源项目使用的开源协议。如:

"license": "MIT",

这里浅谈一下开源协议相关的内容,开源协议概括来说,开源协议本质就是:

  • 法律合同
  • 非签署的、使用即默认同意
  • 开源=开放代码≠无版权≠免费

然后生活场景中来讲就是某个开源项目使用了某种开源协议,是针对以后使用这个项目的用户进行要求,比如GPL协议(linux,乌班图等开源项目使用),他就要求如果你用我的源代码,你的项目就必须遵守我的开源协议里的要求。

选择开源协议的依据(说白了就是你希望别人用的源代码时要满足的要求):

总结来说,就是MIT协议是对商业最友好的,直白点说就是限制最宽松的。

功能性配置

files

files是一个文件数组,描述了将软件包作为依赖项安装时要包括的条目。如果在数组里面声明了一个文件夹,那也会包含文件夹中的文件。某些特殊文件和目录也被包括或排除在外,无论它们是否存在于文件数组中。

简而言之,别人下载我们的包所包含的文件。

比如dance-ui里只设置了dist文件夹

"files": [  "dist" ],

main

别人使用npm包时,如果通过require()的方式引入包。那么就会查看main字段,作为包的主入口文件。

module

性质等同于main字段。module用于ES6规范的模块,只要支持ES6,会优先使用module入口。换句话说别人通过import的方式引入我们的包时,实际上寻找的模块就是module字段指定的文件。

exports

用来指定脚本或子目录的别名。

概念比较抽象,来个例子就ok了:

首先package.json中配置如下

"exports": {
  "./submodule": "./src/submodule.js"
}

exports里面的即为别名(供用户使用): 实际路径的键值对,如下

import submodule from 'es-module-package/submodule';
// 等价于加载 ./node_modules/es-module-package/src/submodule.js

解释一下:exports里面键值对里,不管是键还是值,都把.视作包名,类似于一种参照,上面配置"./submodule": "./src/submodule.js"的含义就是用户引入资源时如果路径写(包名)/submodule那么就转换为(包名)/src/submodule.js

关于这个配置,还有很多更高级的用法,可以参考阮一峰老师的es6

bin

工具性质的npm包,一定有bin字段,对外暴露脚本命令。

比如webpack-cli为我们在命令行提供了webpack命令进行打包,看了下它的package.json

"bin": {
  "webpack-cli": "./bin/cli.js"
},

scripts

太熟了,就是配置一些项目操作的自动化脚本。

dependencies、devDependencies、peerDependencies

dependencies非常熟了,就是我们项目安装的直接依赖。

devDependencies与dependencies的区别就是dependencies里的依赖最终是作为项目代码的一部分(有助于功能的实现);而devDependencies里的依赖是参与项目代码实现的,比如webpack这种构建工具就属于项目的devDependencies,以为它的作用是对开发完成的项目代码进行后期处理。

peerDependencies感觉就是为了服务于发包的,就比如我们的这个库要发包,然后可以通过peerDependencies给安装我们包的用户一些提示,比如我们的包配置如下:

"peerDependencies": {
    "react": ">=16.8.0"
}

那么安装我们包的用户的项目如果react的版本不满足要求,控制台就会给警告。这也就是我们安装一些依赖时控制台经常会报peerDependencies警告的原因,就是因为我们安装的这个包,他本身对一些依赖有版本要求,我们项目里的依赖版本不符合要求。

types

项目如果是用TypeScript写的,则需要types字段,对外暴露相关的类型定义。比如dance-ui(ts编写的react组件库)项目:

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

猜测这就是某些开源库对类型支持友好的原因吧(因为导出了.d.ts文件)

workspaces

对于monorepo架构的项目(现在的工具库主流架构,不知道的朋友建议去补补课,很有意思),有必要配置workspaces指明所有子项目的工作目录(子项目根目录),这样应该才支持各个子项目之间作为依赖互相安装使用。这个配置毕竟不是个性化配置,子项目有啥配啥就完事了,反正肯定就能保证项目的正常工作了,比如packages文件夹下的所有(直接)子文件夹都是子项目(支持使用通配符,*表示直接文件夹,不包含嵌套文件夹):

"workspaces": [
  "packages/*"
],

发布相关的配置

private

private和发布npm包相关。

private: true时,npm会拒绝发布当前项目。这是防止意外发布个人仓库的一种保护方式。

看了下,公司里的业务项目都设置了这个字段为true。(发布出去怕是会犯法😂)

我试了一下,private设置为true之后即使设置了publishConfig字段是不生效的,一些文档(官方)与文章中写到publishConfig可以搭配private:true然后成功发包,我不理解啊!chatgpt很肯定的告诉我:private设置为true之后是铁定发不出去包的,他没摇摆,我很感动。

publishConfig

这个配置项是一个对象,里面有registryaccesstag三个比较常用(我感觉够用)的字段

  • registry:对应我们的包的下载地址(npm源),我们发包的时候就会把包发到这个源里,比如我们可能因为嫌npm慢然后把registry设置为国内的一些镜像源,这个字段不设置的话应该默认就是https://registry.npmjs.org/(不然怎么会发到npm上呢哈哈)
  • access:默认值就是public,表示我们的包是开放的,大家都可以下载,然后还有个取值restricted,我试着发布了一下,失败了,好像要求包必须是一个作用域包(作用域包相关看name字段),感觉这个accessregistry一样,都用默认值就完事了(发包的初衷不就是发布到npm,并且让所有人都能用么😁)
  • tag:默认值是lastest,表示最新,说白了这玩意有点像git commit-m,登录到npm查看发包历史,每次发布都能看到有个tag字段。

跟三方库相关的配置

sideEffects

sideEffects格式:boolean | string[]

sideEffects: false用于告知打包工具(webpack),当前项目无副作用,可以使用tree shaking优化。

sideEffects的值,也可以是一个文件路径组成的数组。告知哪些文件有副作用,不可以使用tree shaking优化。

"sideEffects": [
    "a.js",
    "b.js"
]

并且,由于tree shaking只在production模式生效,所以本地开发会一切正常,生产环境很难及时发现这个问题。

当然, 样式文件使用"import xxx;"的方式引入,会进行保留。

上面是这篇文章里的描述,但是原文有一定的错误,已经进行了修正,并且我谈下我对sideEffects的理解:生产模式下,webpack打包时会开启tree-shaking,本质上就是webpack对程序打包的一种优化手段,但是tree-shaking要保证程序的正确运行为前提,所以一段代码该不该被tree-shaking掉,本身有一定的判断逻辑,所以sideEffects字段就是辅助webpack去进行tree-shaking的,如果设置为false,就表示项目里没有那种一定存在副作用的代码文件,所以可以走webpack本身的tree-shaking逻辑,但是如果sideEffects里面指定了一些存在副作用的代码文件,那么就说明这些文件如果被引用,即使webpack本身的逻辑判断他们没有副作用,可以被删除掉,那么也会因为sideEffects的配置而被保留,所以算是一个webpack进行tree-shaking的辅助配置。

其它

还有一些如babel、eslint、gitHooks等相关的配置,作者现在还没用到,感兴趣的参考这篇文章

发包

这就比较简单了,对于拥有package.json文件的项目(或者不是项目...),npm login登陆上我们的npm账号后,执行npm publish就完事了,完全依据我们配置的package.json,就把代码上传到npm上了,然后别人就可以安装使用了。

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值