frame_front前端项目搭建

181 阅读9分钟

环境搭建

本文档将从0到1记录该项目搭建过程,不定时更新内容

注意: 由于本项目是我的个人学习项目,可能内容不一定完全正确,有错误或者更好的设计方案欢迎评论

本项目环境

PS C:\Users\周文锋\Desktop\frame_front-master\frame_front-master> node -v
v20.13.1
PS C:\Users\周文锋\Desktop\frame_front-master\frame_front-master> pnpm -v
9.1.2

初始化项目

image.png

  • 删除掉多于文件,我们后续会重新搭建(有报错文件都删除就行后续我们会一一介绍

image.png

  • package.json
{
  "name": "frame_front",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc -b && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.4.31"
  },
  "devDependencies": {
    "@types/node": "^20.14.11",
    "@vitejs/plugin-vue": "^5.0.5",
    "typescript": "^5.2.2",
    "vite": "^5.3.4",
    "vue-tsc": "^2.0.24"
  }
}

配置tsconfig

当我们启动vite项目的时候,ts编译器默认会读取当前目录 (输入命令行的目录) 下的tsconfig.json文件中的配置。

{
    // 编译器的选项
    "compilerOptions": {
      "target": "ESNext", // 设置编译后的目标版本
      // 启用此选项后,TypeScript 编译器将允许你使用 # 语法来声明类字段,这些字段将被视为私有的,只能在类的内部访问。
      "useDefineForClassFields": true,
      // 指定要使用的模块化规范
      "module": "ESNext",
      "moduleResolution": "Node", // 决定如何处理模块
      "types": ["vite/client"], //指定全局组件类型
  
      /* 严格的类型检查选项*/
      "strict": true /* 启用所有严格类型检查选项。 */,
      "noImplicitAny": false /* 对隐含的` any `类型的表达式和声明抛出错误。*/,
      // "strictNullChecks": true,              /* 启用严格的null检查 */
      // "strictFunctionTypes": true,           /* 启用函数类型的严格检查。*/
      // "strictBindCallApply": true,           /* 在函数上启用严格的` bind `、` call `和` apply `方法。 */
      // "strictPropertyInitialization": true,  /* 在类中启用属性初始化的严格检查。 */
      // "noImplicitThis": true,                /* 在“这个”表达式上提高错误,并带有隐含的“任何”类型。*/
  
      // "alwaysStrict": true,                  /* 以严格模式解析,并对每个源文件发出“use strict”。 */
      "removeComments": false, // 编译是否移除注释
      "jsx": "preserve", // 指定jsx代码的生成
      "resolveJsonModule": true, // 将json文件视为模块,支持ES6风格的import语法导入
      "isolatedModules": true, // 将每个文件作为单独的模块(与“ts.transpileModule”类似)。
      "esModuleInterop": true, // 提供对CommonJs和ESM模块的导入方式的兼容性
      //指定要使用的包
      "lib": ["ESNext", "DOM"],
      "skipLibCheck": true,
      // 不生成输出文件 开启这个选项后 tsc不会将ts文件编译出来输出js文件
      "noEmit": true,
      "noEmitOnError": false, //当有错误时,并生成编译后的文件
      "baseUrl": "./",
      "paths": {
        "@": ["src"],
        "@/*": ["src/*"]
      }
    },
    "files": ["./vite.config.ts"],
    // 用来指定需要编译的ts文件
    "include": [
      "src/**/*.ts",
      "src/**/*.d.ts",
      "src/**/*.tsx",
      "src/**/*.vue",
      "build/**/*.ts",
      "build/**/*.d.ts",
    ],
    //排除文件
    "exclude": ["node_modules", "dist", "**/*.js"]
  }

步骤:

(1)读取配置文件中的includefile 中指定文件进行编译,并排除exclude中指定的文件不进行编译

"files": ["./vite.config.ts"],
// 用来指定需要编译的ts文件
"include": [
 "src/**/*.ts",
 "src/**/*.d.ts",
 "src/**/*.tsx",
 "src/**/*.vue",
 "build/**/*.ts",
 "build/**/*.d.ts",
],
"exclude": ["node_modules", "dist", "**/*.js"] //排除文件

