手把手教你搭建vite开发环境 - [vue3、vue-route、vuex 、tsx、sass]

1,627 阅读3分钟

vite 和 vue3 已经出了2年了,大家已经不再陌生,如果让自己从0搭建一个vue3的vite项目,我们该怎么做呢?

第二期:搭建vite开发环境 - [vue3ts 代码检查,单元测试, 异步组件,自动生成 .d]

本期项目代码地址

梦开始的地方 - yarn create vite

当我们 sudo yarn add -g vite 全局安装完vite以后

输入$ yarn create vite my-vite-project-test --template=vue-ts,然后看到的界面是这样的:

image.png

而后 cd 到我们的刚刚创建的项目内,安装一下依赖,vite官方实际是通过create-vite插件来帮你配置你的新app的,感兴趣的同学可以戳一下这里 create-vite

打开你的这个新项目,文件目录和 vue-cli 的基本完全一样

image.png

现在,你的 vite 的初始化模版步骤已经完成,我们来进行下一步,vue -> jsx

放弃vue语法糖🍬追求更加原生的写法 - vue 2 jsx

对于喜欢用jsx的同学,继续跟着我走,如果不希望转换请跳转 设置项目内的文件目录别名

首先

  • 在 vue 内使用 jsx 我们需要的是编译工具
    • vite已经在生成模版的时候就将 typescript 给我们装好了, 但是我们需要安装 vue 的 tsx 引擎, vite 的插件内可以直接下载 @vitejs/plugin-vue-js
    $ yarn add @vitejs/plugin-vue-jsx -D
    
  • 默认后缀忽略
    • 文件后缀忽略需要在vite.config.ts内的resolve-extensions配置,官方默认配置值, 如果需要vue后缀支持的话,需要单独配置这个字段
    // vite.config.ts
    import { defineConfig } from 'vite'
    
    import vue from '@vitejs/plugin-vue'
    import vueJsx from '@vitejs/plugin-vue-jsx'
    
    export default defineConfig({
      envPrefix: 'VITE_',
      plugins: [vue(), vueJsx()],
      server: {
        port: 3000
      },
      resolve: {
        extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
      }
    })
    
    

经过了上面两个步骤,我们已经可以动手给我们的 .vue 文件改成 .tsx 文件了

// App.tsx
import { defineComponent } from 'vue'

import HelloWorld from './components/HelloWorld'
import LogoPic from './assets/logo.png'

export default defineComponent({
  setup() {
    return () => (
      <>
        <img alt="Vue logo" src={LogoPic} />
        <HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
      </>
    )
  }
})

将我们的 App.vue 改造成上面这样大家就会看到新的,通过tsx书写的vue文件啦

设置项目内的文件目录别名

简单的配置好jsx的模版引擎后,我们去配置一下目录的别名信息 大家在项目内经常会访问到 src 目录,一般我们所有的代码和资源文件都会放在这个文件里, 在vite内,也提供了相应的配置

import { resolve } from 'path'
import { defineConfig } from 'vite'

const pathResolve = (pathStr: string) => {
  return resolve(__dirname, pathStr)
}

import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
  envPrefix: 'VITE_',
  plugins: [vue(), vueJsx()],
  server: {
    port: 3000
  },
  resolve: {
    alias: {
      '@': pathResolve('./src')
    },
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
  }
})

根据上面的配置我们就可以在项目内使用 @ 别名来访问 src 目录下的文件了 但是使用 ts 的同学在这一步可能会报错 __dirname找不到呀,path模块未声明啊等问题, 这是我们缺少了typings,需要将类型文件,和path的包安装下来

$ yarn add @types/node path -D

使用ts的同学们,我们做完这些就够了吗,当然,还缺了一步,我们需要在 tsconfig.json 内加入刚才声明的别名

image.png

