记录--工程化第一步这个package.json要真的搞明白才行
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
工程化最开始就是package.json开始的,很多人学了很多年也没搞清楚这个为什么这么神奇,其实有些字段是在特定场景才有效的,那每个属性的适用场景和作用是什么,又牵扯很多知识点,今天先解读一些常见的属性,关注我,后期在遇到特定场景也会再逐步的补充这些属性,只有真正清楚知道每个自动的属性和场景你才能真正使用它得心应手,也才能真正掌握并帮助你解决你的问题。
创建
一个package.json 你可以使用npm init 按指令创建,也可以通过npm init -y来快速创建,当然也可以手动来创建,那现在我们创建一个。 package.json
{
"name": "package-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
这个是原装的属性,当然还有一些额外的场景才有的,接下来我们来逐步分析:
常用属性
这些属性没有没有太复杂,但还是要仔细看看每个都可以做什么,适用于什么场景,如何去使用和配置
name
package.json 中最重要字段之一就是名称name 字段,有人的说为什么我没有配置也没有影响我项目的正常运行呢?这个是因为你没有发布npm 包,这个name就是你发布到npm的包名,如果你不打算发布你的包到npm上这个是可以省略的。
当然这个名称也不是随便乱起的,它也有一定的规则,否则有警告的如下:
字符串与 "^(?:(?:@(?:[a-z0-9-*~][a-z0-9-*._~]*)?/[a-z0-9-._~])|[a-z0-9-~])[a-z0-9-._~]*$" 的模式不匹配。
name的规则如下:
- 名称必须少于或等于 214 个字符。 这包括范围包的范围。
- 范围包的名称可以以点或下划线开头。 没有范围是不允许的。
- 新包的名称中不得包含大写字母。
- 该名称最终成为 URL、命令行参数和文件夹名称的一部分。 因此,名称不能包含任何非 URL 安全字符
version
这个是版本,跟name 字段差不多,基本是一起的,因为它们共同构成一个假定完全唯一的标识符,如果你不发布包也是这个省略这个字段的,当然这个字段值也不是随意写的,它完全基于符合语义化版本(Semantic Versioning)来管理依赖的版本,所以版本号的更新需要符合语义化版本规范,简单总结:可以被 semver 包可解析的,当然你也可以使用这个semver 进行版本的操作,具体可以看我的另一篇版本号文章版本号
keywords
这个也是发布到npm 上才有用的,它的作用也是别人可以通过搜索来查找你的包,或是通过npm search xxx开查找你的包 如下,我有两个运行时的包处理react preact 的className的,可以看看查出了什么:
PS D:\lucky-file\package-demo> npm search 'react runtime clsx'
NAME | DESCRIPTION | AUTHOR | DATE | VERSION | KEYWORDS
react-auto-clsx | | =crazy-code | 2023-10-10 | 1.1.0 | react vite webpack className clsx runtime
react-runtime-clsx | | =zsh-yzy | 2023-11-30 | 0.0.1 | react vite webpack className clsx runtime
react-auto-classnames | JSX runtime for… | =meowtec | 2022-09-30 | 1.0.2 | react classnames clsx jsx-runtime
PS D:\lucky-file\package-demo>
是不是几个包的信息,所以这个是搜索查找用的,如果你不发布这个也可以不写的
homepage
项目主页的 url。随便找个npm 包,可以看一下,该包的右侧有个地址就是这个字段进行配置的

bugs
这个就是要需要作者给个地址,比如你写的包有问题,别人怎么给你提问题,联系到你 通常我们设置的issue地址,那如何打开呢,可以通过如下方式:
npm bugs [<pkgname> [<pkgname> ...]]
license
指定一个许可证,以便人们知道他们如何被允许使用它,以及你对其施加的任何限制,常见的开源协议是 MIT 和 BSD,如果我们不确定我们应该如何写,可以看一下网上这个图说的比较清晰借用一下:

author
它表示项目的作者信息,它既可以是一个字符串,又可以是一个对象
"author":{
"name": "lvz",
"email": "xxxx@xx.com",
"url": "https://xxxxx"
}
或者使用字符串的形式也可以
"author": "lvz <xxxxx@xx.com> (https://xxxxx)"
contributors
contributors 它表示的是贡献者,是一个数组,当然这个也有两种写法
"contributors": [
"lvz1 <xxxxx@xx.com> (https://xxxxx)"
]
或者对象的写法
"contributors":[
{
"name": "lvz1",
"email": "xxxx@xx.com",
"url": "https://xxxxx"
}
]
funding
如果你不开源,对资金没有要求或有其它渠道可以不使用,这个是在npm 6.13.0添加了funding命令,针对开源者,让维护 npm 的开发人员,为有意愿的捐赠者指明捐赠平台。在 package.json 文件中添加了一个funding字段,指向在线捐赠服务的 url,如 Patreon、Open 或者其他支付网站,并可以通过npm fund命令列出这些捐赠平台及其 url。
"funding": [
{
"type": "patreon",
"url": "http://XXXXXX"
},
"http://XXXXX",
{
"type": "open",
"url": "https://XXXXXX"
}
]
files
项目在进行 npm 发布时,可以通过 files 指定需要跟随一起发布的内容来控制 npm 包的大小,避免安装时间太长,比如我们包体有很多文件,但我们只想把dist放进去,其他src,test文件并不想放在包体中,可以使用这个字段
但无论设置如何,总是会包含某些文件:
package.jsonREADMECHANGES/CHANGELOG/HISTORYLICENSE/LICENCENOTICE- “main”字段中的文件 相反,某些文件总是被忽略:
.gitCVS.svn.hg.lock-wscript.wafpickle-N.*.swp.DS_Store._*npm-debug.log.npmrcnode_modulesconfig.gypi*.origpackage-lock.json
当然除了files 也有其它方式可以来忽略文件进入包体,我们先看一下我们什么也不处理的文件格式

- 添加.gitignore文件
src/*
example/*
我们发布之后在看一下文件结构,只有index.js 也就是main字段指向的index.js还有package.json两个文件

- 添加.npmignore 文件
src/*
example
同样我们发布之后看一下文件结构,如下图所示:

.npmignore在程序包的根目录下,它不会覆盖“files”字段,但在子目录中,它将覆盖。该
.npmignore文件的工作方式与一样.gitignore。如果有.gitignore文件但.npmignore缺少文件,.gitignore则将使用的内容
repository
简单点说就是配置仓库地址,这个配置后,可以在npm 包首页看到仓库地址入口,可以进行点击查看
"repository": {
"type": "git",
"url": "https://github.com/xxxxx",
"directory": "xxxx/xxx"
}
当然你也可以直接写字符串
"repository":"https://github.com/xxxxx/xxxx"
config
配置对象可用于设置在升级后持续存在的包脚本中使用的配置参数
"config": {
"type": "chrome"
},
我们在index.js中进行打印一下
console.log(process.env.npm_package_config_type)
此时如果你直接node index.js 你会发现打印的是个undefined,我们在将其放在scripts中:
"scripts": {
"start": "node index.js"
},
再执行就可以打印出值了,这样我们就可以在脚本中使用了这个环境变量了。
依赖配置项
这个是我们这次的重点之一,其实有些朋友经常分不清,这些到底怎么回事,我们先整体分析一下,我们安装一个包有两种,一种是当前项目package.json 已有的,一种是安装包中package.json的依赖,那针对这个我们做个实验再总结一下看看它们都是什么妖魔鬼怪。
我们在介绍version这个字段的时候,讲解了如何安装一个指定范围的npm包,如果有疑问可以进去查看哈,这里就不再赘述了
背景 有两个项目,一个是project-demo,一个是package-demo,包名是lucky-package-demo,project-demo会依赖lucky-package-demo这个包。 如下project-demo 中的package.json
"dependencies": {
"lucky-package-demo": "*"
}
devDependencies
简单理解就是这个包是开发环境用到了,生产环境并不需要它,比如我们的webpack,vite,或是eslint等
我们在package-demo 中安装 vite
"devDependencies": {
"vite": "4.3.0"
}
然后我们在project-demo更新lucky-package-demo后,可以看到project-demo的node_modules中发现react 和 react-demo 已经被安装了,虽然暂时我们并没有去使用这两个包,也就是说dependencies中的包将会被安装
peerDependencies
也叫同等依赖,它主要用于确保多个模块在同一个主模块的上下文中使用,并共享依赖的版本,简单来说就是project-demo项目中已经安装react了,package-demo中我没必要在dependencies依赖这个react了。从而避免项目中和依赖包中出现重复安装包所导致的包版本不相容、打包了多份不同版本的库等问题,我们举几个常遇到的问题来解释一下这个属性。
- 我有一个组件库,依赖了react,项目中我也要使用react并且已经安装好了,组件库和项目可以共享react
- 但有个问题,我项目更新了,react的版本和组件库react的版本不一致了,还是共享,如何避免冲突
安装方式:
我们可以配合一些属性使用,在依赖包中,因为我们不会在项目包中安装,可以放在devDependencies中,我们又想告诉项目包我们需要什么范围内的版本,就需要设置peerDependencies,如下:
package-demo中如下配置
"devDependencies": {
"react": "17.0.2",
"vite": "4.3.0"
},
"peerDependencies": {
"react":">16.8.0 <18.0.0"
}
如果我们在project-demo中安装的是 react:"17.0.1",此时是满足我们依赖包中peerDependencies中对react的版本范围要求的,安装很顺利,项目和依赖包会共享17.0.1的react的包,也不会存在任何警告。
dependencies:
- lucky-package-demo
+ lucky-package-demo 0.0.10
- react
+ react 17.0.1 (18.2.0 is available)
dependencies:
- lucky-package-demo
+ lucky-package-demo 0.0.10
- react
+ react 16.8.0 (18.2.0 is available) WARN Issues with peer dependencies found
.
└─┬ lucky-package-demo 0.0.10
└── ✕ unmet peer react@">16.8.0 <18.0.0": found 16.8.0
peerDependenciesMeta
如果 peerDependencies 中指定的包尚未安装,npm 将发出警告,如下配置将对等依赖标记为可选,如果用户没有安装对等依赖,npm不会发出警告
"peerDependenciesMeta":{
"react":{
"optional":true
}
}
在project-demo中安装lucky-package-demo,可以发现node_modules中并不存在react的包,控制台也没有任何的警告出现
npm i -S lucky-package-demo
如果设置成optional:false中,在project-demo中安装lucky-package-demo后将会自动安装符合范围的react的包
bundleDependencies
npm的命令 -B, --save-bundle
语法:npm i -B [package-name]
这个属性使用的较少,通过在 bundleDependencies 数组中指定包名称,在发布包时,包名的数组会被打包进去,有的说我试过但发布包什么也没有呢?因为单单配置bundleDependencies这个是没有效果的,需要再在依赖包中安装devDependencies或dependencies中才能将其打包到node_modules中。举例说明:
在package-demo 中进行如下安装和配置,并在project-demo中npm i -S lucky-package-demo安装,你会发现project-demo中的node_modules中lucky-package-demo的node_modules中是bundleDependencies中配置的react-runtime-clsx包
"dependencies": {
"react-runtime-clsx": "0.0.1"
},
"bundleDependencies": [
"react-runtime-clsx"
]
当然你可以在package-demo跟目录执行npm pack,和安装lucky-package-demo一样,可以看看目录结构:
project-demo
----node_modules
-------lucky-package-demo
-----------node_modules
---------------react-runtime-clsx //这个是bundleDependencies配置的
---------------clsx 这个是react-runtime-clsx的依赖
optionalDependencies
通过npm 命令 -O, --save-optional
npm i -O [package-name]
optionalDependencies 用于定义可选依赖项,和 dependencies 非常类似,主要的差别在于:在 optionalDependencies 中的依赖包安装报错甚至找不到时不会影响到包管理器的安装行为
npm i -O react-runtime-clsx
// package-demo package.json 如下:
"optionalDependencies": {
"react-runtime-clsx": "0.0.1"
}
optionalDependencies中的条目将覆盖dependencies中的同名条目,因此通常最好只放在一个位置
overrides
如果需要对依赖项的依赖项进行特定更改,例如将依赖项的版本替换为已知的安全问题,将现有依赖项替换为分支,或者确保在任何地方都使用相同版本的包,则可以添加覆盖。
package-demo中package.json 配置
"optionalDependencies": {
"react-runtime-clsx": "0.0.1"
}
具体的大家可以看一下文档overrides文档)
项目中的依赖
项目中我们也会有依赖,有些是辅助开发的工具,有些是项目引用的代码包,因为项目我们是不会发布它作为npm包来使用的,它作为的是一个工程,所以在依赖上是有区分的,你是不是也有下面的困惑呢?
我随便装的并不影响到开发和构建,似乎这两者没有区别,安装哪里都一样呢?
感觉是对的,其实项目中这两者并没有明显的划分,只是我们通常是将开发中使用的安装到devDependencies,运行使用的放在dependencies,其实这两个都是安装了的,无论你放哪都可以使用,所以也有部分刚接触时很困惑,因为这个针对的是npm发布包有用的,在项目中还是按规范了养成习惯,清楚每个的含义,对我们做npm包的发布是有用的哈
本文转载于:
https://juejin.cn/post/7315606159742058530
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--工程化第一步这个package.json要真的搞明白才行的更多相关文章
- 第二章第一个项目——package.json
在其中写版本好的时候, { "name": "chatroom", "version": "0.0.1", " ...
- Docker+Cmd+Cli+Git之前端工程化纪要(二)自定义类package.json文件管理模块包
全新升级后的FE工作流为:使用FE命令包进行项目的初始化,其中包括项目初始化.拉取脚手架.私库拉取模块包或后期扩展的CI/CD等与本公司工作流相关的操作. 出现的问题如下: 脚手架工具的包依赖信息存放 ...
- ElasticSearch第一步-环境配置
ElasticSearch第一步-环境配置 ElasticSearch第二步-CRUD之Sense ElasticSearch第三步-中文分词 ElasticSearch第四步-查询详解 Elasti ...
- java微信开发API第一步 服务器接入
I如何接入服务器,下面就为大家进行介绍 一.说明 * 本示例根据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/2016 5:34 ...
- 基于gulp编写的一个简单实用的前端开发环境好了,安装完Gulp后,接下来是你大展身手的时候了,在你自己的电脑上面随便哪个地方建一个目录,打开命令行,然后进入创建好的目录里面,开始撸代码,关于生成的json文件请点击这里https://docs.npmjs.com/files/package.json,打开的速度看你的网速了注意:以下是为了演示 ,我建的一个目录结构,你自己可以根据项目需求自己建目
自从Node.js出现以来,基于其的前端开发的工具框架也越来越多了,从Grunt到Gulp再到现在很火的WebPack,所有的这些新的东西的出现都极大的解放了我们在前端领域的开发,作为一个在前端领域里 ...
- 零代码第一步,做个添加数据的服务先。node.js + mysql
node.js + mysql 实现数据添加的功能.万事基于服务! 增删改查之添加数据. 优点:只需要设置一个json文件,就可以实现基本的添加功能,可以视为是零代码. 添加数据的服务实现的功能: 1 ...
- package-lock.json和package.json的作用
转自:https://www.cnblogs.com/cangqinglang/p/8336754.html package-lock.json的作用就是锁定安装依赖时包的版本,并且需要上传到git, ...
- npm使用入门(package.json)
npm使用入门 crazygit 关注 2017.03.10 18:31 字数 1773 阅读 1617评论 0喜欢 10 NPM是什么 npm npm makes it easy for JavaS ...
- npm 与 package.json 快速入门
npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解了一些,这次结合官方文章总结一下,加深下理解吧! 读完本文你将了解: 什么是 npm 安装 npm 更新 npm ...
- 十二、Nodejs 包与 NPM 第三方模块安装 package.json 以及 CNPM
1. 包 Nodejs 中除了它自己提供的核心模块外,我们可以自定义模块,也可以使用第三方的模块.Nodejs 中第三方模块由包组成,可以通过包来对一组具有相互依赖关系的模块进行统一管理. 在 Nod ...
随机推荐
- .NET周刊【2月第1期 2024-02-04】
祝大家新年快乐,龙年大吉~ 国内文章 C#/.NET/.NET Core优秀项目和框架2024年1月简报 https://www.cnblogs.com/Can-daydayup/p/18000401 ...
- NC22598 Rinne Loves Edges
题目链接 题目 题目描述 Rinne 最近了解了如何快速维护可支持插入边删除边的图,并且高效的回答一下奇妙的询问. 她现在拿到了一个 n 个节点 m 条边的无向连通图,每条边有一个边权 \(w_i\) ...
- C语言,变长数组的用法
在我的<C语言,结构体成员的地址>文章中,定义了一个demo_node结构体,其中用到变长数组char addr[0].本文以此为例,对C语言变长数组的基本用法展开介绍. typedef ...
- Java 递归的方式将list集合的某一字段拼接单个String
场景介绍 要将list 集合中的某一个字段合并成一个字符串,并且要用符号 "|" 分割开每个拼接后的字段. 一个例子胜于一切的文字表达,拼接后的结果如下 str1|str2|str ...
- 【framework】AMS启动流程
1 前言 AMS 即 ActivityManagerService,负责 Activy.Service.Broadcast.ContentProvider 四大组件的生命周期管理.本文主要介绍 A ...
- diffstat命令
diffstat命令 diffstat命令根据diff的比较结果,统计各文件的插入.删除.修改等差异计量. 语法 diffstat [options] [files] 参数 -c: 输出的每一行都以# ...
- wordpress设置固定链接404及伪静态配置
说明 最近在将wordpress设置中文章url修改为月份和名称型 之后访问文章出现404.原因是配有配置好apache的伪静态. 配置步骤 1.修改httpd.conf 我这里是centos7,默认 ...
- Java中的包装类(wrapper class)
1.介绍 顾名思义,包装类是封装Java原始类型的对象.每个Java原始类型都有一个对应的包装类: 基本类型 包装类 boolean Boolean byte Byte short Short cha ...
- 文心一言 VS 讯飞星火 VS chatgpt (201)-- 算法导论15.2 6题
六.用go语言,证明:对 n 个元素的表达式进行完全括号化,恰好需要 n-1 对括号. 文心一言,代码正常运行: 在Go语言中,证明对n个元素的表达式进行完全括号化恰好需要n-1对括号,可以通过数学归 ...
- RK3568开发笔记(一):瑞芯微RK3568芯片介绍,入手开发板的核心板介绍
前言 目前主流国产芯片为RV11XX.RK33XX.Hi35XX系列,本系列开启RK3568系列的技术教程笔记分享. 本篇主要介绍RK3568芯片和入手开发板的核心板详细介绍. RK3568 ...
