Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架

简介: Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架

Vue2 与 Vue3 的区别

  • Vue3由于完全由TS进行重写,在应用中对类型判断的定义和使用有很强的表现。同一对象的多个键返回值必须通过定义对应的接口(interface)来进行类型定义。要不然在 ESLint 时都会报错。
  • Vue2 与 Vue3 最大的区别: Vue2 使用Options API而 Vue3 使用的Composition API

介绍 vite

  • 💡 极速的开发服务器启动
  • ⚡️ 轻量快速的热模块重载(HMR)
  • 🛠️ 丰富的功能
  • 📦 自带优化的构建
  • 🔩 通用的插件接口
  • 🔑 完全类型化的 API
  • Vite (法语意为 “迅速”,发音 /vit/)是一种全新的前端构建工具,它极大地改善了前端开发体验。

使用 vite 快速创建脚手架

兼容性注意:Vite 需要 Node.js 版本 >= 12.0.0。
  1. 第一步: 在需要创建项目文件目录下打开 cmd 运行以下命令
  # npm 6.x
  npm init vite@latest my-vue-app --template vue

  # npm 7+, 需要额外的双横线:
  npm init vite@latest my-vue-app -- --template vue

  # yarn
  yarn create vite my-vue-app --template vue

  # pnpm
  pnpm create vite my-vue-app -- --template vue
  1. 这里采用npm方法安装

2.png

  1. 这里选择vue-ts 然后回车

3.png

  1. 等项目创建完之后,就可以看到结果了cd到文件夹,安装依赖,启动项目

4.png
5.png

代码风格统一