// ts-config.json
{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

好了,路径引用正确,完整的 alias 我们已经配置完毕

使用 vue-router

在 vue3 内引入 vue-route 的方式很简单,起手式还是一样,我们先装包

yarn add vue-router

而后我们在src目录下建立新的文件夹,用于存放我们的路由声明文件,在文件夹内建立 index.ts 用于暴露路由信息,vue-route官方文档

// routers/index.ts
import {
  createRouter,
  createWebHashHistory,
  RouteRecordRaw,
  RouteLocationNormalized,
  NavigationGuardNext
} from 'vue-router'

// 路由配置 和以前一样
const routes: RouteRecordRaw[] = [
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/home',
    name: 'home',
    meta: {
      type: 'home'
    },
    component: () => import('@/views/home')
  },
  {
    path: '/login',
    name: 'login',
    meta: {
      type: 'login'
    },
    component: () => import('@/views/login')
  },
  {
    path: '/:pathMatch(.*)*', // 注意此处 404页面匹配规则和以前不相同,得采用这种配置方式才行
    name: '404',
    component: () => import('@/views/404')
  }
]

const router = createRouter({
  history: createWebHashHistory(), //路由模式的配置采用API调用的方式 不再是之前的字符串 此处采用的hash路由
  routes
})

// 路由守卫和之前的实现方式一致 此处只是做了一个demo仅供演示
router.beforeEach(
  (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
    // 获取userToken,根据业务场景可由localStorage也可由cookie中获取
    const user = localStorage.getItem('user')
    // 路由守卫判断
    if (to.meta.type === 'login' && user) {
      next({ name: 'home' })
      return
    }

    if (to.meta.type === 'home' && !user) {
      next({ name: 'login' })
      return
    }

    next()
  }
)


export default router

声明好 router 文件后,我们在 main.ts 内使用就可以了

import { createApp } from 'vue'

import routers from './routers'

import App from './App'

createApp(App).use(routers).mount('#app')

使用 vuex

和上面的route 安装方式一样,

$ yarn add vuex

而后创建 store 文件夹输出文件即可, 具体请戳 vuex官方文档,这里不再赘述

scss样式的使用(jsx + 单文件)和静态文件的引入

在 vite 内使用 scss 或者其他css编译器,基本都不需要额外配置直接即装即用, 以 scss 为例子:

$ yarn add sass -D

而后直接创建 styles 目录,书写即可,例子:

/* styles/app.module.scss */
@function invert($color, $amount: 100%) {
  $inverse: change-color($color, $hue: hue($color) + 180);
  @return mix($inverse, $color, $amount);
}

$red-color: red;

.page-bg {
  background-color: invert($red-color, 80%);
}

接着在jsx内导入使用

import { defineComponent } from 'vue'
import { RouterView } from 'vue-router'

// 静态文件的引入使用图片资源
import imgUrl from '@/assets/logo.png'

// .module 相当于 css 作用域语法
import appClasses from '@/styles/app.module.scss'

export default defineComponent({
  setup() {
    return () => (
      <>
        <img src={imgUrl} />
        <RouterView class={appClasses['page-bg']} />
      </>
    )
  }
})

今天先到这里,下期将会将 vite - eslint & prettierrc 的配置,和如何进行单元测试,如何在打包时生成 ts.d 类型声明,异步组件怎么做,按需加载怎么做, gizp 如何做,同学们,下期见。

// package.json

{
  "name": "my-vite-project-test",
  "private": true,
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.2.25",
    "vue-router": "^4.0.14"
  },
  "devDependencies": {
    "@types/node": "^17.0.23",
    "@vitejs/plugin-vue": "^2.3.0",
    "@vitejs/plugin-vue-jsx": "^1.3.9",
    "path": "^0.12.7",
    "prettier": "^2.6.1",
    "typescript": "^4.5.4",
    "vite": "^2.9.0",
    "vue-eslint-parser": "^8.3.0",
    "vue-tsc": "^0.29.8"
  }
}