从零开始搭建 vite + vue3 + ts + pinia + vueuse 项目

1,142 阅读6分钟

前言

通过这篇文章你可以了解到

  • 如何使用使用 Vite 搭建项目
  • 如何在 Vite 中集成 typescript
  • 如何在项目中集成 eslintprettier 保证代码风格和质量的统一
  • 如何在 Vite 中集成 vue-router4pinia
  • 如何使用 Vue3 的伴侣 vueuse
  • 如何规范化 git 提交信息
  • 如何为团队开发定制 专属的项目模板

初始化项目

1. 创建 Vite 项目

# pnpm
pnpm create vite

# npm
npm create vite@latest

# yarn
yarn create vite

2. 输入项目名

? Project name:  vite-vue3-ts-pinia

3. 选择一个框架

? Select a framework: » - Use arrow-keys. Return to submit.
    Vanilla // 原生js
>   vue     // 默认就是 vue3
    React   // react
    Preact  // 轻量化react框架
    Lit     // 轻量级web组件
    Svelte  // svelte框架
    Others

4. 选择 TypeScript

? Select a variant: » - Use arrow-keys. Return to submit.
>   TypeScript
    JavaScript
    Customize with create-vue ↗
    Nuxt ↗

5. 启动项目

cd vite-vue3-ts-pinia && npm install && npm run dev

项目配置

Vite 配置

1. 安装 Node 类型声明

用于代码提示 Node 内置模块以及环境变量等

npm i @types/node -D

2. 配置 tsconfig.json

为了使用 TypeScript 语法提示需要做一些自定义的配置

