您当前的位置:首页 > 文章 > Vite + Vue + TypeScript 项目搭建总结

Vite + Vue + TypeScript 项目搭建总结

作者:GreyFable 时间:2024-09-27 阅读数:421 人阅读

1. 初始项目

官网地址:Vite | 下一代的前端工具链

1.1 项目搭建

pnpm create vite	

然后按照提示操作,这里选择的是 Vue + TypeScript,生成的目录结构如下

├── .vscode
│   └── extensions.json
├── public
│   └── vite.svg
├── src
│   ├── assets
│   │   └── vue.svg
│   ├── components
│   │   └── HelloWorld.vue
│   ├── App.vue
│   ├── main.ts
│   ├── style.css
│   └── vite-env.d.ts
├── .gitignore
├── README.md
├── index.html
├── package.json
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts	
  1. .vscode/extensions.json:用来配置推荐安装的 VSCode 插件
  2. public/vite.svg:网站图标,可自定义
  3. src/:存放项目源代码
    1. assets/:存放静态资源,如图片、字体等
    2. components/:存放公共组件
    3. App.vue,根组件
    4. main.ts:入口 TypeScript 文件
    5. vite-env.d.ts:Vite 环境变量
  4. .gitignore:指定被 Git 忽略的文件或文件夹
  5. README.md:描述项目的主要信息
  6. index.html:入口 HTML 文件
  7. package.json:项目的依赖列表和工具配置信息
  8. tsconfig.app.json:定义项目中其他文件的 TypeScript 编译规则
  9. tsconfig.json:tsconfig.node.json和tsconfig.app.json最终会被引入到这个文件中
  10. tsconfig.node.json:专门用来配置vite.config.ts文件的编译规则
  11. vite.config.ts:Vite 配置文件

1.2 配置

官网地址:配置 Vite | Vite 官方中文文档

修改vite.config.ts配置文件

1.2.1 服务器配置

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  server: { port: 3000, proxy: { '/api': 'http://localhost:8080' } },
});

1.2.2 别名

下载@types/node依赖

pnpm install @types/node	

添加别名

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';

export default defineConfig({
  resolve: { alias: { '@': resolve(__dirname, 'src') } },
  plugins: [vue()],
  server: { port: 3000, proxy: { '/api': 'http://localhost:8080' } },
});

修改tsconfig.app.json,添加别名映射

{
  "compilerOptions": {
    "composite": true, // 是否编译构建引用项目
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", // 指定文件用来存储增量编译信息
    "target": "ES2020", // 用于指定编译之后的版本目标
    "useDefineForClassFields": true, // 改变类属性声明的行为
    "module": "ESNext", // 指定要使用的模块标准
    "lib": ["ES2020", "DOM", "DOM.Iterable"], // 指定要包含在编译中的库文件
    "skipLibCheck": true, // 跳过声明文件的类型检查
    /* Bundler mode */
    "moduleResolution": "bundler", // 模块解析策略
    "allowImportingTsExtensions": true, // 允许在非 TypeScript 文件中导入 .ts 或 .tsx 文件
    "resolveJsonModule": true, // 解析 JSON 模块
    "isolatedModules": true, // 是否将每个文件作为单独的模块
    "moduleDetection": "force", // 强制 TypeScript 将所有文件视为模块
    "noEmit": true, // 不生成编译文件
    "jsx": "preserve", // 指定 JSX 代码用于的开发环境
    /* Linting */
    "strict": true, // 是否启动所有类型检查
    "noUnusedLocals": true, // 检查是否有定义但是没有使用的变量
    "noUnusedParameters": true, // 检查是否有在函数体中没有使用的参数
    "noFallthroughCasesInSwitch": true, // 检查 Switch 中是否有 Case 没有使用 break 跳出
    /* Alias */
    "baseUrl": ".", // 设置解析非相对模块名称的基本目录
    "paths": { "@/*": ["src/*"] } // 设置模块名称到基于 baseUrl 的路径映射
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] // 指定要编译的路径列表
}

2. UnoCSS

官网地址:UnoCSS: The instant on-demand Atomic CSS engine

2.1 安装

pnpm add -D unocss	

安装插件

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import UnoCSS from 'unocss/vite';
export default defineConfig({
  resolve: { alias: { '@': resolve(__dirname, 'src') } },
  plugins: [vue(), UnoCSS()],
  server: { port: 3000, proxy: { '/api': 'http://localhost:8080' } },
});

