欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈npm的package.json和package-lock.json

程序员文章站 2022-05-29 10:14:31
...

package.json包说明/描述文件

创建 package.json 文件

该文件不需要手动创建 , 在要创建该文件的目录下执行

npm init

会进入向导式创建

也可以使用

npm init -y

来直接创建,使用该方式创建的文件将是默认的;

package.json文件解析

{
  "name": "blog_web",//项目名称
  "version": "0.1.0",//项目版本
  "private": true,//是否是个人项目
  "scripts": {//项目可用的脚本
    "dev": "vue-cli-service serve",//例子:运行 npm run dev相当于运行vue-cli-service serve,vue-cli-service serve是vueCli的一个命令,作用是启动一个本地服务
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {//所有服务依赖(可以理解为线上依赖,他的具体名称记不住了)
    "@kangc/v-md-editor": "^1.2.12",
    "axios": "^0.19.2",
    "core-js": "^3.6.4",
    "echarts": "^4.7.0",
    "element-ui": "^2.13.0",
    "prismjs": "^1.20.0",
    "qs": "^6.9.3",
    "vue": "^2.6.11",
    "vue-axios": "^2.1.5",
    "vue-router": "^3.1.5",
    "vuex": "^3.1.2"
  },
  "devDependencies": {//所有开发依赖
    "@vue/cli-plugin-babel": "~4.2.0",
    "@vue/cli-plugin-eslint": "~4.2.0",
    "@vue/cli-plugin-router": "~4.2.0",
    "@vue/cli-plugin-vuex": "~4.2.0",
    "@vue/cli-service": "~4.2.0",
    "babel-eslint": "^10.0.3",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.1.2",
    "less": "^3.0.4",
    "less-loader": "^5.0.0",
    "vue-template-compiler": "^2.6.11"
  }
}

dependencies

线上依赖,即在运行build(打包)命令时,线上依赖会被一起打包

常见的线上依赖:(不是开发依赖就是线上依赖):element-ui,jquery,axios…

devDependencies

开发依赖,,即在运行build(打包)命令时,开发依赖不会被打包

意思就是只有开发/打包(编译)的时候才会用到的依赖

常见的开发依赖: webpack ,webpack-dev-server ,less-loader(所有loader和大部分plugin都是开发依赖) ,@vue/cli, less(所有css预处理器也都是开发依赖,为啥?因为less在结合less-loader吧.less文件编译成css就没less什么事了,线上还用它干嘛?)

main

该属性其实在上面的加载原理中已经介绍过了。

如果你写的是中间件项目,那么你还会有一个main属性,改属性指定的是中间件的入口文件

例子:现在我写了一个vue-yx的中间件,而且我的main属性值为"./index.js"。那么,如果你使用npm install vue-yx后使用import "vue-yx"的效果与使用import "vue-yx/index.js"效果一致

npm

网站:npmjs.com

查看版本

npm --version

升级npm

npm install --global npm

常用命令

  • npm init 生成 package.json
    • npm init -y 可以跳过向导快速生成 package.json
  • npm install
    • 一次性把 package.json 中的 dependencies 属性中的包全部安装
  • npm install 包名
    • 安装指定包
  • npm install --save 包名
    • 安装指定包,并将依赖信息添加到 package.json 中的 dependencies
    • npm install 包名 --save
  • npm install --save-dev 包名
    • 安装指定包,并将依赖信息添加到 package.json 中的 devDependencies
    • npm install 包名 --save-dev
  • npm uninstall 包名
    • 只删除包,不删除 package.json 中的 dependencies 中的相关信息
  • npm uninstall --sava 包名
    • 不只删除包,也删除 package.json 中的 dependencies 中的相关信息
  • npm uninstall —save-dev 包名
    • 不只删除包,也删除 package.json 中的 devDependencies 中的相关信息

包名后面可以跟@版本号来指定版本,例如 npm install --save [email protected]

install 可以简写为 i

--save 可以简写为 -S (大写)

--save-dev可以简写为-D

解决npm被墙问题

安装cnpm

# 在任意目录执行都可以
# --global 表示全局安装
# --global 不能省略
npm install --global cnpm

使用时将原来的 npm 换成 cnpm 就行啦

如果不想安装cnpm又想使用淘宝镜像怎么办

npm install jquery --registry=https://registry.npm.taobao.org

如果想一直所有淘宝镜像又嫌输入后面的 --registry=https://registry.npm.taobao.org 太麻烦怎么办?

我们可以直接配置镜像站地址

npm config set registry https://registry.npm.taobao.org
# 执行完这条命令后,以后使用npm都将通过 https://registry.npm.taobao.org 这个地址来下载


#查看 npm 配置信息
npm config list

#切换回默认的镜像
npm config delete registry
npm config delete disturl

npm新版本

在5.0以后的版本中,使用 npm -i 会自动创建或者更新一个 package-lock.json 文件,该文件相比 package.json 文件进行啦更大的优化,还可以锁定依赖的版本,和提高下载速度等等。

新版本中 --save 命令是可以省略的,系统会自动添加该命令。

package-lock.json文件

有人问lock(package-lock.json)是干嘛的,

lock出现前:

  • 1、npm -i安装命令
  • 2、获取到package.json文件中所有的依赖
  • 3、npm后台解析命令
  • 4、npm后台验证对应包及版本是否存在和是否可下载
  • 5、判断可以下载后,获取该包依赖的其他包
  • 6、重复执行第3.4步(类似于一个递归,知道对应包没有其他依赖为止)
  • 7、 npm后台命令解析结果 (得到最初目标包依赖Tree中的所有包下载地址)
  • 8、 获取解析结果中的地址开始下载
  • 9、完成

(这种方式在只是安装了少量依赖的时候区别不大,但是如果需要安装大量依赖,npm去逐个验证和解析对应依赖信息的时候后花费大量时间,所有会慢)

而lock会吧npm后台命令解析结果存储起来 (所有依赖包和其直接依赖、间接依赖的包的下载信息),这样下一次安装的时候就不需要让npm再次解析,而是直接去lock文件中获取下载地址直接下载即可

lock出现后:

  • 1、npm -i安装命令
  • 2、 获取lock文件中存储的解析结果的下载地址开始下载
  • 3、下载完

例子:

不存在lock文件时

例如项目中依赖了vue-router

  • 执行 npm -i
  • 获取到package.json文件中所有的依赖
"vue-router": "~1.8.1"

我认为这里有必要说一下package.json文件中版本的~1.8.1和^1.8.1的区别

"vue-router": "^1.8.1",//代表在1.8.1到2.0.0之间的版本(1.X.X中最新版)
"vue-router": "~1.8.1",//代表在1.8.1到1.9.0之间的版本(1.8.X中最新版)

//默认npm会帮我们加入~,而不是^
  • 来到npm后台解析
  • 解析vue-router 1.8.x最新版本
  • 得到下载地址,放入数组
  • 解析到vue-router的上线依赖-----------------------(1)
    "async-validator": "~1.8.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.0",
    "deepmerge": "^1.2.0",
    "normalize-wheel": "^1.0.1",
    "resize-observer-polyfill": "^1.5.0",
    "throttle-debounce": "^1.0.1"
  • 解析 async-validator1.8.x 版本中的最新版本
  • 得到下载地址,放入数组,回到1处
  • 解析 babel-helper-vue-jsx-merge-props2.x.x 版本中的最新版本
  • 得到下载地址,放入数组,回到1处
  • 解析 deepmerge1.x.x 版本中的最新版本
  • 得到下载地址,放入数组,回到1处
  • …直到所有依赖Tree解析完毕
  • 由数组获取解析结果的下载地址(并将数组中数据返回给客户端生成lock文件)
  • 挨个下载
  • 完成

存在lock文件时

  • 执行 npm -i

  • 获取lock文件中的数据构建成一个数组,直接获取里面的下载地址(每一个版本的下载地址不一样,由这个特点,lock实现了锁版本的功能(就是固定到精确的版本,而不是类似1.5.x中的最新版这种),这也是它为什么叫做package-lock.json(包-锁)的原因啦

  • 挨个下载

  • 完成

由于lock文件的存在,不需要npm后台再去解析依赖Tree,所以它极大的加快的下载速度哦。