Eslint支持
# eslint 安装
      yarn add eslint --dev
      # eslint 插件安装
      yarn add eslint-plugin-vue --dev

      yarn add @typescript-eslint/eslint-plugin --dev

      yarn add eslint-plugin-prettier --dev

      # typescript parser
      yarn add @typescript-eslint/parser --dev
  • 项目下新建 .eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    es2021: true,
  },
  parser: "vue-eslint-parser",
  extends: [
    "eslint:recommended",
    "plugin:vue/vue3-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended",
    // eslint-config-prettier 的缩写
    "prettier",
  ],
  parserOptions: {
    ecmaVersion: 12,
    parser: "@typescript-eslint/parser",
    sourceType: "module",
    ecmaFeatures: {
      jsx: true,
    },
  },
  // eslint-plugin-vue @typescript-eslint/eslint-plugin eslint-plugin-prettier的缩写
  plugins: ["vue", "@typescript-eslint", "prettier"],
  rules: {
    "@typescript-eslint/ban-ts-ignore": "off",
    "@typescript-eslint/no-unused-vars": "off",
    "@typescript-eslint/explicit-function-return-type": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/no-var-requires": "off",
    "@typescript-eslint/no-empty-function": "off",
    "@typescript-eslint/no-use-before-define": "off",
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "no-var": "error",
    "prettier/prettier": "error",
    // 禁止出现console
    "no-console": "warn",
    // 禁用debugger
    "no-debugger": "warn",
    // 禁止出现重复的 case 标签
    "no-duplicate-case": "warn",
    // 禁止出现空语句块
    "no-empty": "warn",
    // 禁止不必要的括号
    "no-extra-parens": "off",
    // 禁止对 function 声明重新赋值
    "no-func-assign": "warn",
    // 禁止在 return、throw、continue 和 break 语句之后出现不可达代码
    "no-unreachable": "warn",
    // 强制所有控制语句使用一致的括号风格
    curly: "warn",
    // 要求 switch 语句中有 default 分支
    "default-case": "warn",
    // 强制尽可能地使用点号
    "dot-notation": "warn",
    // 要求使用 === 和 !==
    eqeqeq: "warn",
    // 禁止 if 语句中 return 语句之后有 else 块
    "no-else-return": "warn",
    // 禁止出现空函数
    "no-empty-function": "warn",
    // 禁用不必要的嵌套块
    "no-lone-blocks": "warn",
    // 禁止使用多个空格
    "no-multi-spaces": "warn",
    // 禁止多次声明同一变量
    "no-redeclare": "warn",
    // 禁止在 return 语句中使用赋值语句
    "no-return-assign": "warn",
    // 禁用不必要的 return await
    "no-return-await": "warn",
    // 禁止自我赋值
    "no-self-assign": "warn",
    // 禁止自身比较
    "no-self-compare": "warn",
    // 禁止不必要的 catch 子句
    "no-useless-catch": "warn",
    // 禁止多余的 return 语句
    "no-useless-return": "warn",
    // 禁止变量声明与外层作用域的变量同名
    "no-shadow": "off",
    // 允许delete变量
    "no-delete-var": "off",
    // 强制数组方括号中使用一致的空格
    "array-bracket-spacing": "warn",
    // 强制在代码块中使用一致的大括号风格
    "brace-style": "warn",
    // 强制使用骆驼拼写法命名约定
    camelcase: "warn",
    // 强制使用一致的缩进
    indent: "off",
    // 强制在 JSX 属性中一致地使用双引号或单引号
    // 'jsx-quotes': 'warn',
    // 强制可嵌套的块的最大深度4
    "max-depth": "warn",
    // 强制最大行数 300
    // "max-lines": ["warn", { "max": 1200 }],
    // 强制函数最大代码行数 50
    // 'max-lines-per-function': ['warn', { max: 70 }],
    // 强制函数块最多允许的的语句数量20
    "max-statements": ["warn", 100],
    // 强制回调函数最大嵌套深度
    "max-nested-callbacks": ["warn", 3],
    // 强制函数定义中最多允许的参数数量
    "max-params": ["warn", 3],
    // 强制每一行中所允许的最大语句数量
    "max-statements-per-line": ["warn", { max: 1 }],
    // 要求方法链中每个调用都有一个换行符
    "newline-per-chained-call": ["warn", { ignoreChainWithDepth: 3 }],
    // 禁止 if 作为唯一的语句出现在 else 语句中
    "no-lonely-if": "warn",
    // 禁止空格和 tab 的混合缩进
    "no-mixed-spaces-and-tabs": "warn",
    // 禁止出现多行空行
    "no-multiple-empty-lines": "warn",
    // 禁止出现;
    semi: ["warn", "never"],
    // 强制在块之前使用一致的空格
    "space-before-blocks": "warn",
    // 强制在 function的左括号之前使用一致的空格
    // 'space-before-function-paren': ['warn', 'never'],
    // 强制在圆括号内使用一致的空格
    "space-in-parens": "warn",
    // 要求操作符周围有空格
    "space-infix-ops": "warn",
    // 强制在一元操作符前后使用一致的空格
    "space-unary-ops": "warn",
    // 强制在注释中 // 或 /* 使用一致的空格
    // "spaced-comment": "warn",
    // 强制在 switch 的冒号左右有空格
    "switch-colon-spacing": "warn",
    // 强制箭头函数的箭头前后使用一致的空格
    "arrow-spacing": "warn",
    "no-var": "warn",
    "prefer-const": "warn",
    "prefer-rest-params": "warn",
    "no-useless-escape": "warn",
    "no-irregular-whitespace": "warn",
    "no-prototype-builtins": "warn",
    "no-fallthrough": "warn",
    "no-extra-boolean-cast": "warn",
    "no-case-declarations": "warn",
    "no-async-promise-executor": "warn",
  },
  globals: {
    defineProps: "readonly",
    defineEmits: "readonly",
    defineExpose: "readonly",
    withDefaults: "readonly",
  },
};
  1. 项目下新建 .eslintignore

      # eslint 忽略检查 (根据项目需要自行添加)
      node_modules
      dist
    prettier 支持
# 安装 prettier
yarn add prettier --dev
  • 解决 eslint 和 prettier 冲突
# 安装插件 eslint-config-prettier
      yarn add eslint-config-prettier --dev
  • 项目下新建 .prettier.js
 module.exports = {
        tabWidth: 2,
        jsxSingleQuote: true,
        jsxBracketSameLine: true,
        printWidth: 100,
        singleQuote: true,
        semi: false,
        overrides: [
          {
            files: '*.json',
            options: {
              printWidth: 200,
            },
          },
        ],
        arrowParens: 'always',
      }
  • 项目下新建 .prettierignore
# 忽略格式化文件 (根据项目需要自行添加)
      node_modules
      dist
4 package.json 配置:

