共计 11995 个字符,预计需要花费 30 分钟才能阅读完成。
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
官网介绍能够应用 npm
或yarn
来创立我的项目。
应用 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
Vuex
是 Vue
所反对的状态管理工具,在在理论利用过程中也有很大的作用,当多个组件之间的数据流转变得十分艰难,因而须要集中的对状态进行治理,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.3
npm install @types/jest -D # 单元测试类型文件
npm install babel-jest -D # 反对 es6 模块 ^26.6.3
npm install @babel/preset-env -D # 反对 es6 模块 ^7.14.7
npm install vue-jest@next -D # 反对 Vue 文件 ^5.0.0-alpha.8
npm install ts-jest -D # 反对 Ts ^26.5.1
npm install @vue/test-utils@next # Vue 官网测试工具 2.0.0-rc.6
npm install @vue/test-utils@next -D # 2.0.0-rc.6
npm install @babel/preset-typescript # 反对 Ts ^7.12.17
应用 Yarn:
yarn add jest --dev # 单元测试工具 ^26.6.3
yarn add @types/jest --dev # 单元测试类型文件
yarn add babel-jest --dev # 反对 es6 模块 ^26.6.3
yarn add @babel/preset-env --dev # 反对 es6 模块 ^7.14.7
yarn add vue-jest@next --dev # 反对 Vue 文件 ^5.0.0-alpha.8
yarn add ts-jest --dev # 反对 Ts ^26.5.1
yarn add @vue/test-utils@next # Vue 官网测试工具 2.0.0-rc.6
yarn add @babel/preset-typescript # 反对 Ts ^7.12.17
依赖装置实现之后,在 src
目录下创立 tests
文件夹,这个文件夹用来寄存对于测试相干的文件,因为咱们岂但有单元测试还有 E2E
测试,所以要对两者进行辨别。
因为在装置配置的时候可能会导致版本不兼容,导致的报错,所以在配置的时候添肯定要留神版本号,在下面曾经正文了版本号,须要留神一下。装置完所依赖之后,接下来就须要对单元测试进行配置。
在根目录创立 jest.config.js
对Jest
进行初始化的根本配置:
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
这里须要应用 babel
对TypeScript
进行编译,要配置 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 total
Tests: 0 total
Snapshots: 0 total
Time: 3.234 s
Ran all test suites.
error Command failed with exit code 1.
很显著,咱们的单元测试收到 E2E
测试的影响,运行失败了,能够依据文件提醒找到对应的地位,因为两个测试库的 expect
抵触了,所以导致单元测试下 expect
返回的对象内容不在是原来单元测试 expect
了。
既然呈现问题了就须要解决问题 ing,在下面配置单元测试的时候,为了让单元测试反对 TypeScript
在tsconfig.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 -D
npm install chalk -D
应用 Yarn:
yarn add yorkie --dev
yarn 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_PARAMS
const 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 -D
npm install eslint-plugin-vue -D
npm install @vue/eslint-config-typescript -D
npm install @typescript-eslint/parser -D
npm install @typescript-eslint/eslint-plugin -D
npm install typescript -D
npm install prettier -D
npm install eslint-plugin-prettier -D
npm install @vue/eslint-config-prettier -D
应用 Yarn:
yarn add eslint --dev
yarn add eslint-plugin-vue --dev
yarn add @vue/eslint-config-typescript --dev
yarn add @typescript-eslint/parser --dev
yarn add @typescript-eslint/eslint-plugin --dev
yarn add typescript --dev
yarn add prettier --dev
yarn add eslint-plugin-prettier --dev
yarn 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
对我的项目初始化还是存在很多坑的,比方在配置单元测试的时候的版本兼容,还有配置别名的时候须要留神多个文件之间的协调。
咱们做了这么多的对立配置无非是为了可能让我的项目在开发过程中更加的标准,可能达成对立的成果,也能让咱们的程序更加的强壮。反动尚未胜利,同志仍需致力。
可能文章中一些见解存在一些问题,欢送大家在评论区指出,大家一起学习,一起提高。如果文章对你有帮忙的话,请点击赞吧~