一、起因
elemenu-ui只支持vue2.x的版本,而我们整个项目是基于vue3的,想在Vue3.x中使用,需要引入element-plus~
- 安装:
npm install element-plus --save
// 或者:
yarn add element-plus --save
- main.ts中引入:
import { createApp } from 'vue'
import ElementPlus from 'element-plus';
import 'element-plus/lib/theme-chalk/index.css';
import App from './App.vue';
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
OK,正常work!
二、问题
之前按照上述步骤安装element-plus能正常work,然而某天我新增了一个依赖包并npm install之后element-plus却一直报错,debug了好久,终于发现了问题所在。原来是因为element-plus近期更新比较频繁,npm install之后安装了最新版本,导致了一系列的错误。
试了试更新Vue版本至Vue3.3+,可以正常使用element-plus,但这又导致我们项目中使用的另一个包出现了问题不能正常work,最后还是将element-plus回退到了之前的版本。
// eg:
npm i element-plus@1.0.2-beta.71 --save
三、深入
1、devDependencies与dependencies
我们在使用npm install 安装模块或插件的时候,有两种命令将其写入到package.json文件:
--save-dev 和 --save
// 简写形式:
-D 和 -S
它们的区别在于:使用--save-dev安装的模块或插件,会被写入到devDependencies里面,而使用--save安装的,则是被写入到dependencies里面。
package.json里面的devDependencies和dependencies对象又有什么区别呢?
devDependencies里面的插件只用于开发环境,不用于生产环境,而dependencies是需要发布到生产环境的。比如我们写项目页面要依赖于element-plus,没有这个包的依赖运行就会报错,这时候就需要写入dependencies;而我们使用的一些构建工具比如webpack这些只是在开发中使用的包,上线后就和它们没关系了,所以将它们写入devDependencies。
2、npm install发生了什么
大致流程:
(1)确定首层依赖——package.json中dependencies 和 devDependencies 属性中直接指定的依赖;
(2)递归获取模块:模块信息——模块实体——模块依赖;
(3)模块扁平化:去掉冗余模块;(v3之后)
(4)安装模块,更新node_modules;
(5)生成或更新版本描述文件。
3、npm install的不确定性
前面提到我遇到的问题是因为npm install时自动更新了版本,npm的依赖版本管理非常宽松,同一个项目一天之内可能会install不同版本的依赖,而依赖包的升级很有可能带来bug。
我们在dependencies里面指定的版本号称为语义化版本号,这里插播一下语义化版本号的规则:主版本号.次版本号.修订号,并且版本号的递增规则如下:
- 主版本号:做了不兼容的 API 修改
- 次版本号:做了向下兼容的功能性新增
- 修订号:做了向下兼容的问题修复
依赖的版本范围用三种符号指定:
- ~:只升级修订号
- ^:升级次版本号和修订号
- *:升级到最新版本
比如我们的package.json里有这样的依赖:
"dependencies": {
"echarts": "^5.1.1",
"vue": "^3.0.11"
},
我们就知道^是什么意思 & npm install的时候会安装什么了。在这个例子中,如果echarts的版本超过5.1.1并在大版本号(5)上相同,就允许下载最新的echarts包,我们npm install的时候下载的具体版本号可能是5.2.1(或者别的)。
语义化版本号定义了我们理想的版本更新规则,但在实际安装时依赖版本有可能和我们指定的不一致,这就是npm install的不确定性问题。为了解决这一问题,npm在5.0+默认会生成package-lock.json文件“锁”住版本号。
自npm 5.0版本发布以来,npm install的规则发生了三次变化:
- npm 5.0.x 版本,不管package.json怎么变,npm install时都会根据package-lock.json文件下载;
- 5.1.0版本后,npm install会无视package-lock.json文件去下载最新的包;
- 5.4.2版本后,如果改了package.json,且package.json和package-lock.json文件不同,那么执行npm install时npm会根据package.json中的版本号以及语义含义去下载最新的包,并更新至package-lock.json。如果两者是同一状态,那么执行npm install会根据package-lock.json下载,不会理会package.json实际包的版本是否有更新。
4、npm install相关问题排查
我们拿到一个项目,要本地运行起来的第一步一般都是执行npm install,但往往npm install的时候并不顺利,常常报错。我们一般怎么去解决呢?
1、根据报错信息debug
报错的原因千千万,不能一言以蔽之,这时候还需要具体问题具体对待。
2、查看node版本和registry
通过查看node版本和registry,可以判断是不是因为项目所依赖的包和我们所使用的node版本存在不兼容问题,或是我们要下载的包是通过当前registry下载不到的,从而排查问题。
3、清除npm缓存
npm会缓存每个包的具体版本和下载链接,后续就不需要再去远程仓库进行查询,从而减少了大量网络请求。但是缓存也可能导致问题出现,试试清除缓存:
npm cache clean --force
4、尝试yarn
有时候npm install报错,但yarn install却能成功安装。yarn的出现是为了解决npm v3版本的问题,它除了带来安装速度的提升以外,最大的贡献是通过lock文件来保证安装依赖的确定性,不论在何种环境何种机器上安装依赖都会得到相同的结果,也就是相同的node_modules目录结构。
四、总结
通过此次debug,学到了:
(1)安装依赖时,选择合适的--save-dev 或 --save;
(2)安装依赖时单独安装,避免手动修改 package.json 或 yarn.lock 等文件;
(3)npm install报错时该怎么去排查问题。