```js
  {
    "script": {
      "lint": "eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx",
      "prettier": "prettier --write ."
    }
  }
```

##### 配置 husky + lint-staged

  1. 使用husky + lint-staged助力团队编码规范,

    1. 安装插件
npm install husky -dev
      npm install lint-staged -dev
  • husky 是一个为 git 客户端增加 hook 的工具。安装后,它会自动在仓库中的 .git/ 目录下增加相应的钩子;比如 pre-commit 钩子就会在你执行 git commit 的触发。
  • 那么我们可以在 pre-commit 中实现一些比如 lint 检查、单元测试、代码美化等操作
  • lint-staged,一个仅仅过滤出 Git 代码暂存区文件(被 git add 的文件)的工具;这个很实用,因为我们如果对整个项目的代码做一个检查,可能耗时很长,如果是老项目,要对之前的代码做一个代码规范检查并修改的话,这可能就麻烦了呀,可能导致项目改动很大。

  "husky": {
          "hooks": {
            "pre-commit": "lint-staged"
          }
        },
        "lint-staged": {
          "*.{js,jsx,vue,ts,tsx}": [
            "yarn lint",
            "prettier --write",
            "git add"
          ]
        }

配置文件引用别名 alias

  • 直接修改 vite.config.ts 文件配置:
 import { defineConfig } from 'vite'
      import vue from '@vitejs/plugin-vue'
      import path from 'path'

      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [vue()],
        resolve: {
          alias: {
            '@': path.resolve(__dirname, 'src'),
          },
        },
      })
  • 修改 tsconfig.json
{
          "compilerOptions": {
            "target": "esnext",
            "module": "esnext",
            "moduleResolution": "node",
            "strict": true,
            "jsx": "preserve",
            "sourceMap": true,
            "resolveJsonModule": true,
            "esModuleInterop": true,
            "lib": ["esnext", "dom"],
            "baseUrl": ".",
            "paths": {
              "@/*":["src/*"]
            }
          },
          "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
        }

配置 css 预处理器 scss

  • 插件安装

      yarn add sass-loader --dev
      yarn add dart-sass --dev
      yarn add sass --dev
    • 配置全局scss样式

      - 在 src/assets 下新增 style 文件夹,用于存放全局样式文件
      - 新建 main.scss, 设置一个用于测试的颜色变量 :
      
      ```js
        $test-color: rgb(0, 4, 255);
      ```
      
    • 全局配置

        css:{
          preprocessorOptions:{
            scss:{
              additionalData:'@import "@/assets/style/mian.scss";'
            }
          }
        },
      • 组件中使用

          <style scoped lang="scss">
            .title {
              color: $test-color;
            }
          </style>

    2345截图20220801203646.png

路由安装使用

  • 安装路由插件

      yarn add vue-router@4
  • 在 src 文件下新增 router 文件夹 => router.ts 文件,内容如下:
 import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
        const routes: RouteRecordRaw[] = [
          {
            path: '/',
            name: 'home',
            component: () => import('@/views/Home/index.vue'), // 注意这里要带上 文件后缀.vue
          },
        ];

        const router = createRouter({
          history: createWebHistory(),
          routes,
        });

        export default router;
  • 修改入口文件 mian.ts :
 import { createApp } from 'vue'
        import App from './App.vue'
        import router from './router/index'

        const app = createApp(App)

        app.use(router)

        app.mount('#app')
  • 路由文档使用说明

      vue-router: https://next.router.vuejs.org/zh/guide/

状态管理 pinia

  • 由于 vuex 4 对 typescript 的支持让人感到难过,所以状态管理弃用了 vuex 而采取了 pinia. pinia 的作者是 Vue 核心团队成员
  • 安装 pinia

      yarn add pinia@next
  • main.ts 中增加

      import { createPinia } from "pinia"
      # 创建根存储库并将其传递给应用程序
      app.use(createPinia())
  • 在 src 文件夹下新增 store 文件夹,接在在 store 中新增 main.ts

      import { defineStore } from 'pinia'
      export const useMainStore = defineStore({
        id: 'mian',
        state: () =>({
          name: '群主'
        })
      })
  • 组建中获取 store :
