前言
今天,我在原来使用vue-cli创建的个人项目的基础上,使用vite2重新搭建了项目框架,中途踩了一些坑,但最终在本地和生产环境都运行良好。基于此,我分享一下我踩的坑,帮读者少走些弯路。
一、使用vite创建项目
介绍vite不是这篇文章的目的,但是基本的创建项目的流程我还是需要从官方copy一下给读者看 使用vite创建项目:
使用 NPM:
$ npm init vite@latest
使用 Yarn:
$ yarn create vite
使用 PNPM:
$ pnpx create-vite
然后按照提示操作即可!
二、安装vue-cli项目中的依赖
我创建好了vite项目,并使用了vue-ts作为模板,并安装了依赖。这时,我把vue-cli项目
中的代码部分都拷贝到vite项目
中,这时候要考虑到的是vue-cli项目
相关依赖需要补齐。
我需要的生产环境的依赖包括:axios
,element-plus
, lodash
, vue-router
, vuex
, vuex-persistedstate
。
这里如果我简单地一次性安装这些依赖,就遇到第一小坑。
1.生产环境依赖问题
我的想法是直接安装这些依赖的最新版本,所以在控制台输入:
yarn add axios element-plus lodash vue-router vuex vuex-persistedstate
但最终结果是,vue-router
和vuex
安装的不是预期的4.0版本,而是3.x的最新版本,因为目前主流的版本还是vue2对应的vue-router@3.x
和vuex@3.x
。
所以,这时候要细心查看下package.json具体的依赖版本,安装具体的版本,我想要安装的是vue-router
和vuex
的4.0版本,在控制台输入以下命令:
yarn add vue-router@^4.0.0-0 vuex@^4.0.0-0
问题解决😏
2. 开发环境依赖问题
如果读者自己手头上也有使用vue-cli
创建的项目,打开package.json文件能看到项目中开发环境的依赖也有很多,这个时候是否需要全部都安装到vite项目
中呢?
答案是不需要。至少vue-cli
自带的那部分是不需要的,自己加的那部分以根据具体情况为准。
我的项目中的开发依赖就只有vue-cli
创建时默认安装的那些依赖,其中就包括了node-sass
和sass-loader
。因为我在项目里使用了sass
,所以需要在使用vue-cli
创建项目的时候它我安装了这2个依赖。
如果读者对vite
有一点儿了解,而且相对细心,就能知道,这2个依赖在vite项目
中不一定需要安装。但是我没想那么多,直到打包到生产环境才发现了问题。
因为node-sass
和sass-loader
是配合webpack
使用的依赖包,vite
中并没有webpack
(它有rollup,但我不熟),所以应该不需要安装这2个依赖。
虽然不需要安装上面2个依赖,但是要使得sass
文件可以在项目中被转换成css,还是需要提供对sass
的支持,所以这里我需要安装sass
:
yarn add --dev sass
三、改造vite.confg.ts
在vue-cli项目
中,全局配置文件是vue.config.js
,在vite项目
中,是根目录下的vite.config.ts
。
在vue-cli项目
中,我有配置了项目别名,同时设置了devServer,还设置了打包后的目录名。在vite项目
中我也需要把这几点进行配置。我先直接贴代码,再做解释:
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
function resolve(dir: string) {
return `${path.resolve(__dirname, dir)}/`;
}
export default defineConfig({
resolve: {
alias: {
"@/": resolve("src/"),
},
},
plugins: [vue()],
server: {
port: 8080,
proxy: {
"/api": {
// 以/api开头的接口都代理到target指定的域名下
target: "http://127.0.0.1:4000",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
build: {
outDir: "music-player",
},
});
关于设置打包后代码输出目录是用过设置build.outDir
来控制,我着重讲讲别名的设置和server的配置。
1. 别名设置
在vue-cli项目
中,我在很多使用了别名@
,在vite项目中
也需要这么做,那么不可避免的需要设置别名,别名设置的方式除了上面代码中的key: value的模式,还支持{ find, replacement }
的数组。写法如下:
alias: [{
find: "@/",
replacement: resolve("src/"),
}],
至于为何这里别名需要拼接一个/
,读者可以自己去探寻。我来讲另一个点,那就是在我们配置好了别名之后在代码中使用到@
为路径的地方仍会有typescript报错,这个时候就需要修改tsconfig.json
文件,在compilerOptions
配置下添加(paths需要配合baseUrl):
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
},
2. server设置
先来一下vite项目
和vue-cli项目
中开发环境服务器的配置:
vite项目
:
server: {
port: 8080,
proxy: {
"/api": {
// 以/api开头的接口都代理到target指定的域名下
target: "http://127.0.0.1:4000",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
vue-cli项目
:
devServer: {
proxy: {
"/": {
target: "http://127.0.0.1:4000",
},
},
},
vite
中,实际上把所有指向/api
的请求都转到了http://127.0.0.1:4000
;而vue-cli
中不需要。个人认为,在vite中实际上是把/api
的请求转发到了http://127.0.0.1:4000
下。因为vite实际上是把页面和接口都当作一个资源,如果我把/api
改成/
那么对于端口8080
的所有请求都会转到4000
端口下。
这一点儿,读者需要注意。
三、vue-router配置文件踩坑
vue-router中动态导入的写法在vite中也发生了变化。
先贴一下我的部分代码:
/**
* 实现路由懒加载的工具函数
* @param {string} viewPath view的相对路径,相对于src目录
*/
export function lazyLoad(viewPath: string) {
const modules = import.meta.glob("../views/**/*.vue");
return modules[`../views/${viewPath}.vue`];
}
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "Home",
component: lazyLoad("home/Home"),
children: [
{
path: "/",
name: "Personal",
component: lazyLoad(
"home/components/main-content/views/personal-recommends/index"
),
},
],
},
];
Vite 支持使用特殊的 import.meta.glob
函数从文件系统导入多个模块:
const modules = import.meta.glob('./dir/*.js')
以上将会被转译为下面的样子:
// vite 生成的代码
const modules = {
'./dir/foo.js': () => import('./dir/foo.js'),
'./dir/bar.js': () => import('./dir/bar.js')
}
读者可以参照我的写法并根据实际情况进行改造。
四、main.ts文件踩坑
-
导入
import "element-plus/dist/index.css";
代替import "element-plus/lib/theme-chalk/index.css";
-
基础组件的自动化全局注册,由于没有来了webpack,缺少webpack的
require.context
API,这部分功能只能舍弃。不知打读者有没有好的解决办法。
我遇到的坑印象深刻的大概是这几个,欢迎读者在评论探讨。
最后,给我自己的开源项目大哥大小广告:
vue3.2 + typescript仿网易云音乐Mac版本. github: github.com/callmehui/w… 在线访问地址(已使用vite打包):music-player.immortalboy.cn/
欢迎star,欢迎fork,欢迎提issue👏。