(2) 读取compilerOptions中配置的编译器选项规则

{
    // 编译器的选项
    "compilerOptions": {
      "target": "ESNext", // 设置编译后的目标版本
      // 启用此选项后,TypeScript 编译器将允许你使用 # 语法来声明类字段,这些字段将被视为私有的,只能在类的内部访问。
      "useDefineForClassFields": true,
      // 指定要使用的模块化规范
      "module": "ESNext",
      "moduleResolution": "Node", // 决定如何处理模块
      "types": ["vite/client"], //指定全局组件类型
  
      /* 严格的类型检查选项*/
      "strict": true /* 启用所有严格类型检查选项。 */,
      "noImplicitAny": false /* 对隐含的` any `类型的表达式和声明抛出错误。*/,
      // "strictNullChecks": true,              /* 启用严格的null检查 */
      // "strictFunctionTypes": true,           /* 启用函数类型的严格检查。*/
      // "strictBindCallApply": true,           /* 在函数上启用严格的` bind `、` call `和` apply `方法。 */
      // "strictPropertyInitialization": true,  /* 在类中启用属性初始化的严格检查。 */
      // "noImplicitThis": true,                /* 在“这个”表达式上提高错误,并带有隐含的“任何”类型。*/
  
      // "alwaysStrict": true,                  /* 以严格模式解析,并对每个源文件发出“use strict”。 */
      "removeComments": false, // 编译是否移除注释
      "jsx": "preserve", // 指定jsx代码的生成
      "resolveJsonModule": true, // 将json文件视为模块,支持ES6风格的import语法导入
      "isolatedModules": true, // 将每个文件作为单独的模块(与“ts.transpileModule”类似)。
      "esModuleInterop": true, // 提供对CommonJs和ESM模块的导入方式的兼容性
      //指定要使用的包
      "lib": ["ESNext", "DOM"],
      "skipLibCheck": true,
      // 不生成输出文件 开启这个选项后 tsc不会将ts文件编译出来输出js文件
      "noEmit": true,
      "noEmitOnError": false, //当有错误时,并生成编译后的文件
      "baseUrl": "./",
      "paths": { //别名
        "@": ["src"],
        "@/*": ["src/*"]
      }
    },
  } 

配置vite.config.js文件

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

注意:即使项目没有在 package.json 中开启 type: "module",Vite 也支持在配置文件中使用 ESM 语法。这种情况下,配置文件会在被加载前自动进行预处理。

你可以显式地通过 --config 命令行选项指定一个配置文件(相对于 cwd 路径进行解析)

vite --config  my-config.js

vite.config.js

import { ConfigEnv, defineConfig, loadEnv, UserConfig } from 'vite'
import {resolve } from 'path'
import { createVitePlugins } from './build/plugins';
import { createProxy } from './build/proxy';
import { wrapperEnv } from './build/getEnv';

// https://vitejs.dev/config/
export default defineConfig( ({  mode } : ConfigEnv) : UserConfig => {
  // 当前node进程的工作目录
  const root = process.cwd();

  // 根据当前工作目录中的 `mode` 加载 .env 文件
  // 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
  const env = loadEnv(mode, root,'');
  // 对环境变量进行格式处理优化
  const viteEnv = wrapperEnv(env);
  return {
    // 根目录
    base: viteEnv.VITE_PUBLIC_PATH,
    root,
    // 配置别名
    resolve: {
      alias: {
        '@': resolve(__dirname, './src'),
      },
    },
    // 反向代理与跨域配置
    server: {
      host: '0.0.0.0',
      port: viteEnv.VITE_PORT,
      open: viteEnv.VITE_OPEN,
      cors: true, //为开发服务器配置CORS,默认启动并允许任何源
      // 反向代理配置
      proxy: createProxy(viteEnv.VITE_PROXY),
    },
    plugins: createVitePlugins(viteEnv),
    // 打包构建规则
    build: {
      // 指定输出路径
      outDir: 'dist',
      // minify: 'esbuild',
      // esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log
      minify: "terser",
      terserOptions: {
      	compress: {
      		drop_console: viteEnv.VITE_DROP_CONSOLE,
      		drop_debugger: true
      	}
      },
      sourcemap: false,
      // 在构建新输出文件时 清除原输出目录中的所有文件
      emptyOutDir: true,
      // 禁用 gzip 压缩大小报告,可略微减少打包时间
      reportCompressedSize: false,
      // 规定触发警告的 chunk 大小
      chunkSizeWarningLimit: 2000,
      rollupOptions: {
        output: {
          // Static resource classification and packaging
          chunkFileNames: 'assets/js/[name]-[hash].js',
          entryFileNames: 'assets/js/[name]-[hash].js',
          assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
        },
      },
    },
  };
})