<template>
          <div>{{mainStore.name}}</div>
        </template>

        <script setup lang="ts">
        import { useMainStore } from "@/store/mian"

        const mainStore = useMainStore()

        </script>
  • getters 用法介绍

     - Pinia 中的 getter 与 Vuex 中的 getter 、组件中的计算属性具有相同的功能
    
 import { defineStore } from 'pinia'
        export const useMainStore = defineStore({
          id: 'mian',
          state: () => ({
            name: '群主',
          }),
          getters: {
            nameLength: (state) => state.name.length,
          }
      })
  • 组件中使用
<template>
          <div>用户名:{{ mainStore.name }}<br />长度:{{ mainStore.nameLength }}</div>
          <hr/>
          <button @click="updateName">修改store中的name</button>
        </template>

        <script setup lang="ts">
        import { useMainStore } from '@/store/mian'

        const mainStore = useMainStore()

        const updateName = ()=>{
          // $patch 修改 store 中的数据
          mainStore.$patch({
            name: '名称被修改了,nameLength也随之改变了'
          })
        }
        </script>

环境变量配置

  • vite 提供了两种模式:具有开发服务器的开发模式(development)和生产模式(production)

    1. 项目根目录新建:.env.development :

        NODE_ENV=development
        VITE_APP_WEB_URL= 'https://www.baidu.com'
  • 项目根目录新建:.env.production :

      NODE_ENV=production
      VITE_APP_WEB_URL= 'https://www.baidu.com'
  • 使用方式

    mport.meta.env.VITE_APP_WEB_URL

  • 打包区分开发环境和生产环境

      "build:dev": "vue-tsc --noEmit && vite build --mode development",
      "build:pro": "vue-tsc --noEmit && vite build --mode production",

    6.png

  • 通过以上的流程,我们就可以搭建一个企业级专业的脚手架模板
目录
相关文章
|
3月前
|
JavaScript 前端开发 IDE
[译] 用 Typescript + Composition API 重构 Vue 3 组件
[译] 用 Typescript + Composition API 重构 Vue 3 组件
[译] 用 Typescript + Composition API 重构 Vue 3 组件
|
23天前
|
前端开发 JavaScript
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
|
1月前
|
JavaScript 安全 开发工具
在 Vue 3 中使用 TypeScript
【10月更文挑战第3天】
|
3月前
|
JavaScript API
如何使用Vue 3和Type Script进行组件化设计
【8月更文挑战第16天】如何使用Vue 3和Type Script进行组件化设计
46 3
|
3月前
|
JavaScript API
如何使用Vue 3和Type Script进行组件化设计
【8月更文挑战第16天】如何使用Vue 3和Type Script进行组件化设计
60 1
|
3月前
|
JavaScript 前端开发 安全
立等可取的 Vue + Typescript 函数式组件实战
立等可取的 Vue + Typescript 函数式组件实战
|
3月前
|
JavaScript 前端开发 安全
解锁Vue3与TypeScript的完美搭档:getCurrentInstance带你高效打造未来前端
【8月更文挑战第21天】Vue3的getCurrentInstance方法作为Composition API的一部分,让开发者能在组件内访问实例。结合TypeScript,可通过定义组件实例类型实现更好的代码提示与类型检查,提升开发效率与代码质量。例如,定义一个带有特定属性(如myData)的组件实例类型,可以在setup中获取并安全地修改这些属性。这种方式确保了一致性和减少了运行时错误,使开发更加高效和安全。
134 0
|
1月前
|
JavaScript 前端开发 安全
深入理解TypeScript:增强JavaScript的类型安全性
【10月更文挑战第8天】深入理解TypeScript:增强JavaScript的类型安全性
45 0
|
1月前
|
JavaScript 前端开发 开发者
深入理解TypeScript:类型系统与实用技巧
【10月更文挑战第8天】深入理解TypeScript:类型系统与实用技巧
|
2月前
|
存储 JavaScript
typeScript进阶(11)_元组类型
本文介绍了TypeScript中的元组(Tuple)类型,它是一种特殊的数组类型,可以存储不同类型的元素。文章通过示例展示了如何声明元组类型以及如何给元组赋值。元组类型在定义时需要指定数组中每一项的类型,且在赋值时必须满足这些类型约束。此外,还探讨了如何给元组类型添加额外的元素,这些元素必须符合元组类型中定义的类型联合。
47 0