// todo
{
  "compilerOptions": {
    "typeRoots": [
      "node_modules/@types", // 默认值
      "src/types"
   ],
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "baseUrl": "./",
    "paths":{
      "@": ["src"],
      "@/*": ["src/*"],
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

3. 配置 vite.config.js

Vite 配置文件,当以命令行方式运行 vite 时,Vite 会自动解析 项目根目录 下名为 vite.config.js 的文件。

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import * as path from 'path';
// todo
// https://vitejs.dev/config/
export default defineConfig({
    resolve: {
        //设置别名
        alias: {
            '@': path.resolve(__dirname, 'src')
        }
    },
    plugins: [vue()],
    server: {
        port: 8080, //启动端口
        hmr: {
            host: '127.0.0.1',
            port: 8080
        },
        // 设置 https 代理
        proxy: {
            '/api': {
                target: 'your https address',
                changeOrigin: true,
                rewrite: (path: string) => path.replace(/^\/api/, '')
            }
        }
    }
});

代码质量&风格统一

代码质量风格统一的最佳实践是将 ESLint 与 Prettier 配合使用,具体参考这几篇文章:

在配置之前需要了解 ESLint、Prettier 的一些工具,ESLint 和 Prettier 又分 npm 包和 vscode 插件,它们的区别是:

  • npm 包:只能在运行时 eslint xxx 或者 prettier xxx 时起作用
  • vscode 插件:1.eslint插件:能在文件中直接通过 eslint 插件直接看到报错效果,然后就能直接随手改正错误;2.prettier插件:可以配合 vscode 格式化程序直接在代码 save 时格式化文件

这里可能会疑惑,如果安装插件就能校验代码那 npm 包到底需不需要装呢?答案是需要,因为并且不是每个人都会装 eslint 或者 prettier 的 vscode插件,所以最佳实践就是:

  1. 通过装 vscode 插件来方便个人开发;
  2. 通过 npm 包来保障和维护多人协作项目整体的代码质量与风格统一。

1. 集成ESLint

npm i eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin -D
  • eslint-plugin-vue:使得 eslint 可以解析 .vue 文件语法;
  • @typescript-eslint/parser:由于 ESLint 默认使用 Espree 进行语法解析,无法识别 TypeScript 的一些语法,故我们需要安装 @typescript-eslint/parser 替代掉默认的解析器;
  • @typescript-eslint/eslint-plugin@typescript-eslint/eslint-plugin 它作为 eslint 默认规则的补充,提供了一些额外的适用于 ts 语法的规则;

通过配置文件:.eslintrc.js 自定义校验格式

module.exports = {
    parser: 'vue-eslint-parser',

    parserOptions: {
        parser: '@typescript-eslint/parser',
        ecmaVersion: 2020,
        sourceType: 'module',
        ecmaFeatures: {
            jsx: true
        }
    },

    extends: [
        'plugin:vue/vue3-recommended',
        'plugin:@typescript-eslint/recommended',
    ],

    rules: {
        // override/add rules settings here, such as:
    }
};

创建忽略文件:.eslintignore

node_modules/
dist/
index.html

命令行式运行:修改 package.json

{
    ...
    "scripts": {
        ...
        "eslint:comment": "使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件",
        "eslint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
    }
    ...
}

2. 集成Prettier

npm i prettier eslint-config-prettier eslint-plugin-prettier -D
  • eslint-config-prettier:禁用所有与格式相关的 ESLint 规则,使 Prettier 提供的可共享配置不会成为障碍。
  • eslint-plugin-prettier:可以理解为 ESLint 的 Prettier,将 Prettier 作为 ESLint 规则运行,并将差异报告为单个 ESLint 问题。此插件附带一个 extends: plugin:prettier/recommended,可一次性设置此插件和 eslint-config-prettier

通过配置文件:.prettierrc.js 自定义格式

module.exports = {
    // 一行最多 80 字符
    printWidth: 80,
    // 使用 4 个空格缩进
    tabWidth: 4,
    // 不使用 tab 缩进,而使用空格
    useTabs: false,
    // 行尾需要有分号
    semi: true,
    // 使用单引号代替双引号
    singleQuote: true,
    // 对象的 key 仅在必要时用引号
    quoteProps: 'as-needed',
    // jsx 不使用单引号,而使用双引号
    jsxSingleQuote: false,
    // 末尾使用逗号
    trailingComma: 'all',
    // 大括号内的首尾需要空格 { foo: bar }
    bracketSpacing: true,
    // jsx 标签的反尖括号需要换行
    jsxBracketSameLine: false,
    // 箭头函数,只有一个参数的时候,也需要括号
    arrowParens: 'always',
    // 每个文件格式化的范围是文件的全部内容
    rangeStart: 0,
    rangeEnd: Infinity,
    // 不需要写文件开头的 @prettier
    requirePragma: false,
    // 不需要自动在文件开头插入 @prettier
    insertPragma: false,
    // 使用默认的折行标准
    proseWrap: 'preserve',
    // 根据显示样式决定 html 要不要折行
    htmlWhitespaceSensitivity: 'css',
    // 换行符使用 lf
    endOfLine: 'auto'
}

在 .eslintrc.js 中添加对prettier的配置

module.exports = {
    ...

    extends: [ // extends 指定扩展的配置, 支持规则的覆盖和聚合
        'plugin:vue/vue3-recommended',
        'plugin:@typescript-eslint/recommended',
        'plugin:prettier/recommended' //如果同时使用了eslint和prettier发生冲突了,会关闭掉与prettier有冲突的规则,也就是使用prettier认为对的规则
    ],

    ...
};

命令行式运行:修改 package.json

{
    ...
    "scripts": {
        ...
        "prettier:comment": "自动格式化当前目录下的所有文件",
        "prettier": "prettier --write"
    }
    ...
}

3. 配置插件

首先在拓展中安装 eslint 和 prettier 插件

然后配置setting.json如下:

{
    // 下面这三个是关键配置
    "editor.formatOnSave": true,
    "[javascript]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
        // 这里也可以使用 "editor.defaultFormatter": "esbenp.prettier-vscode",但是要保证安装了prettier插件
        // 这样使用快捷键格式化 command + k \ command + f,可以进行选择部分代码进行格式化
    },
}

4. 配置 pre-commit

通过上面的配置,我们基本已经可以实现对代码格式化的效果,然后就能愉快的提交代码了。

还有一个问题是,并不一定每个人都配置好了格式化的插件,这就没法保证所有人提交的代码都是格式化后的,所以我们还需要增加最后一道防线,在代码提交前验证一遍。这需要添加git的pre-commit钩子,添加钩子可以手动配置,也可以选择目前成熟的方案,这里我们使用husky + lint-staged方案

参考