npm install 就是安装模块,npm run dev 就是执行npm script中的命令。当我们执行npm命令的时候,它到哪里去找,这就要说到每个node项目中都有的核心文件package.json 文件。
项目开始时,我们就要建立这个文件。假设我们要创建一个node 项目,我们会新建一个文件夹命名node, 这时我们就要创建package.json文件。进入node 文件夹,你可以手动创建,就和创建一个txt文件一样,但我们一般都会使用命令创建,打开cmd 窗口,输入npm init, 这时你要回答几个问题,如name,version 等,输入内容,一路回车键,当你输入yes的时候,package.json 创建成功,你的文件夹中多了这个文件。
其中有几个字段比较重要:
name 项目名称, 你可能在项目中使用过 var express = require(‘express’), require 函数后面的参数,就是package.json 中的name字段,所以这个name一定要简短,且不能有大写,这是规定。
version版本号:安装一个模块的时候, 你可能指定过特定的版本号,npm install express @4.13.2, 版本号4.13.2 就是我们这里的version。版本号有三个组成部分,4:表示的是大版本,一般是重大升级。13:表示的是小版本, 在大版本的基础进行的小的更新,如某个功能废弃了,新增了那个功能。2: 对该版本进行补丁,主要是版本bug的修复。
script: 我们在命令行中执行的所有命令都写在这个地方,然后用 npm run 去执行这个命令。
项目初始完成后,我们就可以进行项目开发。在开发过程中我们都会用到一些第三方库和 框架,尤其是node 开发, 因为它提供的API 有点底层. 如果想用第三方的东西,就要事先安装。上面说到 安装用的命令是npm install。 npm install express --save --save 是什么意思?--save表示,我们安装模块的时候,同时把它写到package.json 文件中。这时打开package.json 文件,我们看到多了一个dependencies字段,它包括了我们刚安装的express. node中有些es6/es7 的语法不支持,我们使用的时候,就需要进行转换。这时安装babel. npm install babel-cli babel-preset-es2015 --save–dev --save-dev 又是什么,它也表示安装依模块的时候,把它写到package.json中,不过它写入的不是dependencies, 而是devDependencies中。
无论devDependencies还是dependencies中,安装的模块版本号前面还有符号^, 其实这里还有很多符号也可以无符号,符号主要是限定版本。
"express": "4.15.2" 版本号前面什么符号都没有,它表示固定版本,安装版本时,只会安装这个指定的版本。
"express": "~4.15.2",版本号前面有符号~,它表示安装4.15.x 的版本,只x>3 就可以。在这里,我们express指定是4.15.2 版本,当我们npm install 安装的时候,它可能在项目中安装4.15.5或者4.15.6 版本。
"express": "^4.15.2" , 版本号前面有符号^, 它表示可以安装4.x.x 的版本,只要中间的x 大于15就可以。
>=4.15.3 版本号前面有符号>=, 它安装大于我们指定的版本,就可以。
有时还看到一个*, 表示安装最新版本。
版本号一定要注意,因为有些框架和库在进行版本升级的时候,向后兼容性必较差,容易引起代码冲突。但npm install 进行安装的时候,它默认是^ 符号,如果不符合我们要求,我们可以对package.json 进行手动修改,如 把^号改成~, 或直接去掉符号, package.json文件,只是一个文件, 我们可以手动地进行任何修改。
package.json和package-lock.json的区别
发现我的node项目下有一个package.json和一个package-lock.json文件,顺便扒一扒这两个的区别,其实package-lock就是锁定安装时的包版本号,需要上传到git上,以保证其他人在install时候,大家的依赖版本相同。
官方文档:这个package-lock.json 是在 `npm install`时候生成一份文件,用以记录当前状态下实际安装的各个npm package的具体来源和版本号.
跟package.json的区别在于(举个栗子):
"dependencies": { "@types/node": "^8.0.33", },
这里的^向上尖号是定义向后(新)兼容依赖,如果types/node版本是超过8.0.33,并且是在大版本(8)上相同,就允许下载最新的types/node包。同一个大版本不同版本号之间存在差异,导致依赖库包行为特征有时候不兼容。
所以npm最新的版本就开始自动生成package-lock.json功能,目的就是确保所有库包与你上次安装的完全一样。
package.json文件只能锁定大版本,即版本号的第一位,不能锁定后面的小版本,你每次npm install时候拉取的该大版本下面最新的版本,可能有些童鞋之前就踩过类似的坑。
一般为了稳定性考虑我们不能随意升级依赖包,因为如果换包导致兼容性bug出现很难排查,所以package-lock.json就是来解决包锁定不升级问题的。
如果要升级package-lock.json里面的库包,怎么操作呢?
npm install XXX@x.x.x
package.json与package-lock.json文件的作用
package.json文件记录你项目中所需要的所有模块。当你执行npm install的时候,node会先从package.json文件中读取所有dependencies信息,然后根据dependencies中的信息与node_modules中的模块进行对比,没有的直接下载,已有的检查更新(最新版本的nodejs不会更新,因为有package-lock.json文件,下面再说)。另外,package.json文件只记录你通过npm install方式安装的模块信息,而这些模块所依赖的其他子模块的信息不会记录。
package-lock.json文件锁定所有模块的版本号,包括主模块和所有依赖子模块。当你执行npm install的时候,node从package.json文件读取模块名称,从package-lock.json文件中获取版本号,然后进行下载或者更新。
因此,正因为有了package-lock.json文件锁定版本号,所以当你执行npm install的时候,node不会自动更新package.json文件中的模块,必须用npm install packagename(自动更新小版本号)或者npm install packagename@x.x.x(指定版本号)来进行安装才会更新,package-lock.json文件中的版本号也会随着更新。
附:当package.json与package-lock.json都不存在,执行"npm install"时,node会重新生成package-lock.json文件,然后把node_modules中的模块信息全部记入package-lock.json文件,但不会生成package.json文件,此时,你可以通过"npm init --yes"来生成package.json文件