使用 vite 从零搭建一个 vue3 应用
之前写了一篇 使用Vite初始化Vue3.x+TS项目,其中大部分内容可以正常使用,部分内容有点过时,主要是
- elsint 的安装方式
- vuex 不在推荐使用,推荐使用 pinia
其他地方还是可以参考使用的, 下面内容主要是介绍最新 eslint 配置、 pinia 的基本使用 和 vue3 测试相关简介
创建项目
使用下面命令创建项目
npm create vite@latest
选择 vue + typescript
✔ Project name: myapp
✔ Select a framework: › Vue
✔ Select a variant: › TypeScript
安装依赖
cd myapp
pnpm i
这里我使用的是 pnpm 安装依赖,也可以使用 npm,下面安装依赖使用的都是 pnpm
启动项目
npm run dev
配置 eslint
首先 vscode 需要安装 eslint 这个插件,这样在编辑中技能查看到 eslit 所报的错误
使用 eslint 来规范我们的代码
安装 eslint
npm init @eslint/config
选择下面
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · vue
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ What format do you want your config file to be in? · JavaScript
这里我们没有选择 eslint 来格式化我们的代码,因为 eslint 无法格式化我们的 jsx 代码片段,使用 prettier 可以格式化 tsx 文件中的所有代码。
如果我们没有使用 jsx ,也可以使用 eslint来格式化我们的代码,建议使用 prettier 来格式化代码
安装 prettier
首先 vscode 需要安装 prettier 这个插件
安装 prettier 及 eslint 相关的插件
pnpm i prettier eslint-config-prettier eslint-plugin-prettier -D
将 prettier 配置到 eslint 中
{
extends: [
...
'plugin:prettier/recommended',
]
}
编写 prettier 配置文件, 新建 .prettierrc.cjs 文件
module.exports = {
trailingComma: 'es5',
tabWidth: 2,
semi: false,
singleQuote: true,
}
配置 eslint
首先需要安装
pnpm i vue-eslint-parser -D
默认生成的 eslint 配置文件时 parser 和 parserOptions 这样的
{
...
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
},
...
修改为下面
{
...
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
parser: "@typescript-eslint/parser",
},
},
...
环境变量
vite 在 4.2 之后支持在 html 中使用环境变量,参考 .env 文件
<h1>%VITE_APP_TITLE%</h1>
pinia
pinia 的使用与 vuex 非常类似,使用起来比 vuex 更加简单,对 typescript 也更加友好
pnpm i pinia
两种使用方式
方式一
与 vuex 使用十分类似,没有 mutation, action 中可以写异步和同步
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 0 }
},
actions: {
increment() {
this.count++
},
},
})
方式二
这种方式更加简单,与 组件的 setup 十分类似
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
function increment() {
count.value++
}
return { count, increment }
})
在组件中使用也十分简单
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
// 直接调用 increment 方法
counter.increment()
</script>
<template>
<!-- 直接从 store 中访问 state -->
<div>Current Count: {{ counter.count }}</div>
</template>
更详细的使用方式可以参考 pinia 文档 pinia.vuejs.org
测试相关
测试工具我们可以使用 jest 和 vitest,这里我使用 vitest,它的使用方式大部分与 jest 都十分类似,而且可以复用 vite 的配置
安装
pnpm i vitest -D
在 package.json 中配置测试使用的命令
{
"scripts": {
"test": "vitest",
"coverage": "vitest run --coverage"
}
}
在 vite.config.ts 文件添加 vitest 配置
// 这里是为了能够提示 vitest相关配置, vite defineConfig 无法识别 test 选项的
/// <reference types="vitest" />
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.join(__dirname, 'src'),
},
conditions: process.env.VITEST ? ['node'] : [],
},
test: {
environment: 'jsdom',
coverage: {
provider: 'c8', // 或 istanbul
},
},
我们还需要安装 jsdom 和 c8
pnpm i jsdom @vitest/coverage-c8 -D
我们要测试 vue 组件还需要安装 Vue Test Utils
pnpm i @vue/test-utils -D
编写测试文件
我们要测试下面组件
<script setup lang="ts">
import { ref } from 'vue'
defineProps<{ title: string }>()
const count = ref(0)
</script>
<template>
<h1>{{ title }}</h1>
<div class="card">
<div>
count is <span class="count">{{ count }}</span>
</div>
<button type="button" @click="count++">add</button>
</div>
</template>
需要测试的功能有
- h1 内容根据 props 显示正确的标题
- span 下的 cout 初始值是0 ,点击一次 +1
根据上面的内容编写测试
// __test__/helloWorld.spec.ts
import { shallowMount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import Helloworld from '@/components/HelloWorld.vue'
describe('HelloWorld', () => {
const wrapper = shallowMount(Helloworld, {
props: {
title: 'Hello world',
},
})
it('test title', () => {
expect(wrapper.get('h1').text()).toEqual('Hello world')
const wrapper1 = shallowMount(Helloworld, {
props: {
title: 'Vue',
},
})
expect(wrapper1.get('h1').text()).toEqual('Vue')
})
it('test add', async () => {
await wrapper.get('button').trigger('click')
expect(wrapper.get('.count').text()).toEqual('1')
await wrapper.get('button').trigger('click')
expect(wrapper.get('.count').text()).toEqual('2')
})
})
有关测试的更多内容可以参考文档
- vitest 文档 vitest.dev
- Vue Test Utils 文档 test-utils.vuejs.org
其他相关
其他相关可以参考之前我写的文章 使用Vite初始化Vue3.x+TS项目
转载自:https://juejin.cn/post/7224059698911248442