根目录下创建uno.config.ts文件

import { defineConfig } from 'unocss';
export default defineConfig({
  // ...UnoCSS options
});

添加virtual:uno.css到主入口,即main.ts文件

import { createApp } from 'vue';
import App from './App.vue';
import 'virtual:uno.css';
createApp(App).mount('#app');

2.2 预设

  1. Uno preset:默认预设,目前相当于@unocss/preset-wind
    • Wind preset:Tailwind CSS / Windi CSS 兼容预设,继承了@unocss/preset-mini
    • Mini preset:基础预设,只包含最基本的工具
  2. Icons preset:使用纯 CSS 的任意图标,图标数据源为 Iconify
    • pnpm add -D @iconify-json/ic
    • pnpm add -D @iconify-json/mdi
    • pnpm add -D @iconify-json/line-md
    • pnpm add -D @iconify-json/twemoji
  3. Attributify preset:为其他预设启用属性模式
  4. Typography preset:提供一组可以用于为原生 HTML 添加排版默认值的文本类
  5. Tagify preset:为其他预设启用标签化模式

修改uno.config.ts文件

import {
  defineConfig,
  presetAttributify,
  presetIcons,
  presetTagify,
  presetTypography,
  presetUno,
} from 'unocss';

export default defineConfig({
  presets: [
    presetUno(),
    presetIcons(),
    presetAttributify(),
    presetTypography(),
    presetTagify(),
  ],
});

3. unplugin-auto-import

GitHub 地址:unplugin/unplugin-auto-import: Auto import APIs on-demand for Vite, Webpack and Rollup

pnpm i -D unplugin-auto-import	

安装插件

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import UnoCSS from 'unocss/vite';
import AutoImport from 'unplugin-auto-import/vite';
export default defineConfig({
  resolve: { alias: { '@': resolve(__dirname, 'src') } },
  plugins: [
    vue(),
    UnoCSS(),
    AutoImport({
      imports: ['vue', 'vue-router', 'pinia'],
      dirs: [],
      vueTemplate: true,
    }),
  ],
  server: { port: 3000, proxy: { '/api': 'http://localhost:8080' } },
});

当安装了 TypeScript 时,会应用默认配置,生成相关的./auto-imports.d.ts文件,即根目录下,但可以看到在tsconfig.app.json里编译路径列表只包含了src/下的文件,因此要手动添加进去,或者修改配置自定义生成文件路径

{
  "compilerOptions": {
    "composite": true, // 是否编译构建引用项目
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", // 指定文件用来存储增量编译信息
    "target": "ES2020", // 用于指定编译之后的版本目标
    "useDefineForClassFields": true, // 改变类属性声明的行为
    "module": "ESNext", // 指定要使用的模块标准
    "lib": ["ES2020", "DOM", "DOM.Iterable"], // 指定要包含在编译中的库文件
    "skipLibCheck": true, // 跳过声明文件的类型检查
    /* Bundler mode */
    "moduleResolution": "bundler", // 模块解析策略
    "allowImportingTsExtensions": true, // 允许在非 TypeScript 文件中导入 .ts 或 .tsx 文件
    "resolveJsonModule": true, // 解析 JSON 模块
    "isolatedModules": true, // 是否将每个文件作为单独的模块
    "moduleDetection": "force", // 强制 TypeScript 将所有文件视为模块
    "noEmit": true, // 不生成编译文件
    "jsx": "preserve", // 指定 JSX 代码用于的开发环境
    /* Linting */
    "strict": true, // 是否启动所有类型检查
    "noUnusedLocals": true, // 检查是否有定义但是没有使用的变量
    "noUnusedParameters": true, // 检查是否有在函数体中没有使用的参数
    "noFallthroughCasesInSwitch": true, // 检查 Switch 中是否有 Case 没有使用 break 跳出
    /* Alias */
    "baseUrl": ".", // 设置解析非相对模块名称的基本目录
    "paths": { "@/*": ["src/*"] } // 设置模块名称到基于 baseUrl 的路径映射
  },
  // 指定要编译的路径列表
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "auto-imports.d.ts"
  ]
}

4. unplugin-vue-components

GitHub 地址:unplugin/unplugin-vue-components: ?? On-demand components auto importing for Vue

pnpm i unplugin-vue-components -D 