在根目录新建环境变量配置文件.env

====================.env===========================
# title 标题
VITE_GLOB_APP_TITLE = 李太白

# 本地运行端口号
VITE_PORT = 8848

# 启动时自动打开浏览器
VITE_OPEN = false

# 打包后是否生成包分析文件
VITE_REPORT = false
====================.env.development===========================
# 本地环境
VITE_USER_NODE_ENV = development

# 公共基础路径
VITE_PUBLIC_PATH = /

# 路由模式
# Optional: hash | history
VITE_ROUTER_MODE = history

# 打包时是否删除 console
VITE_DROP_CONSOLE = true

# 是否开启 VitePWA
VITE_PWA = false

# 开发环境接口地址
VITE_API_URL = /api

# 开发环境跨域代理,支持配置多个
VITE_PROXY = [["/api","http://127.0.0.1:8888"]]

关于vite中环境变量相关知识可以看官网中的介绍环境变量

执行步骤

  • 当我们以pnpm run dev命令运行 vite 时,Vite 会自动解析项目根目录(index.html所在的目录下名为 vite.config.js的文件,及上述配置文件
  • 首先通过第12行loadEnv方法可以获取配置文件信息

image.png

  • 通过自定义方法对获取的配置文件进行格式化处理
// 对环境变量进行格式转换
export function wrapperEnv(envConf: Recordable): ViteEnv {
  const ret: any = {};

  for (const envName of Object.keys(envConf)) {
    let realName = envConf[envName].replace(/\\n/g, '\n');
    realName = realName === 'true' ? true : realName === 'false' ? false : realName;
    if (envName === 'VITE_PORT') realName = Number(realName);
    if (envName === 'VITE_PROXY') {
      try {
        realName = JSON.parse(realName);
      } catch (error) {}
    }
    ret[envName] = realName;
  }
  return ret;
}

这里我们使用了ts的范型,需要在tsconfig中include指定的编译文件中进行类型声明

// 配置对象的类型声明
declare interface ViteEnv {
  // 路由模式
  VITE_ROUTER_MODE: 'hash' | 'history';
  // 公共路径
  VITE_PUBLIC_PATH: string;
  // 端口
  VITE_PORT: number;
  // 启动开发服务时是否自动打开浏览器
  VITE_OPEN: boolean;
  // 跨域声明
  VITE_PROXY: [string, string][];
  // 标题
  VITE_GLOB_APP_TITLE: string;
}
/* Vite */
declare type Recordable<T = any> = Record<string, T>;
  • 第32行 createProxy()方法配置反向代理
import type { ProxyOptions } from 'vite';

type ProxyItem = [string, string];

type ProxyList = ProxyItem[];

type ProxyTargetList = Record<string, ProxyOptions>;

/**
 * 创建代理,用于解析 .env.development 代理配置
 * @param list
 */
export function createProxy(list: ProxyList = []) {
  const ret: ProxyTargetList = {};
  for (const [prefix, target] of list) {
    const httpsRE = /^https:\/\//;
    const isHttps = httpsRE.test(target);

    // https://github.com/http-party/node-http-proxy#options
    ret[prefix] = {
      target: target, // 要使用 url 模块解析的 url 字符串
      changeOrigin: true, // 当设置为 true 时,它指示代理服务器在转发请求时修改 Origin 请求头,以匹配目标服务器的主机名。
      ws: true,
      rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
      // https is require secure=false
      ...(isHttps ? { secure: false } : {}),
    };
  }
  return ret;
  /**
    {                                                                                                                                                                               22:04:23
      '/api': { // 接口地址代理
        target: 'http://127.0.0.1:8888', // 接口的域名
        changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
        ws: true,
        rewrite: [Function: rewrite]
      }
    }
  */
}
  • 第35行 通过createVitePlugins()方法配置vite插件
import { PluginOption } from 'vite';
import vue from '@vitejs/plugin-vue';
/**
 * 创建 vite 插件
 * @param viteEnv
 */
export const createVitePlugins = (viteEnv: ViteEnv): (PluginOption | PluginOption[])[] => {
  const { VITE_GLOB_APP_TITLE } = viteEnv;
  return [
    vue(),
  ];
};

vite-plugin-html 插件

vite-plugin-html 是一个 Vite 插件,用于简化 HTML 模板的处理。它允许你在 Vite 项目中更轻松地使用 HTML 文件,支持以下特性:

  1. 基础模板支持:允许你指定一个基础 HTML 模板,其他页面的 HTML 模板将继承这个基础模板。
  2. 多页面支持:可以配置多个入口 HTML 文件,每个文件对应一个页面。
  3. 模板变量替换:支持在 HTML 中使用模板变量,这些变量可以从 Vite 的构建配置中获取。
  4. 环境变量注入:可以将环境变量注入到 HTML 中,例如 VITE_APP_ 开头的环境变量。
  5. CSS 和 JS 资源引用:自动处理 CSS 和 JS 资源的引用路径,确保资源正确加载。
  6. 自定义模板函数:允许你使用自定义函数来修改 HTML 模板。

安装 vite-plugin-html

首先,你需要安装 vite-plugin-html 插件:

npm install vite-plugin-html --save-dev

配置 vite-plugin-html

然后,在createVitePlugins()方法中添加该配置

import { PluginOption } from 'vite';
import vue from '@vitejs/plugin-vue';
import { createHtmlPlugin } from 'vite-plugin-html'
/**
 * 创建 vite 插件
 * @param viteEnv
 */
export const createVitePlugins = (viteEnv: ViteEnv): (PluginOption | PluginOption[])[] => {
  const { VITE_GLOB_APP_TITLE } = viteEnv;
  return [
    vue(),
    // 配置html模板插件
    createHtmlPlugin({
      minify: true, // 是否压缩 html
      inject: { // 注入 HTML 的数据
        data: { title: VITE_GLOB_APP_TITLE }, //	注入的数据
      },
    })
  ];
};

使用 vite-plugin-html

在项目中使用 vite-plugin-html,你可以这样做:

  • 创建 HTML 模板:在指定的基础模板路径创建 HTML 文件,使用模板语法来定义页面结构。
  • 配置入口文件:为每个页面指定一个入口 JavaScript 文件。
  • 构建项目:运行 Vite 的构建命令,插件将处理 HTML 文件,生成最终的 HTML 页面。
  • 自定义模板:如果需要,可以编写自定义模板函数来进一步自定义 HTML 的生成过程。

通过使用 vite-plugin-html,你可以简化 Vite 项目中 HTML 模板的管理,提高开发效率,尤其是在创建多页面应用时非常有用。

  • 在 index.html 中增加 EJS 标签,
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%- title %></title> // 模板语法
  </head>
</html>
  • 在 vite.config.ts 中配置,该方式可以按需引入需要的功能即可
import { defineConfig, Plugin } from 'vite'
import vue from '@vitejs/plugin-vue'
import { createHtmlPlugin } from 'vite-plugin-html'
export default defineConfig({
  plugins: [
    vue(),
    createHtmlPlugin({
      minify: true,
      /**
       * 在这里写entry后,你将不需要在`index.html`内添加 script 标签,原有标签需要删除
       * @default src/main.ts
       */
      entry: 'src/main.ts',
      /**
       * 如果你想将 `index.html`存放在指定文件夹,可以修改它,否则不需要配置
       * @default index.html
       */
      template: 'public/index.html',
      /**
       * 需要注入 index.html ejs 模版的数据
       */
      inject: {
        data: {
          title: 'index',
          injectScript: `<script src="./inject.js"></script>`,
        },
      },
    }),
  ],
})
  • 多页应用配置
import { defineConfig } from 'vite'
import { createHtmlPlugin } from 'vite-plugin-html'
export default defineConfig({
  plugins: [
    createHtmlPlugin({
      minify: true,
      pages: [
        {
          entry: 'src/main.ts',
          filename: 'index.html',
          template: 'public/index.html',
          injectOptions: {
            data: {
              title: 'index',
              injectScript: `<script src="./inject.js"></script>`,
            },
          },
        },
        {
          entry: 'src/other-main.ts',
          filename: 'other.html',
          template: 'public/other.html',
          injectOptions: {
            data: {
              title: 'other page',
              injectScript: `<script src="./inject.js"></script>`,
            },
          },
        },
      ],
    }),
  ],
})
  • 参数说明 vite-plugin-html 是一个用于处理 HTML 文件的 Vite 插件,提供了压缩、加载、CDN 功能等。以下是 vite-plugin-html 的一些关键配置参数说明:
  1. minify (boolean | MinifyOptions): 是否压缩 HTML 代码。默认值为 true。如果需要自定义压缩选项,可以提供 html-minifier-terserOptions 配置。
  2. loading (boolean | HtmlLoadingOptions): 是否在应用根节点增加 loading 代码,避免网络问题造成的白屏。提供 HtmlLoadingOptions 配置,包括 selector、style、before、after 等属性。
  3. cdn (false | HtmlCdnOptions): 配置 vite build 将模块改为 CDN 的方式引用,提高打包速度和减小包体积。HtmlCdnOptions 包括 modules、type、url、local 等属性 。
  4. entry (string): 入口文件,默认值为 src/main.ts。指定你的应用程序入口文件 。
  5. template (string): 模板的相对路径,默认值为 index.html。这是 HTML 模板文件的路径 。
  6. inject (InjectOptions): 注入 HTML 的数据。InjectOptions 包括 data、ejsOptions、tags 等属性 。
  7. pages (PageOption): 多页配置。PageOption 包括 filename、template、entry、injectOptions 等属性 88。
  8. env 注入: 默认会向 index.html 注入 .env 文件的内容,类似 Vite 的 loadEnv 函数 。

使用 vite-plugin-html 时,可以在 vite.config.tsvite.config.js 中配置这些参数,以满足项目需求。例如:

import { defineConfig } from 'vite';
import { createHtmlPlugin } from 'vite-plugin-html';

export default defineConfig({
  plugins: [
    createHtmlPlugin({
      minify: true,
      entry: 'src/main.ts',
      template: 'public/index.html',
      inject: {
        data: {
          title: 'My App',
        },
      },
      // 其他配置...
    }),
  ],
});

以上配置提供了 vite-plugin-html 的基本使用方式,你可以根据项目的具体需求调整这些参数。

集成ESlint和Prettier

操作步骤

安装Pinia

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 export const state = reactive({}) 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞。 而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:

  • 测试工具集

  • 插件:可通过插件扩展 Pinia 功能

  • 为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能。

  • 支持服务端渲染

  • Devtools 支持

    • 追踪 actions、mutations 的时间线
    • 在组件中展示它们所用到的 Store
    • 让调试更容易的 Time travel
  • 热更新

    • 不必重载页面即可修改 Store
    • 开发时可保持当前的 State

开始

  • 安装npm install pinia
  • 创建实例
import { createPinia } from 'pinia'
// 创建pinia实例
const pinia = createPinia()

export default pinia;
  • 在vue中引用中间件
import { createApp } from "vue"
import App from "@/App.vue"
// pinia
import pinia from "@/stores"
createApp(App).use(pinia).mount("#app")
  • 安装pinia持久化插件pnpm install pinia-plugin-persistedstate

pinia-plugin-persistedstate 用于将 Pinia store 中的状态持久化存储,通常存储在浏览器的 localStoragesessionStorage 中。这样,即使在页面刷新或关闭后,状态也能被保留并在下次加载时恢复。

  • 在pinia中注册插件
import { createPinia } from 'pinia'
// pinia 持久化插件
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
// 创建pinia实例
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

export default pinia;
  • 配置插件
import { PersistedStateOptions } from "pinia-plugin-persistedstate";
/**
 * @description pinia 持久化参数配置
 * @param {String} key 存储到持久化的 name
 * @param {Array} paths 需要持久化的 state name
 * @return persist
 * */
const piniaPersistConfig = (key: string, paths?: string[]) => {
  const persist: PersistedStateOptions = {
    key,
    storage: localStorage,
    // storage: sessionStorage,
    paths
  };
  return persist;
};
/**
 * persist 配置项可以是一个对象,包含如下选项:
 * key: 用于引用 storage 中数据的键名,默认为 store 的 $id。
 * storage: 将数据持久化到的 storage,默认为 localStorage。
 * paths: 指定 state 中哪些数据需要被持久化。如果设置为空数组,则不持久化任何状态。
 * serializer 和 deserializer: 自定义序列化和反序列化方法。
 * beforeRestore 和 afterRestore: 恢复数据前后的钩子函数。
 * debug: 是否开启调试模式,开启后会在控制台输出错误信息
 */
export default piniaPersistConfig;

安装路由

  • pnpm add vue-router@4
  • 配置路由
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'

const mode = import.meta.env.VITE_ROUTER_MODE; 

// 路由模式
const routerMode = {
    hash: () => createWebHashHistory(),
    history: () => createWebHistory()
};

//创建路由实例
const router = createRouter({
    history: routerMode[mode],
    routes: []
});

export default router;
``


# 异常处理

## ts无法识别.vue文件的问题

![image.png](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/135a83c448fe47aca7fbf0a2dcdd114d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pWF5Y-K:q75.awebp?rk3s=f64ab15b&x-expires=1776580751&x-signature=AML9p9TTuYD%2FSdYR2cCxPy0wGrc%3D)
> 解决方案

在tsconfig.json`files`或者`include`配置中指定的.d.ts文件下添加vue文件声明
```ts
// 扩展模块 (不懂去看ts关于声明文件的内容)
declare module '*.vue' {
  import { ComponentOptions } from 'vue'
  const componentOptions: ComponentOptions
  export default componentOptions
}

安装element-plus

  • pnpm install element-plus

按需引入

  • 安装插件 npm install -D unplugin-vue-components unplugin-auto-import
  • 配置vite按需引入
import { PluginOption } from "vite"
import { createHtmlPlugin } from "vite-plugin-html"
import vue from "@vitejs/plugin-vue"
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import {ElementPlusResolver} from 'unplugin-vue-components/resolvers'
/**
 * 创建 vite 插件
 * @param viteEnv
 */
export const createVitePlugins = (viteEnv: ViteEnv): (PluginOption | PluginOption[])[] => {
  // 标题
  const { VITE_GLOB_APP_TITLE } = viteEnv
  return [
    vue(),
    // 注入变量到 html 文件
    createHtmlPlugin({
      minify: true,
      inject: {
        data: { title: VITE_GLOB_APP_TITLE }
      }
    }),
    // ElementPlus按需引入配置
    AutoImport({
      resolvers:[ElementPlusResolver()],
    }),
    Components({
      resolvers:[ElementPlusResolver()]
    })
  ]
}

安装element-plus/icons-vue

  • pnpm install @element-plus/icons-vue --save
  • 在main.ts中引入并注册图标
import { createApp } from "vue"
import App from "@/App.vue"
// element plus
import ElementPlus from "element-plus";
// element icons
import * as Icons from "@element-plus/icons-vue";
// pinia
import pinia from "@/stores"
// router
import router from "@/routers"
// 全局样式
import '@/styles/general.css'

const app = createApp(App)

// 注册element的Icons组件
Object.keys(Icons).forEach(key => {
    app.component(key, Icons[key as keyof typeof Icons]);
});

app.use(ElementPlus).use(router).use(pinia).mount("#app")
  • 声明图标类型文件
/// <reference types="vite/client" />
// 扩展模块 (不懂去看ts关于声明文件的内容)
declare module "*.vue" {
  import { ComponentOptions } from "vue"
  const componentOptions: ComponentOptions
  export default componentOptions
}
// element plus 图标声明
declare module '@element-plus/icons-vue';

安装scss

pnpm install sass --save-dev

安装axios

  • pnpm install axios