likes
comments
collection
share

手把手教你搭建vite开发环境 - [vue3ts 代码检查,单元测试, 异步组件,自动生成 .d]

作者站长头像
站长
· 阅读数 18

第一期:搭建 vue3 ts sass的开发环境

本期项目代码地址

第一期我们搭建了基础结构后,项目依然需一些代码检查类的工作,这里暂时选用的 eslint + prettierrc 的格式化工具,事例如下:

配置 eslint + prettierrc

所需的安装包如下:

$ yarn add eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-vue vue-eslint-parser @typescript-eslint/eslint-plugin @typescript-eslint/parser -D

首先是 eslint、prettier 模块 和 eslint 插件模块

eslint、prettier 不必多说,现在先聊一下eslint的插件部分

  1. eslint-plugin-vue插件是vue官方给eslint提交的一个插件,其目的是给eslit支持解析.vue后缀的能力,也提供了一些有用的解析器服务来帮助遍历生成的 AST 和访问模板令牌:

    • context.parserServices.defineTemplateBodyVisitor(visitor, scriptVisitor)
    • context.parserServices.getTemplateBodyTokenStore()
  2. vue-eslint-parser做的工作是让eslit可以正常解析vue文件,和上面的eslint-plugin-vue的区别是:

    • eslint-plugin-vue 是一个针对vue内容的检查插件
    • vue-eslint-parser 则是对 vue 文件进行编译和和解析的

    两个包虽然都会去读 .eslintrc 的配置,但是其工作原理不同,eslint-plugin-vue 插件依赖 vue-eslint-parser解析器,vue-eslint-parser解析器,只解析 .vue 中html部分的内容,不会检测<script>中的JS内容,由于Vue中的单个文件组件不是普通的JavaScript,因此无法使用默认解析器,因此引入了新的解析器。vue-eslint-parser生成带有节点的增强型AST,这些节点代表模板语法的特定部分以及<script>标记内的内容。

  3. eslint-plugin-prettier插件会调用prettier对你的代码风格进行检查,其原理是先使用prettier对你的代码进行格式化,然后与格式化之前的代码进行对比,如果过出现了不一致,这个地方就会被prettier进行标记

  4. eslint-config-prettier插件是麻省理工提供的eslint和prettier的扩展程序,他并非以插件形式运作,而是去通过污染prettier的配置选项的方式工作的,有兴趣的同学可以访问他们的github

  5. @typescript-eslint/eslint-plugin@typescript-eslint/parser 看完了上面的vue相关的eslint插件的描述,大家对这两个插件的用途应该也理解了吧,当然,ts里还是做了很多关于ts的类型语言的解释的,这是vue-eslint-parser所没有的

配置事例

// .eslintrc.js 
// options to see https://eslint.org/docs/user-guide/configuring/
module.exports = {
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 2020,
    sourceType: 'module',
    ecmaFeatures: {
      tsx: true,
      jsx: true,
    },
  },
  settings: {
    tsx: {
      version: 'detect',
    },
  },
  ignorePatterns: ['node_modules/', 'dist/'],
  extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
  rules: {},
}

// .prettierrc.js
// options to see https://prettier.io/docs/en/options.html
module.exports = {
  printWidth: 120,
  tabWidth: 2, // tab 2 spaces
  semi: false, // no semicolons
  singleQuote: true, // use single quotes
  trailingComma: 'es5', // trailing commas es5 
  jsxSingleQuote: false,
  jsxBracketSameLine: false,
  arrowParens: 'always',
  vueIndentScriptAndStyle: true,
  htmlWhitespaceSensitivity: 'strict',
}

代码风格检查的配置差不多配置完毕了。我们现在配置一下eslint检查的package命令,方便以后进行检查

// package.json
{
    "script": {
        ...
        "lint:fix": "eslint src --fix --ext .ts,.tsx"
    }
}

如果大家使用的是 vscode, 下载一下相关插件然后打开auto format on save就可以在保存文件的时候自动格式化了

增加 Jest 单元测试 vitest

vitest 官方地址

关于 Jest 单元测试,看到其他博主都给了很多自己安装的解决方案,实际官方给出了vitest的解决方案,官网在上面,使用方式也很简单

  • 在项目内引入
