Vite当初堪称是煊赫一时,可能很多小伙伴还没有应用过Vite,然而我置信大多数小伙伴曾经在应用Vite了,因为是太香了有没有。可能在应用过程中很多货色Vite不是配置好的,并不像Vue-cli配置的很周全,那么明天就说一下如何配置开发环境,其中次要波及到的点有一下几个:

  • TypeScript
  • Vuex
  • Vue-Router
  • E2E

    • Cypress
  • Test unit

    • Jest
    • vtu
  • Eslint + Perttite
  • verify git commit message
  • CI
  • alias

Vite初始化我的项目

在开始之前首先要先应用Vite创立我的项目,如果小伙伴曾经对Vite曾经有了肯定的理解,那么能够跳过。依据Vite官网介绍能够应用npmyarn来创立我的项目。

应用 NPM:

npm init vite@latest

应用 Yarn:

yarn create vite

应用 PNPM:

pnpx create-vite

输出完命令之后而后依照提醒操作即可,因为在我的项目要反对TypeScript所以我这里就抉择的是vue-ts。创立好之后Vite会帮忙咱们把我的项目给创立好,能够发现Vite所创立好的我的项目其实与应用Vue-cli所创立的我的项目目录构造其实是差不多的,这里也就不多赘述了。

集成Vue-Router

Vue-Router是大多数我的项目中比不可少的工具之一了,Vue-Router能够让构建单页面利用变得更加的容易。蕴含的性能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查问、通配符
  • 基于 Vue.js 过渡零碎的视图过渡成果
  • 细粒度的导航管制
  • 带有主动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中主动降级
  • 自定义的滚动条行为

以上截取自Vue-router官网

装置Vue-Router:

应用 NPM:

npm install vue-router@next --save

应用 Yarn:

yarn add vue-router@next --save

装置实现之后在src目录下创立文件夹router/index.ts,创立实现之后须要在Vue-Router中对Vue-Router进行初始化配置。咱们临时把初始化的工作搁置一下,先须要创立pages文件夹,把须要展现的页面创立实现。

创立实现之后,接下来就是欠缺router/index.ts中文件的初始化工作了:

import { createRouter, createWebHashHistory } from "vue-router";const router = createRouter({  history: createWebHashHistory(),  routes: [    {      path: "/home",      name: "Home",      alias: "/",      component: () => import("../pages/Home.vue")    },    {      path: "/about",      name: "About",      component: () => import("../pages/About.vue")    }  ]})export default router;

接下来在main.ts文件中集成Vue-Router

import { createApp } from 'vue';import App from './App.vue';import router from "./router";const app = createApp(App);app.use(router);app.mount('#app');

测试一下,这里批改一下App.vue的代码,测试一下咱们的路由是否曾经能够失常应用了。

<template>  <router-link to="/home">Home</router-link>  <router-link to="/about">About</router-link>  <router-view></router-view></template><script lang="ts">import { defineComponent } from 'vue'export default defineComponent({  name: 'App'})</script>

接下来启动服务就能够看到所配置的页面了,阐明配置的路由曾经失效了。Good Job,真的很不错~~~

集成Vuex

VuexVue所反对的状态管理工具,在在理论利用过程中也有很大的作用,当多个组件之间的数据流转变得十分艰难,因而须要集中的对状态进行治理,Vuex的状态存储是响应式的。当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会相应地失去高效更新。

装置Vuex:

应用 NPM:

npm install vuex@next --save

应用 Yarn:

yarn add vuex@next --save

装置实现之后,首先增加store/index.ts来初始化Vuex。须要留神的是,如下示例应用了Vuex命名空间。可能在理论我的项目中应用命名空间相对来说还是比拟广泛的,防止进行状态治理的时候导致变量净化。

import { createStore } from "vuex";const store = createStore({  modules: {    home: {      namespaced: true,      state: {        count: 1      },      mutations: {        add(state){          state.count++;        }      }    }  }})export default store;

集成到Vue中:

import { createApp } from 'vue';import App from './App.vue';import router from "./router";import store from "./store";const app = createApp(App);app.use(router);app.use(store);app.mount('#app');

当初Vuex就曾经被集成到Vue中了为了保障集成的Vuex是无效地,那么须要对此进行测试:

pages/Home.vue

<template>  <h1>Home</h1>  <h2>{{count}}</h2>  <button @click="handleClick">click</button></template><script lang="ts">import { defineComponent, computed } from 'vue';import { useStore } from 'vuex';export default defineComponent({  setup () {    const store = useStore();    const count = computed(() => store.state.home.count);    const handleClick = () => {      store.commit('home/add');    };    return {      handleClick,      count    };  }})</script>

当点击按钮的时候,就能够发现count值也随着点击每次递增,那么store是能够失常应用。Good Job,真的很不错~~~

集成单元测试

在开发过程中为了保障程序的健壮性,就须要对程序进行单元测试,所以在我的项目初始化的时候,同样就须要为单元测试进行配置。配置中应用的工具是jest,如果对于单元测试不太理解的,请自行百度学习,脱离本文重点,不多赘述。

装置相干依赖:

应用 NPM:

npm install jest -D                  # 单元测试工具 ^26.6.3npm install @types/jest -D           # 单元测试类型文件npm install babel-jest -D            # 反对es6模块 ^26.6.3npm install @babel/preset-env -D     # 反对es6模块 ^7.14.7npm install vue-jest@next -D         # 反对Vue文件 ^5.0.0-alpha.8npm install ts-jest -D               # 反对Ts      ^26.5.1npm install @vue/test-utils@next     # Vue官网测试工具 2.0.0-rc.6npm install @vue/test-utils@next -D  # 2.0.0-rc.6npm install @babel/preset-typescript # 反对Ts ^7.12.17

应用 Yarn:

yarn add jest --dev                  # 单元测试工具 ^26.6.3yarn add @types/jest --dev           # 单元测试类型文件yarn add babel-jest --dev            # 反对es6模块 ^26.6.3yarn add @babel/preset-env --dev     # 反对es6模块 ^7.14.7yarn add vue-jest@next --dev         # 反对Vue文件 ^5.0.0-alpha.8yarn add ts-jest --dev               # 反对Ts      ^26.5.1yarn add @vue/test-utils@next        # Vue官网测试工具 2.0.0-rc.6yarn add @babel/preset-typescript    # 反对Ts ^7.12.17

依赖装置实现之后,在src目录下创立tests文件夹,这个文件夹用来寄存对于测试相干的文件,因为咱们岂但有单元测试还有E2E测试,所以要对两者进行辨别。

因为在装置配置的时候可能会导致版本不兼容,导致的报错,所以在配置的时候添肯定要留神版本号,在下面曾经正文了版本号,须要留神一下。装置完所依赖之后,接下来就须要对单元测试进行配置。

在根目录创立jest.config.jsJest进行初始化的根本配置:

