vue-cli项目迁移至vite项目

项目上遇到了需要将vue-cli项目迁移至vite的情况,完成迁移后记录一下。

vue-cli项目迁移至vite项目

分析项目结构

  • 分析package.json的依赖及版本:确保项目上的功能依赖都能更新成vite项目所需;如果没对应的依赖,是否有替换方案。
  • 特殊插件:是否有针对特殊业务需求处理所使用的插件或依赖,例如svg-sprite-loader在vite中就用不了,就要替换一下。
  • 分析可能存在的兼容问题:例如require使用、环境变量等等。

卸载vue-cli相关依赖

可能每个项目情况不同,但大致都有这些:

1
2
3
4
5
6
7
8
9
10
11
12
//"dependencies"
"svg-sprite-loader": "^6.0.11", //webpack支持的svg-icon插件

//"devDependencies"
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"vue-loader": "^17.1.0"

添加vite相关依赖

1
2
3
4
5
6
7
//"dependencies"
"vite-plugin-html": "^3.2.2", //用于在html里注入变量,例如title

//"devDependencies"
"@vitejs/plugin-vue": "^5.0.5",
"vite": "^5.3.1",
"vite-plugin-svg-icons": "^2.0.1" //取代上面的"svg-sprite-loader"

修改配置

添加并修改vite.config.js

对比原vue.config.js,在根目录新建vite.config.js,争取做到功能复刻

给出一套配置,仅供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { createHtmlPlugin } from 'vite-plugin-html';
import { fileURLToPath, URL } from 'node:url';
import { resolve } from 'path';
import { defineConfig,loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import { codeInspectorPlugin } from 'code-inspector-plugin';


export default defineConfig(({command, mode }) => {
console.log("=>(vite.config.js:15) mode", mode);
// const env = loadEnv(mode, process.cwd());
// console.log("=>(vite.config.js:16) env", env);

const isProduction = mode === 'production';

return {
plugins: [
vue(),
// HTML 插件
createHtmlPlugin({
inject: {
data: {
title: '智慧交通-统一信控平台'
}
}
}),
// 使用 svg 图标
createSvgIconsPlugin({
iconDirs: [resolve(process.cwd(), 'src/assets/icons')],
symbolId: 'svg-icon-[name]'
}),
codeInspectorPlugin({
bundler: 'vite'
})
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'~@': fileURLToPath(new URL('./src', import.meta.url))
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
},
server: {
host: 'localhost',
port: 7005,
open: true,
https: false, //协议
hmr: {
progress: true,
overlay: {
errors: false, // 不显示错误覆盖层
warnings: false, // 不显示警告覆盖层
runtimeErrors: false // 不显示运行时错误覆盖层
}
},
proxy: {
'/api': {
target: 'http://xxxx:xxx',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '/api')
},
}
},
// 构建配置
build: {
outDir: 'dist',
assetsDir: 'static',
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
},
output: {
format: 'esm', // 使用 ESM 输出格式
// Static resource classification and packaging
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
},
},
// 禁用 gzip 压缩大小报告,可略微减少打包时间
reportCompressedSize: false,
// 规定触发警告的 chunk 大小
chunkSizeWarningLimit: 2000,
minify: isProduction ? 'terser' : 'esbuild',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
sourcemap: false,
},
};
});

移动index.html并修改部分代码

将原public文件夹下的index.html 移至 根目录下;接着在index.html中 添加入口文件修改title注入的语法favicon.ico的引入路径

image-20241010151622980

修改package.json配置

看项目情况,之前项目上eslintConfig的配置写到了package.json中,现在把它挪到根目录下的.eslintrc.js中

需要注意的一个点,如果package.json中开启了: “type”:”module” ,那么.eslintrc.js 需要改成 .eslintrc.cjs

启动项目,处理问题

动态路由解析问题

image-20241010152613193

由于打包器变了,获取组件模块的方式也要随之更改;主要是获取文件然后再处理路径的修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//原webpack方式获取
const asyncRoutes = require
.context('@/views', true, /\.vue$/, 'lazy')
.keys()
.reduce((routes, url) => {
// console.log(routes, url, !/\/(login|components)\//.test(url));
if (!/\/(login|components)\//.test(url)) {
const path = url.replace('./', '');
// 这里的 `webpackChunkName` 不会生效,需要使用 import.meta.webpackContext 代替 require.context
routes[path] = () => import(/* webpackChunkName: "[request]" */ `@/views/${path}`);
}
return routes;
}, {});

//新vite方式获取
const asyncRoutesPath = import.meta.glob('@/views/**/*.vue', { eager: false });
const asyncRoutes = Object.keys(asyncRoutesPath).reduce((routes, url) => {
const path = url.replace(/\/src\/views\//, '');
if (!/\/(login|components)\//.test(path)) {
routes[path] = () => asyncRoutesPath[url]();
}
return routes;
}, {});

依赖require引入问题

image-20241010154222220

按图索骥,顺藤摸瓜,找到问题点,是aes加密引入的报错,改之。

1
2
// const CryptoJS = require('crypto-js');
import * as CryptoJS from 'crypto-js';

图片加载问题

image-20241010154823206

图片使用require来解析的都会有问题,修改也分2种情况

  • 纯静态文件路径

    类似url: require('@/assets/images/mapIcons/xxxx.png')改为 url: new URL('@/assets/images/mapIcons/xxxx.png',import.meta.url).href

  • 动态文件路径

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <div :style="{backgroundImage:`url(${require('@/assets/images/xxxx.png')})`}"></div>
    修改方法:

    //定义方法,且new URL第一个参数必须要有一段文件路径(不能使用路径别名@)
    const loadImageUrl = path => {
    return new URL(`/src/assets/${path}`,import.meta.url).href;
    };
    <div :style="{backgroundImage:`url(${loadImageUrl('@/assets/images/xxxx.png')})`}"></div>

环境变量获取问题

  • 非配置文件

image-20241010153531500

定位问题:route/index.js 路由生成时候,改为 import.meta.env.BASE_URL即可

1
2
3
4
5
const router = createRouter({
//history: createWebHashHistory(process.env.BASE_URL),
history: createWebHashHistory(import.meta.env.BASE_URL),
routes
});
  • 配置文件(例如vite.config.js)

    之前可能会通过类似这样的代码来判断环境(或者获取vue自定义的环境变量)

    1
    2
    3
    4
    5
    // 是否为生产环境
    const isProduction = process.env.NODE_ENV !== 'development';
    module.exports = defineConfig({
    //...
    })

    现在使用vite,我们可以这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    export default defineConfig(({command, mode }) => {
    //环境变量直接从mode里获取即可
    console.log("=>(vite.config.js:15) mode", mode);

    //这样可以获取自定义的vite变量
    // const env = loadEnv(mode, process.cwd());

    const isProduction = mode === 'production';

    return {
    //...
    }
    })

最后

记得打包一下,看看有没报错,然后本地nginx部署下启动看看有没报错。

vue-cli项目迁移至vite项目

http://dwchou.cn/blog/2651359156/

作者

dwchou

发布于

2024-10-12

更新于

2024-10-16

许可协议

评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...