Skip to content

Vite 配置

介绍

下面介绍下 Teek 的 vite.config.ts 的内容。

vite.config.ts 是 Vite 构建、打包的核心配置文件。

Vite 官方文档

环境变量

Teek 在 vite.config.ts 文件里封装了一个文件来获取环境变量,文件路径为 node/getEnv

环境变量指的是项目根目录下 .env 或者 .env.*** 文件里的变量。

假设 .env.development 文件的环境变量为:

sh
VITE_API_URL = '/api'

VITE_PUBLIC_PATH = "/"

VITE_ROUTER_MODE = "h5"

你可以这样在 vite.config.ts 获取环境变量:

ts
import type { ConfigEnv, UserConfig } from "vite";
import { fileURLToPath, URL } from "node:url";
import { defineConfig, loadEnv } from "vite";
import { wrapperEnv } from "./node/getEnv";

export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => {
  const env = loadEnv(mode, process.cwd());
  const viteEnv = wrapperEnv(env);

  console.log("静态文件根路径:" + env.VITE_PUBLIC_PATH);
}

Teek 在 vite.config.ts 文件里通过这样的方式让项目的静态文件 base 路径根据不同的环境变量 VITE_PUBLIC_PATH 来进行配置。

ts
export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => {
  const env = loadEnv(mode, process.cwd());
  const viteEnv = wrapperEnv(env);

  return {
    base: env.VITE_PUBLIC_PATH,
  };
});

@ 符号

在 Teek 项目开发中,@ 是一个常用的符号,它代表 src,如 @/main.ts 代表 src/main.ts

不同目录 的文件之间内容引用的时候,Teek 建议使用 @import 引用。

ts
import SystemConfig from "@/common/config";
import { usePermission } from "@/composables";
import { useSettingsStore, usePermissionStore } from "@/pinia";
import Tooltip from "@/components/Tooltip/index.vue";
import MainContent from "@/layout/components/MainContent/index.vue";
import Header from "@/layout/components/Header/index.vue";
import CommonIcon from "@/layout/components/CommonIcon/index.vue";
import Menu from "@/layout/components/Menu/index.vue";
import { resetRouter } from "@/router";

当文件目录层级深的时候,通过相对路径引用看起来非常不优雅,所以此时使用 @ 可以让代码 import 看起来非常简洁。

当然,如果文件引用的层级不深,完全可以用相对路径来引用:

ts
import LayoutVertical from "./LayoutVertical/index.vue";
import LayoutClassic from "./LayoutClassic/index.vue";
import LayoutTransverse from "./LayoutTransverse/index.vue";
import LayoutColumns from "./LayoutColumns/index.vue";
import LayoutMixins from "./LayoutMixins/index.vue";
import LayoutSubsystem from "./LayoutSubsystem/index.vue";

那么为什么 @ 符号可以代表 src 呢?是 Vue 项目自带还是需要配置呢?

@ 符号是需要配置的,至于为什么叫做 @,这是大家约定成俗的规范。

vite.config.ts 文件里,你可以看到这样一段代码:

ts
import { fileURLToPath, URL } from "node:url";

resolve: {
  alias: {
    "@": fileURLToPath(new URL("./src", import.meta.url))
  },
},

这就是 @ 的配置,如果大家想要有更多的自定义符号映射一个路径,则参考 @ 来添加,如添加 $ 代表 src/components

ts
import { fileURLToPath, URL } from "node:url";

resolve: {
  alias: {
    "@": fileURLToPath(new URL("./src", import.meta.url)),
    "$": fileURLToPath(new URL("./src/components", import.meta.url))
  },
},

plugins 插件

你可以在 vite.config.ts 文件里看到这段代码:

ts
import { getPluginsList } from "./node/plugins";

plugins: getPluginsList(command, viteEnv),

Vite 支持很多的插件,为了不让 vite.config.ts 文件内容太多,因此 Teek 将插件单独抽出来放到 ./node/plugins.ts 文件里。

node/plugins.ts 文件可以看到,Teek 添加了:

  • Vue 支持 jsx、tsx
  • Eslint 相关插件
  • setup 支持组件命名
  • Vue API 自动引入
  • svg 图标使用
  • 静态资源打包压缩
  • 打包分析
  • ...

预构建

请看 预构建

proxy 代理

本地开发的时候,涉及请求,会发生跨域问题,那么最好的一个方式就是代理。

Vite 内置代理模式,所以 Teek 在 vite.config.ts 里写了一个代理 Demo:

ts
server: {
  // 服务器主机名,如果允许外部访问,可设置为 "0.0.0.0"
  host: "0.0.0.0",
  port: viteEnv.VITE_PORT,
  open: viteEnv.VITE_OPEN,
  cors: true,
  // 跨域代理配置
  proxy: {
    "/api": {
      target: "https://vue3-design.teek.cn",
      changeOrigin: true,
      secure: true, // 是否忽略 https 安全证书问题,true 不忽略,false 忽略
      rewrite: path => path.replace(/^\/api/, ""),
    },
  }
}

只需要修改 target 对应的链接就可以了,如果您不需要验证 https 的证书问题,则将 secure 设置为 false

如果本地开发的时候,涉及多个不同服务的接口,则跨域添加多个代理:

ts
server: {
  // 服务器主机名,如果允许外部访问,可设置为 "0.0.0.0"
  host: "0.0.0.0",
  port: viteEnv.VITE_PORT,
  open: viteEnv.VITE_OPEN,
  cors: true,
  // 跨域代理配置
  proxy: {
    "/api": {
      target: "https://vue3-design.teek.cn",
      changeOrigin: true,
      secure: true,
      rewrite: path => path.replace(/^\/api/, ""),
    },
    "/test": {
      target: "https://vue3-design.teek.cn",
      changeOrigin: true,
      secure: true,
      rewrite: path => path.replace(/^\/test/, ""),
    },
  }
}

注意 rewrite 是将代理的标识(如上面的 /api/test)去掉,否则请求的时候将会携带这些标识。

css 全局注入

Teek 使用 Vite 的 css.preprocessorOptionssrc/common/styles/index.scss 里的样式全局注册到项目中。

json
css: {
  preprocessorOptions: {
    scss: {
      additionalData: `@use "@/styles/index.scss" as *;`,
    },
  },
}

提示

@/styles 在 vite 的 resolve.alias 中已经定义,默认指向 src/common/styles

打包

Teek 使用 Vite 自带的打包方式,在打包过程去掉 console.logdebugger 调式代码。

同时对静态资源进行分类打包,如 css 专门放在 css 文件夹下,js 专门放在 js 文件夹下。

具体请看 vite.config.tsbuild 配置项。

Teek 信息

Teek 在 vite.config.ts 里将 package.json 的部分信息和最后一次编译/打包时间全局注入到项目中:

ts
import type { ConfigEnv, UserConfig } from "vite";
import { defineConfig, loadEnv } from "vite";
import pkg from "./package.json";

const __APP_INFO__ = {
  pkg: { dependencies, devDependencies, name, version }, // package.json 相关信息
  lastBuildTime: getNowDate(), // 编译或打包时间
};

export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => {
  const env = loadEnv(mode, process.cwd());
  const viteEnv = wrapperEnv(env);

  return {
    define: {
      __APP_INFO__: JSON.stringify(__APP_INFO__),
    },
  };
});

全局注入到项目是 __APP_INFO__,因此可以在项目的任意位置这样读取:

ts
const { lastBuildTime, pkg } = __APP_INFO__;

console.log("项目最后 Build 时间:" + lastBuildTime);
console.log("项目版本号:" + pkg.version);