vue3 已经出了一段时间了,其生态来讲应该已经比较健壮了,但是今天在使用vite+vue3的时候,出现了一个棘手的问题,就是更新.vue文件的时候, 没有热更新,浏览器无响应,网页刷新也不行,只能通过重新run来解决, 这个问题还只涉及我一个公共components里面的一个组件的修改, 其他组件还不受影响, 找了半天才解决这个问题。
问题场景
- 首先来看问题如何出现的, 当我们在使用
vite + vue3
的项目的时候, 每一次修改文件, 那么控制台都会进行一个hrm update
的操作 如下: 但是在我更新我其中一个组件的时候, 每次只会在第一次更新的时候, 执行一次hrm update
, 大家可以看上图,每次更新同一个问题,都会执行, 其会在后面显示次数 如(x2), 但唯独我这个文件不会, 第二次更新的时候没有热更新,且浏览器无响应。刷新无相应。必须重新run
。 如下图: - 文件配置如下, 首先是
package.json
然后是vite.config
: - package.json
{
"name": "my-vue-app",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"prepare": "husky install",
"pre-commit": "lint-staged",
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
"lint-staged": "lint-staged"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^10.9.0",
"axios": "^1.6.8",
"crypto-js": "^4.2.0",
"element-plus": "^2.6.3",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1",
"vue": "^3.4.31",
"vue-router": "^4.3.0",
"unplugin-vue-define-options": "^1.3.5"
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx,vue}": [
"eslint --fix",
"prettier --write",
"git add"
],
"*.{scss,less,styl,html}": [
"prettier --write"
]
},
"devDependencies": {
"@types/axios": "^0.14.0",
"@types/crypto-js": "^4.2.2",
"@types/node": "^20.11.30",
"@types/path-browserify": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"@vitejs/plugin-vue": "^5.0.4",
"eslint": "^8.34.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-vue": "^9.23.0",
"husky": "^8.0.0",
"less": "^4.2.0",
"lint-staged": "^10.5.4",
"mockjs": "^1.1.0",
"prettier": "^3.2.5",
"typescript": "^5.4.2",
"unplugin-auto-import": "^0.17.5",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.3.3",
"vite-plugin-mock": "2.9.6",
"vite-plugin-svg-icons": "^2.0.1",
"vite-svg-loader": "^5.1.0",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vue-tsc": "^1.8.27"
}
}
- vite.config
可以看到我这个文件里面server
的配置 有一行是hmr: true
,这个也是找了网上一些方案, 配置了一下,其实这个删掉我也试了,无所谓, 因为本身vite
配置的默认值就是true
。
import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import { viteMockServe } from 'vite-plugin-mock';
// element-plus按需引入
import AutoImport from 'unplugin-auto-import/vite';
import VueSetupExtend from 'vite-plugin-vue-setup-extend';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
// svg
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import svgLoader from 'vite-svg-loader';
import DefineOptions from 'unplugin-vue-define-options/vite'; // 给标签式 setup 加 name
// https://vitejs.dev/config/
/**
* 配置 Vite 开发环境的函数
*
* @param config - Vite 提供的配置对象,包含当前的命令和模式等信息
* @returns 返回一个配置对象,用于定制 Vite 的行为
*/
export default defineConfig((config) => {
const { command, mode } = config;
const env = loadEnv(mode, process.cwd());
return {
base: './',
define: {
'process.env': {},
},
// 配置需要使用的插件列表
plugins: [
viteMockServe({
// 只在开发阶段开启 mock 服务,mock和后端服务器接口能共存,可以通过配置来区分
localEnabled: command === 'serve',
}),
vue(),
DefineOptions(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
// * name 可以写在 script 标签上
VueSetupExtend(),
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
symbolId: 'icon-[dir]-[name]',
}),
// * vite-svg-loader支持,可以直接引入svg图标当作组件使用
svgLoader(),
],
resolve: {
alias: {
// 配置别名
'@': path.resolve(__dirname, './src'),
},
},
css: {
preprocessorOptions: {
less: {
math: 'always',
// 允许使用 js 表达式
javascriptEnabled: true,
// 引入全局变量
additionalData: `@import "${path.resolve(__dirname, 'src/styles/common.less')}";`,
},
},
},
server: {
hmr: true,
host: 'localhost',
port: Number(env.VITE_APP_PORT), // 服务器端口,从环境变量读取
proxy: {
[env.VITE_APP_BASE_API]: {
target: 'https://bizfw.dev.d2d.ai/gateway', // 代理地址
changeOrigin: true, // 允许跨域
// rewrite: (path) => path.replace(/^\/rest/, ''), // 重写路径,移除前缀
},
},
},
};
});
问题解决
- 首先肯定是网上看看大家有没有遇到这种情况, 搜到的很多都是一些命名不规范,产生此类问题的,而 官方库 github.com/vitejs/vite… 里面也有很多记录,大家也可以查看。
- 我之前一个同样的项目是没有这个问题的,我详细对照了两个项目的包版本,发现差异还是比较大,然后我把有关
vue
的版本都进行了降低,和我之前的项目进行了同步,再重新run
这个项目 就没有问题了。 下面是版本差异对照。
我觉得这里可能降低版本的只需要vite-plugin-vue
就够了~