package.json
在 Node.js 中,模块是一个库或框架,也是一个 Node.js 项目。Node.js 项目遵循模块化的架构,当我们创建了一个 Node.js 项目,意味着创建了一个模块,这个模块的描述文件,被称为 package.json。
package.json 属性说明:
name : 这个很好理解,就是package的名称。不过需要注意的是,name有长度限制(虽然一般都不会超),而且name不能以 【点】 或者 【下划线】开头,name中不能有大写字母。这个是每一个package必须的。在业务代码中,通过require(${name})就可以引入对应的程序包了;
version : package的版本。对于业务项目来说,这个往往不太重要,但是如果你要发布自己的项目,这个就显得十分重要了。name和version共同决定了唯一一份代码。npm是用npm-semver来解析版本号的。我们一般见到的都是大版本.次要版本.小版本这种版本号,比如16.1.0。版本号的规则、含义其实蛮多的,可以参考这篇文章。;
description : 包的描述。开发组件库时必需,简明的向库的使用者介绍这个库是干嘛的。对整个代码结构的描述。告诉代码包使用者可以在哪里找到对应的文件,对于公司的业务项目,这个配置项一般无所谓;
files:数组。表示代码包下载安装完成时包括的所有文件。
author : 包的作者,它的值是你在 网站的有效账户名,遵循“账户名<邮件>”的规则,例如:zhangsan zhangsan@;可以为字符串,对象。
contributors :包的其他贡献者;author的数组。
main : 指定了程序的主入口文件,这个字段的默认值是模块根目录下面的 index.js;代码入口。这个十分重要,特别是对于组件库。当你想在node_modules中修改你使用的某个组件库的代码时,首先在node_modules中找到这个组件库,第一眼就是要看这个main,找到组件库的入口文件。在这个入口文件中再去修改代码吧。
keywords : 关键词。一个字符串数组,对这个npm包的介绍。组件库必需,便于使用者在npm中搜索。对于公司业务项目,这个配置一般无所谓。
homepage: 包的官网URL;项目主页。对于开发组件库来说挺有用的。
bugs:开发者的联系方式,代码库的issues地址等。如果代码使用者发现了bug,可以通过这个配置项找到提bug的地方。
license:开源协议。对于开源组件库,这个十分重要。之前react还因为这事儿没少被社区嫌弃。开源协议略微复杂,用阮一峰前辈的一张图来说明一下吧。注:图里少了ISC, ISC和BSD差不多
config:用于添加命令行的环境变量。具体用法见这里。
bundledDependencies:数组,打包时的依赖。如果配置了bundledDependencies,在项目中执行 npm pack将项目打包时,最后生成的.tgz包中,会包含bundledDependencies中配置的依赖。bundledDependencies中的依赖必须在devDependencies或者dependencies中声明过。
peerDependencies: 指定当前组件的依赖以其版本。如果组件使用者在项目中安装了其他版本的同一依赖,会提示报错。
engines:指定项目所依赖的node环境、npm版本等。
private:如果设为true,无法通过npm publish发布代码。
bin:用来指定各个内部命令对应的可执行文件的路径。具体用法这里不多讲了。详情可以点击这里。
scripts:指定了运行脚本命令的npm命令行缩写。十分重要。
来看一个例子:
"scripts": {"dev": "NODE_ENV=dev webpack-dev-server --progress --hot --host 0.0.0.0 --port 8089","test": "NODE_ENV=test webpack --config webpack.test.config.js --progress","online": "NODE_ENV=production webpack --config webpack.online.config.js --progress","build": "webpack","node": "node server.js"},
在命令行输入:npm run dev , 对应的命令就会被执行。这里有一个地方需要注意,当执行npm run xxx的时候,node_modules/.bin/目录会在运行时被加入系统的PATH变量。上面的例子,当我们在命令行输入:npm run build时,其实真正执行的命令是node_modules/.bin/webpack而不是webpack。所以,当你的webpack并未全局安装时,直接在命令行输入:webpack是会报错的。因为你的webapck是安装在node_modules/.bin/下面的。
repository : 对于组件库很有用。让组件库使用者找到你的代码库地址。这个配置项会直接在组件库的npm首页生效。
例子:
"repository": {"type": "git","url": "git+/CoyPan/react-scroll-to-show-cb.git"},
devDependencies:项目的依赖。通过npm run install --save-dev安装的包会出现在这里。主要是在开发过程中依赖的一些工具。用法与dependencies相似。 dependencies:项目的依赖。通过npm install --save安装的包会出现在这里。注意,不要把测试工具、代码转换器或者打包工具等放在这里。当你在命令行里面使用npm install react --save时,react就会出现在dependencies。默认是安装最新的版本。如果想安装某个特定的版本,可以npm install react@15.6.2。以下的dependencies,格式都是合法的,
"dependencies" : {"foo" : "1.0.0 - 2.9999.9999","bar" : ">=1.0.2 <2.1.2","baz" : ">1.0.2 <=2.3.4","boo" : "2.0.1","qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0","asd" : "/asdf.tar.gz","til" : "~1.2","elf" : "~1.2.3","two" : "2.x","thr" : "3.3.x","lat" : "latest","dyl" : "file:../dyl"}
我们常见的是下面这些:
"dependencies": {"foo": "1.0.0", // 指定了就是1.0.0版本"bar": "~1.2.2", // 安装版本号不低于1.2.2的1.2.x的最新版本,例如:1.2.3, 1.2.4等等。1.2.1 ,1.3.x 等就不行了"baz": "ˆ1.2.2", // 安装版本号不低于1.2.2的1.x.x的最新版本,例如: 1.2.7,1.3.1,1.7.8等。1.2.1 ,2.0.0 等就不行了。注意,如果配置是^0.x.x,则和~0.x.x的效果一样。"lat": "latest" // 安装最新版本}
dependencies 还可以像下面这样配置:
"dependencies": {"foo": "git+ssh://git@:foo/foo.git#v1.0.1",}
foo组件的地址为git+ssh://{foo代码库的ssh地址}#v{foo的版本号}
这样的配置在下面这种场景十分有用:
组内的许多项目都有同一个功能,把这个功能抽出来做成组件是很自然的想法。但是每个项目都有自己的代码库,公司也没有内部的npm库,组件应该放在哪里呢?可以专门为组件新建一个代码仓库,将组件放在这里开发、迭代。这样,各个项目都可以引用该组件:只需要在dependencies中将组件配置成上述的形式。至于组件的版本,可以通过git tag来控制。
dependencies还有其他的配置方式,具体在这里查看。
每个项目的根目录下面,一般都有一个 package.json 文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install
命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。package.json 文件可以手工编写,也可以使用npm init
命令自动生成。
package-lock.json
package-lock.json 是在npm install
时候生成的一份文件,用以记录当前状态下实际安装的各个 npm package 的具体来源和版本号。package-lock.json 文件的作用锁定安装时的包的版本号,并且需要上传到 git,以保证其他人在npm install
时大家的依赖能保证一致。
它有什么用呢?因为 npm 是一个用于管理 package 之间依赖关系的管理器,它允许开发者在 pacakge.json 中标出自己项目对 npm 各库包的依赖。可以选择以如下方式来标明自己所需要库包的版本
"dependencies": {"@angular/core": "~7.2.0","tslib": "^1.9.0"}//package.json
这里面的向上标号^ 是定义了向后(新)兼容依赖,指如果 tslib 版本是超过1.9.0,并在大版本号(1)上相同,就允许下载最新版本的 tslib 库包,例如实际上可能运行npm install
时候下载的具体版本是1.9.3。波浪号大多数情况这种向新兼容依赖下载最新库包的时候都没有问题,可是因为npm是开源世界,各库包的版本语义可能并不相同,有的库包开发者并不遵守严格这一原则:相同大版本号的同一个库包,其接口符合兼容要求。这时候用户就很头疼了:在完全相同的一个 nodejs 的代码库,在不同时间或者不同 npm 下载源之下,下到的各依赖库包版本可能有所不同,因此其依赖库包行为特征也不同有时候甚至完全不兼容。
因此 npm 最新的版本就开始提供自动生成 package-lock.json 功能,为的是让开发者知道只要你保存了源文件,到一个新的机器上、或者新的下载源,只要按照这个 package-lock.json 所标示的具体版本下载依赖库包,就能确保所有库包与你上次安装的完全一样。
"tslib": {"version": "1.9.3","resolved": "/tslib/-/tslib-1.9.3.tgz","integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="}//package-lock.json
版本号
(1) 波浪号(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。
(2) 插入号(caret)+指定版本:比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
(3) latest:安装最新版本
所以建议使用~来标记版本号,这样可以保证项目不会出现大的问题,也能保证包中的小 bug 可以得到修复。
(4) 固定指定版本:比如1.2.2,安装时只安装指定版本。遵循“大版本.次要版本.小版本”的格式规定,
关于使用
package.json 文件只能锁定大版本,也就是版本号的第一位,并不能锁定后面的小版本,npm install
都是拉取的该大版本下的最新的版本,为了稳定性考虑我们几乎是不敢随意升级依赖包的,这将导致多出来很多工作量,测试/适配等,所以 package-lock.json 文件出来了,当你每次安装一个依赖的时候就锁定在你安装的这个版本。
那如果我们安装时的包有bug,后面需要更新怎么办?
在以前可能就是直接改 package.json 里面的版本,然后再npm install
了,但是 5 版本后就不支持这样做了,因为版本已经锁定在 package-lock.json 里了,所以我们只能npm install xxx@x.x.x
这样去更新我们的依赖,然后 package-lock.json 也能随之更新。
总结
本文涵盖了package.json绝大部分的配置项。我的观点是:如果是公司的业务项目,对于package.json,一般情况下,我觉得只需要关注好scripts,dependencies,devDependencies这三个地方就够了。而对于开源的组件库,则至少需要关注好上面标黑的几个点。理解好重要配置的含义,提升开发效率,减少踩坑的概率。
其它博客介绍
如果觉得《package.json和package-lock.json的详细介绍和版本号介绍》对你有帮助,请点赞、收藏,并留下你的观点哦!