$ yarn add @vue/test-utils jsdom vitest -D
  • 在vite.config.ts内写入配置项
下面这是引入 test 的类型声明
/// <reference types="vitest" />

...

export default defineConfig({
    ...
    test: {
        globals: true,
        environment: 'jsdom',
        transformMode: {
          web: [/.[tj]sx$/],
        },
    },
    ...
})

官方给出了各种框架下的使用案例,有兴趣的同学可以戳这里

写个单测试一下:

// utils.ts
export const getArrayDiff = <T>(array: Array<T>, otherArr: Array<T>): Array<T> => {
  return array.filter((item) => !otherArr.includes(item))
}
// utils.spec.ts
import { getArrayDiff } from '../index'

describe('/utils/index.ts', () => {
  it('getArrayDiff', () => {
    const array = [1, 2, 3, 4, 5]
    const otherArr = [1, 2, 3, 4, 5, 6]

    expect(JSON.stringify(getArrayDiff(array, otherArr))).toBe(JSON.stringify([]))
  })
})

手把手教你搭建vite开发环境 - [vue3ts 代码检查,单元测试, 异步组件,自动生成 .d]

可以看到单测已经可以运行了,

而后我们在命令行加入调试命令,方便之后的git提交前进行脚本执行

{
    "scripts": {
        ...
        "test": "vitest",
        "coverage": "vitest run --coverage"
    },
}

现在为止,单元测试已经可以正常运作了,我们继续进行路由的异步处理

异步化路由和文件

借用vue官方文档的描述

以前,异步组件是通过将组件定义为返回 Promise 的函数来创建的,例如:

const asyncModal = () => import('./Modal.vue')

或者,对于带有选项的更高阶的组件语法:

const asyncModal = {
  component: () => import('./Modal.vue'),
  delay: 200,
  timeout: 3000,
  error: ErrorComponent,
  loading: LoadingComponent
}

现在,在 Vue 3 中,由于函数式组件被定义为纯函数,因此异步组件需要通过将其包裹在新的 defineAsyncComponent 助手方法中来显式地定义:

import { defineAsyncComponent } from 'vue'
import ErrorComponent from './components/ErrorComponent.vue'
import LoadingComponent from './components/LoadingComponent.vue'

// 不带选项的异步组件
const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))

// 带选项的异步组件
const asyncModalWithOptions = defineAsyncComponent({
  loader: () => import('./Modal.vue'),
  delay: 200,
  timeout: 3000,
  errorComponent: ErrorComponent,
  loadingComponent: LoadingComponent
})

我们全局注入的组件就需要从之前的Vue.component注入的方式改掉了,从隐式调用,改为显示声明的方式来做。

// vue2.x
Vue.component('async-example', () => import('@/componets/test.vue')

// vue3.x
import { defineAsyncComponent } from 'vue'

app.component('async-example', defineAsyncComponent(() =>
  import('@/componets/test.vue')
)

这样全局注册的组件,vue就会知道它需要异步加载的,而非直接注入。异步的方式也比较简单,检测它是否是一个promise,而进行标记性定义

自动生成ts.d类型声明文件

vite社区提供了一个插件 vite-plugin-dts,这是个国人作者 github请戳vite-plugin-dts

使用也很简单,即装即用, 是一个 基于rollup打包写的插件,也有一些rollup的接口可以去配置你的输出结果,是个不错的工具

$ yarn add vite-plugin-dts -D
export default defineConfig({
  ...
  build: {
    ...
    lib: {
      entry: resolve(__dirname, 'src/main.ts'),
      name: 'MyLib',
      formats: ['es'],
      fileName: 'my-lib' // 输出的.d文件名称事例将会生成 my-lib.d.ts
    }
  },
  plugins: [..., dts()]
})

经过上面的配置,我们的 .d 文件就可以直接在我们dist打包目录的根目录下找到了,是不是很方便。

本期就先到这里,下期我们来讲一下 vite 打包优化方面的问题和 vue3+ tsx 下的 ui组件库引入的一些问题和解决方案

转载自:https://juejin.cn/post/7082352016759980039
评论
请登录