Vue3发布这么久了,还不会用Vite构建项目?

本次构建的项目技术栈: Vite+Vue3+Volar+Pinia+Vue-Router+TS+JSX+Scss+Script setup

  1. Vite: 下一代前端开发与构建工具,极速的热更新开发体验★★★★★
  2. Vue3.2: 超多的黑魔法
  3. Volar: Vue3必备开发神器
  4. Pinia: 新一代的轻量状态管理器
  5. Vue-Router4: Vue3的官方路由
    1. 安装 sass
    npm install sass -D
    npm install node-sass -D
    npm install sass-loader -D
    1. 安装 @types/node
    npm install @types/node -D
    1. 配置路径别名
      vite.config.ts添加配置
    // vite.congfig.ts
    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    import eslintPlugin from 'vite-plugin-eslint';
    import {join} from "path";
    
    export default defineConfig({
      plugins: [vue(), eslintPlugin()],
      resolve: {
        alias: {
          "@": join(__dirname, "src"),
          "~": join(__dirname, "node_modules")
        }
      }
    });

    tsconfig.json在配置

    {
      "compilerOptions": {
        "target": "esnext",
        "useDefineForClassFields": true,
        "module": "esnext",
        "moduleResolution": "node",
        "strict": true,
        "jsx": "preserve",
        "sourceMap": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "esModuleInterop": true,
        "lib": ["esnext", "dom"],
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
        }
      },
      "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
      "references": [{ "path": "./tsconfig.node.json" }]
    }
    1. 安装 pinia轻量状态管理器
    npm install pinia
    1. 创建 stores/user.ts全局状态store
    import { defineStore } from 'pinia'
    import { ref } from 'vue'
    export const useUserStore = defineStore('counter', () => {
      const count = ref(0)
      function increment() {
        count.value++
      }
    
      return { count, increment }
    })
    1. vue启用 pinia,修改 main.ts代码
    import { createApp } from 'vue'
    import App from './App.vue'
    import {router} from './router'
    import { createPinia } from 'pinia'
    
    createApp(App).use(router).use(createPinia()).mount('#app')
    1. 安装 @vitejs/plugin-vue-jsx
    npm install @vitejs/plugin-vue-jsx -D
    1. vite.config.ts中启用 jsx
    // vite.congfig.ts
    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    import eslintPlugin from 'vite-plugin-eslint';
    import {join} from "path";
    import vueJsx from "@vitejs/plugin-vue-jsx";
    
    export default defineConfig({
      plugins: [vue(), eslintPlugin(), vueJsx()],
      resolve: {
        alias: {
          "@": join(__dirname, "src"),
          "~": join(__dirname, "node_modules")
        }
      }
    });
    1. 修改 tsconfig.json规则,包括 src下所有的 .tsx文件
    {
      "compilerOptions": {
        "target": "esnext",
        "useDefineForClassFields": true,
        "module": "esnext",
        "moduleResolution": "node",
        "strict": true,
        "jsx": "preserve",
        "sourceMap": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "esModuleInterop": true,
        "lib": ["esnext", "dom"],
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
        }
      },
      "include": ["src/**/*.ts", "src/*.tsx", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
      "references": [{ "path": "./tsconfig.node.json" }]
    }
    1. 改造 App.vueApp.tsx,并在 main.ts引入
    // App.tsx
    import { defineComponent } from 'vue';
    import {RouterLink, RouterView} from 'vue-router';
    import './style/app.scss'
    
    export default defineComponent({
      name: 'App',
      setup() {
        return () => (
          <>
            
            
          
        );
      }
    });
    // main.ts
    import { createApp } from 'vue'
    import App from './App'
    import {router} from './router'
    import { createPinia } from 'pinia'
    
    createApp(App).use(router).use(createPinia()).mount('#app')
    1. 项目安装 axios
    npm install --save axios vue-axios
    1. 封装 axios 构造一个通用的 request 方法
    // src/request/base.ts
    
    let BASE_URL = ''
    const TIME_OUT = 30000
    if (process.env.NODE_ENV === 'dev') {
      BASE_URL = '开发环境IP'
    } else if (process.env.NODE_ENV === 'prod') {
      BASE_URL = '生产环境IP'
    } else {
      BASE_URL = '其它环境IP'
    }
    export { BASE_URL, TIME_OUT }
    // src/request/type.ts
    
    import type { AxiosRequestConfig, AxiosResponse } from 'axios'
    
    export interface LJRequestInterceptors {
     requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
     requestInterceptorCatch?: (error: any) => any
     responseInterceptor?: (res: T) => T
     responseInterceptorCatch?: (error: any) => any
    }
    
    export interface LJRequestConfig extends AxiosRequestConfig {
      showLoading?: boolean
      interceptors?: LJRequestInterceptors
    }
    
    // src/request/request.ts
    
    import axios from 'axios'
    import type { AxiosInstance } from 'axios'
    import { LJRequestInterceptors, LJRequestConfig } from './type'
     
    class LJRequest {
    
       instance: AxiosInstance
       interceptors?: LJRequestInterceptors
    
       constructor(config: LJRequestConfig) {
    
          //创建axios实例
          this.instance = axios.create(config)
          //保存基本信息
          this.interceptors = config.interceptors
    
          //使用拦截器
          //从config钟取出的拦截器是对应的实例的拦截器
          this.instance.interceptors.request.use(this.interceptors?.requestInterceptor, this.interceptors?.requestInterceptorCatch)
          this.instance.interceptors.response.use(this.interceptors?.responseInterceptor, this.interceptors?.requestInterceptorCatch)
          //所有的实例都有的拦截器
          this.instance.interceptors.request.use((config) => {
             console.log('所有的实例都有的拦截器: 请求拦截成功')
             console.log(config)
             return config
          }, (err) => {
             console.log('所有的实例都有的拦截器: 请求拦截失败')
             return err
          })
    
          this.instance.interceptors.response.use(
             (res) => {
                console.log('所有的实例都有的拦截器: 响应拦截成功')
                return res.data
             },
             (err) => {
                console.log('所有的实例都有的拦截器: 响应拦截失败')
                //例子:判断不同httpErrorCode显示不同错误信息
                if (err.response.status === 404) {
                   console.log('404错误~')
                }
                return err
             }
          )
       }
    
       request(config: LJRequestConfig): Promise {
          return new Promise((resolve, reject) => {
             //单个请求对请求config的处理
             if (config.interceptors?.requestInterceptor) {
                config = config.interceptors.requestInterceptor(config)
             }
             this.instance
                .request(config)
                .then((res) => {
                   //单个请求对数据的处理
                   if (config.interceptors?.responseInterceptor) {
                      res = config.interceptors.responseInterceptor(res)
                   }
                   console.log(res)
                   //将结果返回出去
                   resolve(res)
                })
                .catch((err) => {
                   reject(err)
                })
          })
       }
    
       get(config: LJRequestConfig): Promise {
          return this.request({ ...config, method: 'GET' })
       }
    
       post(config: LJRequestConfig): Promise {
          return this.request({ ...config, method: 'POST' })
       }
    
       delete(config: LJRequestConfig): Promise {
          return this.request({ ...config, method: 'DELETE' })
       }
    
       patch(config: LJRequestConfig): Promise {
          return this.request({ ...config, method: 'PATCH' })
       }
    }
    
    export default LJRequest
    
    // src/request/index.ts
    
    import LJRequest from './request'
    import { BASE_URL, TIME_OUT } from './base'
    const ljRequest = new LJRequest({
      baseURL: BASE_URL,
      timeout: TIME_OUT,
      interceptors: {
        requestInterceptor: (config) => {
          let _config = {
            ...config,
          }
          _config.headers = {
            ...config.headers,
            token: sessionStorage.getItem("token") as any,
            app: 'visionary'
          }
          console.log('请求成功拦截')
          return _config
        },
    
        requestInterceptorCatch: (err) => {
          console.log('请求失败拦截')
          return err
        },
        responseInterceptor: (config) => {
          console.log('响应成功拦截')
          return config
        },
        responseInterceptorCatch: (err) => {
          console.log('响应失败拦截')
          return err
        }
      }
    })
    
    export default ljRequest
    
    // src/views/index.vue
    
    1. 配置脚本启动参数命令 --mode 环境变量值

      "dev": "vite --host --mode development",

    项目打包的相关问题

    1. 打包遇到对node_modules中的类型进行了检查,可以修改npm build 命令, 增加 --skipLibCheck 参数,如下:

         "build": "vue-tsc --noEmit --skipLibCheck && vite build",
    2. 执行打包命令时,vue-tsc 语法检查报错时,请检查 IDEVolar插件版本和 vue-tsc 版本是否兼容,如遇到新语法不兼容时可升级 vue-tscVolar 的版本,我这里出现的是 vue-tsc 无法识别自定义指令,但是 Volar 是支持的(开发过程不报错),所以我将 vue-tsc 升级到了 0.33.9 版本。
    3. 有时候 vue-tsc 报打包错误,检查 node 版本是否为 14.0.0+ ,使用最新的构建工具建议把 node 版本升级到比较新的版本。

你可能感兴趣的:(vue3vite)