写点什么

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

作者:小周先生
  • 2022 年 8 月 02 日
  • 本文字数:6113 字

    阅读完需:约 20 分钟

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
复制代码

```


2.这里采用 npm 方法安装



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



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




代码风格统一


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",  },};
复制代码

```

  • 项目下新建 .eslintignore

```

 # eslint 忽略检查 (根据项目需要自行添加)  node_modules  dist
复制代码

```


prettier 支持

```

# 安装 prettieryarn add prettier --dev
复制代码

```

  • 解决 eslint 和 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
复制代码

```

  • package.json 配置:

```

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

```

配置 husky + lint-staged

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

```

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, 设置一个用于测试的颜色变量 :


  $test-color: rgb(0, 4, 255);
复制代码


  • 全局配置

```

  css:{    preprocessorOptions:{      scss:{        additionalData:'@import "@/assets/style/mian.scss";'      }    }  },
复制代码

```

  • 组件中使用

```

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

```



路由安装使用

  • 安装路由插件

```

  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)

  • 项目根目录新建:.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",
复制代码



  • 通过以上的流程,我们就可以搭建一个企业级专业的脚手架模板

发布于: 刚刚阅读数: 3
用户头像

小周先生

关注

还未添加个人签名 2019.01.16 加入

还未添加个人简介

评论

发布
暂无评论
Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架_typescript_小周先生_InfoQ写作社区