module.exports = {  transform: {  //  babel预设    "^.+\\.vue$": "vue-jest",       //  反对导入Vue文件    "^.+\\.jsx?$": "babel-jest",    //  反对import语法    '^.+\\.tsx?$': 'ts-jest'        //  反对ts  }};

批改tsconfig.json

{  "compilerOptions": {    "target": "esnext",    "module": "esnext",    "moduleResolution": "node",    "strict": true,    "jsx": "preserve",    "sourceMap": true,    "resolveJsonModule": true,    "esModuleInterop": true,    "lib": ["esnext", "dom"],    "types": ["vite/client", "jest"]    //  指定类型为jest  },  "include": [    "src/**/*.ts",     "src/**/*.d.ts",    "src/**/*.tsx",    "src/**/*.vue",     "tests"     // 指定单元测试门路  ]}

因为Node无奈运行TypeScript这里须要应用babelTypeScript进行编译,要配置babel的相干配置,在根目录创立babel.config.js

module.exports = {  transform: {    "^.+\\.vue$": "vue-jest",    "^.+\\.jsx?$": "babel-jest",    '^.+\\.tsx?$': 'ts-jest'  },  testMatch: [  //  匹配单元测试规定    "**/?(*.)+(test).[jt]s?(x)"  ]};

下面根本曾经对单元测试的配置实现了,接下来就是测试是否可能失常运行单元测试,在根目录上面创立tests/unit等文件夹(文件):

index.test.ts

import { mount } from "@vue/test-utils";import demo from "./demo";import Foo from "../../src/components/Foo.vue";test("1+1=2", () => {  console.log(demo);  console.log(mount(Foo));  expect(1+1).toBe(2);});

demo.ts

export default {  a: 1};

之后就是运行单元测试,在package.json中增加命令:

{  "scripts": {    "test:unit": "jest"  }}

运行一下就能够看到输入得后果,那么就代表咱们的单元测试能够失常运行了,Good Job,真的很不错~~~

集成E2E测试

可能很多小伙伴对于E2E测试不是特地的相熟,E2E即端对端测试,属于黑盒测试,通过编写测试用例,自动化模仿用户操作,确保组件间通信失常,程序流数据传递如预期。

既然对E2E有了肯定的理解之后呢,那么就须要装置E2E测试相干的模块的依赖,E2E测试应用是cypress依赖,首次装置的时候可能会慢,要急躁期待:

应用 NPM:

yarn add cypress -D             # e2e测试工具

应用 Yarn:

yarn add cypress --dev          # e2e测试工具

装置依赖实现之后须要对cypress进行初始化,这个时候咱们须要在package.json中增加命令:

{  "scripts": {    "test:e2e": "cypress open"  }}

执行实现之后呢会在根目录下创立一个cypress文件夹,该文件夹外面蕴含了很多目录相干的文件,临时先不论,之后在tests文件夹中增加e2e文件夹,把cypress所有内容剪切到tests/e2e中。

实现上述操作之后咧?cypress在运行的时候会默认的去cypress文件中去找相干依赖,然而当初曾经把cypress中的文件曾经挪走了,那么咱们就须要对cypress进行配置,批改cypress的根底门路,并指向到tests/e2e文件即可。

在根目录创立cypress.json文件:

{  "pluginsFile": "tests/e2e/plugins/index.ts",  "video": false    //  关掉视频录制默认行为}

仔细的小伙伴可能曾经发现了,下面所以援用的文件是以.ts结尾的,然而在对应目录上面是.js文件,这是为什么?因为咱们的我的项目是以TypeScript为根底的我的项目,所以咱们E2E测试也应该应用TypeScript,这个时候咱们应该把E2E文件夹下所有.js文件改为.ts(须要留神的是,把integration改成specs,并删除外面所有测试用例)。

更改plugin文件夹上面的index.ts

module.exports = (on, config) => {  return Object.assign({}, config, {    fixturesFolder: 'tests/e2e/fixtures',    integrationFolder: 'tests/e2e/specs',    screenshotsFolder: 'tests/e2e/screenshots',    videosFolder: 'tests/e2e/videos',    supportFile: 'tests/e2e/support/index.ts'  });};

针对cypress的单元测试曾经实现了,然而方才曾经删除了测试用例,接下来就写一下测试用例,在tests/e2e/specs文件夹上面创立:

first.specs.ts

describe("First ", () => {  it("before", () => {    cy.visit("http://localhost:3000/");    cy.get("button").click();  });});

须要留神的是,因为cypress是须要在我的项目启动的时候进行测试的,所以咱们须要把本地的服务运行起来才能够。测试用例变现实现之后,就能够运行了。在弹出页面中会看到所有用例的文件,点击对应文件,就会在浏览器中关上了,浏览器左侧则是对应测试的步骤了。

通过上述的配置E2E的配置曾经根本实现了,因为两个测试全处于tests中两个测试会相互影响么?

插曲

既然E2E测试和单元测试都曾经实现了,那么别离运行一下单元测试和E2E测试,当运行单元测试后的时候,就会抛出一个谬误。

  ● Test suite failed to run    tests/unit/index.spec.ts:8:15 - error TS2339:        Property 'toBe' does not exist on type 'Assertion'.    8   expect(1+1).toBe(2);                    ~~~~Test Suites: 1 failed, 1 totalTests:       0 totalSnapshots:   0 totalTime:        3.234 sRan all test suites.error Command failed with exit code 1.

很显著,咱们的单元测试收到E2E测试的影响,运行失败了,能够依据文件提醒找到对应的地位,因为两个测试库的expect抵触了,所以导致单元测试下expect返回的对象内容不在是原来单元测试expect了。

既然呈现问题了就须要解决问题ing,在下面配置单元测试的时候,为了让单元测试反对TypeScripttsconfig.json中增加了测试的门路,咱们如果只指向到单元测试外面这个问题是不是就解决了,然而如果这样的话,cypress无奈再反对TypeScript了,其实咱们能够在E2E再创立一个tsconfig.json这个文件只利用于E2E

tsconfig.json

{  "compilerOptions": {    "target": "esnext",    "module": "esnext",    "moduleResolution": "node",    "strict": true,    "jsx": "preserve",    "sourceMap": true,    "resolveJsonModule": true,    "esModuleInterop": true,    "lib": ["esnext", "dom"],    "types": ["vite/client", "jest"]  },  "include": [    "src/**/*.ts",     "src/**/*.d.ts",    "src/**/*.tsx",    "src/**/*.vue",     "tests/unit"     // 指定单元测试门路  ]}

tests/e2e/tsconfig.json

{  "compilerOptions": {    "target": "esnext",    "module": "esnext",    "moduleResolution": "node",    "strict": true,    "jsx": "preserve",    "sourceMap": true,    "resolveJsonModule": true,    "esModuleInterop": true,    "lib": ["esnext", "dom"]  }}

之后再运行yarn test:unit的时候就会发现不会报错了,那么通过这次更改e2e是否受到影响了呢?运行yarn test:e2e显然并没有产生任何谬误,也能够失常运行的。Good Job,真的很不错~~~

当运行yarn test:e2e的时候,总会弹出一个窗口,然而当我的项目部署走CI的时候,是没有方法进行点击的,这个时候应该怎么办呢?其实cypress是有方法在终端执行的,通过npx cypress run这个命令去在终端运行E2E测试。

批改package.json:

{  "scripts": {    "test:unit": "jest",    "test:e2e": "cypress open",    "test": "yarn test:unit && npx cypress run"  }}

之后运行yarn test就能够先运行单元测试,后运行E2E测试了。

集成Git提交验证

在开发我的项目的时候可能并不是一个人进行开发的,可能会由多集体进行开发,那么作为规范的自动化来讲,对于Git提交的时候,要有一些固定显著的格局来标准咱们的我的项目开发人员,这个时候就须要应用某些工具进行束缚。

装置相干依赖:

应用 NPM:

npm install yorkie -Dnpm install chalk -D

应用 Yarn:

yarn add yorkie --devyarn add chalk --dev

装置完依赖之后,对yorkie之后须要对其进行相干的配置,在package.json中增加字段:

{    "gitHooks": {        "commit-msg": "node scripts/commitMessage.js"    }}

在下面的配置中,运行了一个js文件,那么这个js文件中则是对提交内容的校验。

scripts/commitMessage.js

const chalk = require('chalk')const msgPath = process.env.GIT_PARAMSconst msg = require('fs').readFileSync(msgPath, 'utf-8').trim()const commitRE = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\(.+\))?(.{1,10})?: .{1,50}/const mergeRe = /^(Merge pull request|Merge branch)/if (!commitRE.test(msg)) {  if (!mergeRe.test(msg)) {    console.log(msg)    console.error(      `  ${chalk.bgRed.white(' ERROR ')} ${chalk.red(        `invalid commit message format.`,      )}\n\n` +        chalk.red(          `  Proper commit message format is required for automated changelog generation. Examples:\n\n`,        ) +        `    ${chalk.green(`feat(compiler): add 'comments' option`)}\n` +        `    ${chalk.green(          `fix(v-model): handle events on blur (close #28)`,        )}\n\n` +        chalk.red(          `  See https://github.com/vuejs/vue-next/blob/master/.github/commit-convention.md for more details.\n`,        ),    )    process.exit(1)  }}

集成Eslint

Eslint对于团队开发来说是一个很不错的工具,能够依据Eslint的配置给束缚开发者代码的格调,以及书写格局。

装置相干依赖:

应用 NPM:

npm install eslint -Dnpm install eslint-plugin-vue -Dnpm install @vue/eslint-config-typescript -Dnpm install @typescript-eslint/parser -Dnpm install @typescript-eslint/eslint-plugin -Dnpm install typescript -Dnpm install prettier -Dnpm install eslint-plugin-prettier -Dnpm install @vue/eslint-config-prettier -D

应用 Yarn:

yarn add eslint --devyarn add eslint-plugin-vue --devyarn add @vue/eslint-config-typescript --devyarn add @typescript-eslint/parser --devyarn add @typescript-eslint/eslint-plugin --devyarn add typescript --devyarn add prettier --devyarn add eslint-plugin-prettier --devyarn add @vue/eslint-config-prettier --dev

配置装置实现之后呢,还须要对eslint进行配置,在根目录下创立.eslintrc:

.eslintrc

{  "root": true,  "env": {    "browser": true,    "node": true,    "es2021": true  },  "extends": [    "plugin:vue/vue3-recommended",    "eslint:recommended",    "@vue/typescript/recommended"  ],  "parserOptions": {    "ecmaVersion": 2021  }}

配置项曾经增加好了,如何去运行曾经配置好的eslint呢?接下来就须要在package.json中增加命令:

{    "lint": "eslint --ext src/**/*.{ts,vue} --no-error-on-unmatched-pattern"}

接下来运行一下yarn lint就能够了,能够通过eslint实现格局的校验了,当初的问题是什么,在执行yarn lint的时候把所有的文件全副都校验了一次,这个可不是咱们所心愿的,如果有很多文件的话,那么速度将会很慢,那么有没有方法,只在git提交的时候对批改的文件进行eslint校验呢?

装置相干依赖:

应用 NPM:

npm install lint-staged -D

应用 Yarn:

yarn add lint-staged --dev

批改package.json

{  "gitHooks": {    "commit-msg": "node scripts/commitMessage.js",    "pre-commit": "lint-staged"  },  "lint-staged": {    "*.{ts,vue}": "eslint --fix"  },  "scripts": {    "test:unit": "jest",    "test:e2e": "cypress open",    "test": "yarn test:unit && npx cypress run",    "lint": "npx prettier -w -u . && eslint --ext .ts,.vue src/** --no-error-on-unmatched-pattern",    "bea": "npx prettier -w -u ."   //  丑化代码  },}

配置alias

在应用cli的时候总是应用@去引入某些文件,因为Vite没有提供相似的配置,所以咱们须要手动的对其进行一些相干的配置,能力持续应用@符号去快捷的引入文件。

批改vite.config.ts:

import { defineConfig } from 'vite';import vue from '@vitejs/plugin-vue';import { join } from "path";// https://vitejs.dev/config/export default defineConfig({  plugins: [vue()],  resolve: {    alias: [      {        find: '@',        replacement: '/src',      },      { find: 'views', replacement: '/src/views' },      { find: 'components', replacement: '/src/components' },    ]  }});

批改tsconfig.json:

{  "compilerOptions": {    "target": "esnext",    "module": "esnext",    "moduleResolution": "node",    "strict": true,    "jsx": "preserve",    "sourceMap": true,    "resolveJsonModule": true,    "esModuleInterop": true,    "lib": ["esnext", "dom"],    "types": ["vite/client", "jest"],    "baseUrl": ".",    "paths": {      "@/*": ["src/*"]    }   },  "include": [    "src/**/*.ts",    "src/**/*.d.ts",    "src/**/*.tsx",    "src/**/*.vue",    "tests/unit"  ]}

为了保障在单元测试中也能够应用@引入src上面的文件须要对jest.config.js配置进行批改:

批改jest.config.js

module.exports = {  transform: {    '^.+\\.vue$': 'vue-jest',    '^.+\\.jsx?$': 'babel-jest',    '^.+\\.tsx?$': 'ts-jest',  },  testMatch: ['**/?(*.)+(test).[jt]s?(x)'],  moduleNameMapper: {    "@/(.*)$": "<rootDir>/src/$1"   }};

结尾

应用Vite对我的项目初始化还是存在很多坑的,比方在配置单元测试的时候的版本兼容,还有配置别名的时候须要留神多个文件之间的协调。

咱们做了这么多的对立配置无非是为了可能让我的项目在开发过程中更加的标准,可能达成对立的成果,也能让咱们的程序更加的强壮。反动尚未胜利,同志仍需致力。

可能文章中一些见解存在一些问题,欢送大家在评论区指出,大家一起学习,一起提高。如果文章对你有帮忙的话,请点击赞吧~