安装插件

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import UnoCSS from 'unocss/vite';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
export default defineConfig({
  resolve: { alias: { '@': resolve(__dirname, 'src') } },
  plugins: [
    vue(),
    UnoCSS(),
    AutoImport({
      imports: ['vue', 'vue-router', 'pinia'],
      dirs: [],
      vueTemplate: true,
    }),
    Components(),
  ],
  server: { port: 3000, proxy: { '/api': 'http://localhost:8080' } },
});

和 unplugin-auto-import 一样,会应用默认配置,生成相关的./components.d.ts文件,同样将其加入到编译路径列表

{
  "compilerOptions": {
    "composite": true, // 是否编译构建引用项目
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", // 指定文件用来存储增量编译信息
    "target": "ES2020", // 用于指定编译之后的版本目标
    "useDefineForClassFields": true, // 改变类属性声明的行为
    "module": "ESNext", // 指定要使用的模块标准
    "lib": ["ES2020", "DOM", "DOM.Iterable"], // 指定要包含在编译中的库文件
    "skipLibCheck": true, // 跳过声明文件的类型检查
    /* Bundler mode */
    "moduleResolution": "bundler", // 模块解析策略
    "allowImportingTsExtensions": true, // 允许在非 TypeScript 文件中导入 .ts 或 .tsx 文件
    "resolveJsonModule": true, // 解析 JSON 模块
    "isolatedModules": true, // 是否将每个文件作为单独的模块
    "moduleDetection": "force", // 强制 TypeScript 将所有文件视为模块
    "noEmit": true, // 不生成编译文件
    "jsx": "preserve", // 指定 JSX 代码用于的开发环境

    /* Linting */
    "strict": true, // 是否启动所有类型检查
    "noUnusedLocals": true, // 检查是否有定义但是没有使用的变量
    "noUnusedParameters": true, // 检查是否有在函数体中没有使用的参数
    "noFallthroughCasesInSwitch": true, // 检查 Switch 中是否有 Case 没有使用 break 跳出
    /* Alias */
    "baseUrl": ".", // 设置解析非相对模块名称的基本目录
    "paths": { "@/*": ["src/*"] } // 设置模块名称到基于 baseUrl 的路径映射
  },
  // 指定要编译的路径列表
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "auto-imports.d.ts",
    "components.d.ts"
  ]
}

5. Vue Router

官网地址:Vue Router | Vue.js 的官方路由

pnpm add vue-router@4	

创建src/router/index.ts文件

import { createRouter, createWebHistory } from 'vue-router';

const routes = [{ path: '/', component: () => import('@/App.vue') }];

const router = createRouter({
  history: createWebHistory(),
  routes,
  scrollBehavior(_to, _from, savedPosition) {
    return savedPosition ? savedPosition : { left: 0, top: 0 };
  },
});

export default router;

将src/router/index.ts添加到主入口

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import 'virtual:uno.css';
createApp(App).use(router).mount('#app');

6. Pinia

官网地址:Pinia | The intuitive store for Vue.js

pnpm install pinia	

创建一个 pinia 实例(根 store)并将其传递给应用

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { createPinia } from 'pinia';
import 'virtual:uno.css';
createApp(App).use(router).use(createPinia()).mount('#app');

创建一个src\pinia\index.ts文件

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++;
    },
  },
});

7. Axios

官网地址:Axios

pnpm install axios	

创建src\request\index.ts文件,自定义一个 Axios 实例

import axios from 'axios';
const request = axios.create({
  timeout: 5000,
  headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
});
// 请求拦截器
request.interceptors.request.use(
  (config) => {
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);
// 响应拦截器
request.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // 未认证
          break;
        case 403:
          // 未授权
          break;
        case 404:
          // 资源未找到
          break;
        case 408:
          // 超时
          break;
        case 500:
          // 服务器错误
          break;
        default:
          // 未知错误
          break;
      }
    }
    return Promise.reject(error);
  }
);
export default request;

8. Element Plus(可选)

官网地址:一个 Vue 3 UI 框架 | Element Plus

自动导入

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import UnoCSS from 'unocss/vite';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig({
  resolve: { alias: { '@': resolve(__dirname, 'src') } },
  plugins: [
    vue(),
    UnoCSS(),
    AutoImport({
      imports: ['vue', 'vue-router', 'pinia'],
      dirs: ['src/router', 'src/request'],
      vueTemplate: true,
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
  server: { port: 3000, proxy: { '/api': 'http://localhost:8080' } },
});

本站大部分文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了您的权益请来信告知我们删除。邮箱:1451803763@qq.com