Skyroc Admin React
配置

环境变量与 Vite

理解 apps/admin 的 .env 加载、开发代理、defineConfig 预设和 application/vite 配置边界

这一页说明 apps/admin 的环境变量和 Vite 配置怎么协作。重点是弄清楚三层边界:

apps/admin/.env*
  -> apps/admin/vite.config.ts
    -> @skyroc/web-admin-vite
      -> Vite runtime
      -> apps/admin/src import.meta.env

.env* 提供运行时和代理参数;apps/admin/vite.config.ts 描述当前应用和共享预设的差异;@skyroc/web-admin-vite 负责生成 Vite 配置、读取 env、创建代理、注入插件和全局常量。

适用场景

当你要做下面这些改动时,先看这页:

场景重点位置
切换测试或生产后端apps/admin/.env.testapps/admin/.env.prod
修改开发代理VITE_HTTP_PROXYVITE_PROXY_LOGVITE_SERVICE_BASE_URLVITE_OTHER_SERVICE_BASE_URL
修改应用部署 baseVITE_BASE_URLapplication.base
调整 dev server 端口、open、hostapplication.server
调整构建产物、sourcemap、manual chunksapplication.buildapplication.buildTimeDefineNamevite.build
关闭或配置内置插件application.plugins
使用 Vite 原生能力vite 字段

当前实现位置

文件职责
apps/admin/.env公共环境变量。包含应用标题、路由模式、代理开关、服务 code、默认后端和图标前缀等。
apps/admin/.env.testtest mode 覆盖项。当前主要覆盖测试环境后端地址和其他服务地址。
apps/admin/.env.prodprod mode 覆盖项。当前主要覆盖生产环境后端地址和其他服务地址。
apps/admin/vite.config.ts应用 Vite 入口。直接使用 @skyroc/web-admin-vitedefineConfig
apps/admin-example/vite.config.ts示例应用 Vite 入口。沿用同一套 admin preset,只额外指定示例应用 dev server 端口。
apps/admin/src/types/vite-env.d.tsimport.meta.env 类型声明。新增 env 时应同步这里。
apps/admin/src/utils/service.ts前端请求层根据 env 生成真实 baseURL 或代理 baseURL。
packages/web/admin-vite/src/config.tsdefineConfig 主入口,负责读取 env、生成 preset、合并原始 Vite 配置。
packages/web/admin-vite/src/proxy.ts解析服务地址并创建 Vite dev server proxy。

env 加载规则

当前脚本决定了 Vite 使用哪个 mode:

命令Vite mode会读取
pnpm --filter skyroc-admin devtest.env + .env.test
pnpm --filter skyroc-admin dev:prodprod.env + .env.prod
pnpm --filter skyroc-admin buildprod.env + .env.prod
pnpm --filter skyroc-admin build:testtest.env + .env.test
pnpm --filter skyroc-admin previewVite preview 默认 mode已构建产物的运行配置来自构建时 mode

@skyroc/web-admin-vitedefineConfig 会在内部执行:

const root = application.root ?? process.cwd();
const env = loadEnv(configEnv.mode, application.envDir ?? root);

因此,推荐通过 apps/admin/package.json 的脚本启动,不要在仓库根目录直接执行裸 vite。如果 Vite 命令的执行目录不是 apps/adminrootenvDir 就可能指向错误目录,导致 .env* 没有按预期加载。

当前 env 分组

应用基础信息

变量当前用途
VITE_BASE_URLVite base 和应用更新检测的基础路径。
VITE_APP_TITLE页面标题、devtools 名称等应用展示信息。
VITE_APP_DESCindex.html 的 description。
VITE_SOURCE_MAP当前 env 已声明;现有 Vite preset 没有直接读取它。需要 sourcemap 时,通过 vite.build.sourcemap 明确配置。
VITE_STORAGE_PREFIXapps/admin/src/utils/storage.ts 使用的本地缓存前缀。
VITE_AUTOMATICALLY_DETECT_UPDATE当前 env 已声明;现有更新检测实际由 globalConfig.automaticallyDetectUpdate 和生产环境共同控制。

路由和权限

变量当前用途
VITE_AUTH_ROUTE_MODE路由权限模式,当前类型为 staticdynamic
VITE_ROUTE_HOME静态路由模式下的默认首页。
VITE_MENU_ICON菜单未配置图标时使用的默认 Iconify 图标。
VITE_STATIC_SUPER_ROLE静态权限模式下的超级角色标识。
VITE_ROUTER_HISTORY_MODE声明了路由历史模式类型,当前路由实现仍以 TanStack Router 配置为事实源。

图标和 Iconify

变量当前用途
VITE_ICON_PREFIX图标组件前缀约定。
VITE_ICON_LOCAL_PREFIX本地 svg 图标前缀,当前 globalConfig.localIconPrefix 会读取它。
VITE_ICONIFY_URLsetupAdminPlugins() 中的 Iconify 离线服务地址。

@skyroc/web-admin-vite 的图标插件也可以通过 application.plugins.unpluginIconapplication.plugins.unocssapplication.plugins.autoImport 传入图标相关 options。应用运行时读取的 env 和构建插件 options 不要混在一起:页面和运行时读取 import.meta.env,构建期插件差异放到 vite.config.ts

默认情况下不需要在 vite.config.ts 里专门写图标配置。@skyroc/web-admin-vite 会按当前应用启动目录解析 src/assets/svg-icon,并同时配置:

插件配置作用
application.plugins.unpluginIcon注册本地 SVG sprite 和 unplugin-icons 组件。
application.plugins.unocss让 UnoCSS icon preset 能识别 Iconify 和本地 SVG class。
application.plugins.autoImporticon-* 组件自动导入 resolver 提供相同的图标前缀配置。

只有改本地图标目录、前缀、scale 或 SVG transform 时,才需要在这三处传入同一组图标 options,避免 sprite、UnoCSS class 和自动导入 resolver 使用不同规则。

请求和后端 code

变量当前用途
VITE_SERVICE_BASE_URL主后端服务地址。开发代理开启时,对应 /proxy-default
VITE_OTHER_SERVICE_BASE_URL其他后端服务地址,使用 JSON5 字符串。每个 key 对应 /proxy-{key}
VITE_HTTP_PROXYY 时,开发服务创建代理;请求层在 dev 环境也会改用代理前缀。
VITE_PROXY_LOGY 时,代理请求会在终端打印代理地址和真实请求地址。
VITE_SERVICE_SUCCESS_CODE业务成功 code。
VITE_SERVICE_LOGOUT_CODES需要直接退出登录的业务 code,逗号分隔。
VITE_SERVICE_MODAL_LOGOUT_CODES需要弹窗退出登录的业务 code,逗号分隔。
VITE_SERVICE_EXPIRED_TOKEN_CODES需要刷新 token 后重试的业务 code,逗号分隔。

VITE_OTHER_SERVICE_BASE_URL 当前写法允许外层反引号,内部按 JSON5 解析:

VITE_OTHER_SERVICE_BASE_URL= `{
  "demo": "http://localhost:9528"
}`

也可以写成单行 JSON5:

VITE_OTHER_SERVICE_BASE_URL={ demo: "http://localhost:9528" }

新增其他服务时,只改 env 还不够。请求层需要明确使用对应 key,例如当前 demoRequest 使用的是 otherBaseURL.demo。新增 auth 服务时,应同时扩展请求模块中使用的 other key 类型和请求实例。

Vite 配置入口

当前 apps/admin/vite.config.ts 很薄:

import { defineConfig } from '@skyroc/web-admin-vite';

export default defineConfig({
  application: {
    css: {
      additionalData: '@use "@/styles/scss/global.scss" as *;'
    }
  }
});

这表示 apps/admin 接受共享 Vite 预设的大部分默认值,只声明本应用的 SCSS 全局注入。

apps/admin-example/vite.config.ts 也是同一套写法,只额外保留示例应用端口:

import { defineConfig } from '@skyroc/web-admin-vite';

export default defineConfig({
  application: {
    css: {
      additionalData: '@use "@/styles/scss/global.scss" as *;'
    },
    server: {
      port: 9528
    }
  }
});

这已经是当前推荐写法。图标仍走 admin-vite 默认插件链路,不要为了说明 icon 在这里重复配置 vite-plugin-svg-iconsunplugin-icons 或 UnoCSS icon preset。

defineConfig 支持三种写法:

defineConfig();
defineConfig({ application: {}, vite: {} });
defineConfig(configEnv => ({ application: {}, vite: {} }));

函数写法适合根据 mode 或命令动态配置:

import { defineConfig } from '@skyroc/web-admin-vite';

export default defineConfig(configEnv => {
  return {
    application: {
      base: configEnv.mode === 'prod' ? '/admin/' : '/'
    }
  };
});

applicationvite 的边界

@skyroc/web-admin-vite 刻意把配置分成两层:

字段职责示例
applicationSkyroc Admin 预设语义,用来描述后台应用差异server.portproxy.enabledplugins.routercss.additionalDatabuild.manualChunks
vite原始 Vite UserConfig,在 admin preset 之后 mergeoptimizeDepsserver.fsresolve.conditions、第三方 Vite 插件

优先规则:

  1. 后台应用语义优先放 application
  2. Vite 原生能力或最终覆盖放 vite
  3. 两者都配置同一块时,vite 会在最后通过 mergeConfig(adminConfig, options.vite) 合并。
  4. 如果想完全接管某个 preset,先在 application 里设为 false,再用 vite 补原生配置。

示例:

import { defineConfig } from '@skyroc/web-admin-vite';

export default defineConfig({
  application: {
    plugins: {
      projectInfo: false
    },
    server: {
      open: false,
      port: 3000
    }
  },
  vite: {
    server: {
      fs: {
        strict: false
      }
    }
  }
});

不要把 Vite 原生配置平铺到顶层。顶层只支持 applicationvite,否则 pluginsbuildserverresolve 这些字段会失去明确语义。

admin-vite 默认生成什么

defineConfig 会生成一份 admin 应用默认 Vite 配置,再合并 vite 覆盖层。

配置项默认行为
base优先使用 application.base,否则读取 VITE_BASE_URL,再否则为 /
build使用 admin 构建输出规则,拆分 CSS、图片、页面 chunk、组件 chunk 和基础 vendor chunk。
define注入 __DEV__;默认还会注入 BUILD_TIME
cssapplication.css.additionalData 存在时,写入 SCSS preprocessor options。
plugins注入 TanStack Devtools、TanStack Router、React、Babel、UnoCSS、Icons、auto-import、HTML、inspect、remove-console、project info 等内置插件。
preview默认端口 9725
resolve默认 @ -> src~ -> .,并 dedupe React runtime。
server默认 host = 0.0.0.0open = trueport = 9527,并配置 warmup 文件。
proxydev server 下按 env 生成代理。

内置插件不应在 apps/admin 里重新拼一遍。确实要改插件行为时,优先通过 application.plugins 配置。

代理如何工作

代理由构建期 Vite preset 和运行时请求层共同决定。

Vite dev server 代理

@skyroc/web-admin-vite 默认在满足下面条件时创建代理:

configEnv.command === 'serve'
  && !configEnv.isPreview
  && VITE_HTTP_PROXY === 'Y'

代理目标来自:

VITE_SERVICE_BASE_URL
VITE_OTHER_SERVICE_BASE_URL

默认代理前缀:

服务代理前缀目标来源
主服务/proxy-defaultVITE_SERVICE_BASE_URL
其他服务/proxy-{key}VITE_OTHER_SERVICE_BASE_URL 的 key

请求转发时会去掉代理前缀。例如:

/proxy-default/v1/users -> {VITE_SERVICE_BASE_URL}/v1/users
/proxy-demo/v1/users    -> {demo}/v1/users

如果 VITE_PROXY_LOG=Y,终端会打印代理 URL 和真实请求 URL。

应用请求层 baseURL

apps/admin/src/service/request/index.ts 使用同一组 env 判断请求 baseURL:

const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
const { baseURL, otherBaseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);

开发环境且代理开启时:

request.baseURL     = /proxy-default
demoRequest.baseURL = /proxy-demo

生产构建或代理关闭时:

request.baseURL     = VITE_SERVICE_BASE_URL
demoRequest.baseURL = VITE_OTHER_SERVICE_BASE_URL.demo

因此,切换后端时优先改 .env.test.env.prod;只有代理路径、服务 key 或请求实例结构变化时,才需要改 utils/service.tsservice/request/index.ts

最小可用示例

切换测试环境后端

修改 apps/admin/.env.test

VITE_SERVICE_BASE_URL=https://test-api.example.com
VITE_OTHER_SERVICE_BASE_URL={ demo: "https://test-demo.example.com" }

本地重新启动:

pnpm --filter skyroc-admin dev

如果 VITE_HTTP_PROXY=Y,浏览器请求仍会看到 /proxy-default/proxy-demo,真实目标由 Vite dev server 代理到新的后端。

修改开发服务器端口

apps/admin/vite.config.ts 中修改 admin preset 的 server 配置:

import { defineConfig } from '@skyroc/web-admin-vite';

export default defineConfig({
  application: {
    css: {
      additionalData: '@use "@/styles/scss/global.scss" as *;'
    },
    server: {
      open: false,
      port: 3000
    }
  }
});

这种配置属于 admin 应用预设差异,放在 application.server

增加一个后端服务

先在 env 中增加 key:

VITE_OTHER_SERVICE_BASE_URL={ demo: "http://localhost:9528", auth: "https://auth.example.com" }

开发代理会创建:

/proxy-demo
/proxy-auth

然后在请求层显式使用 otherBaseURL.auth 创建对应请求实例。只加 env 不会自动创建业务 API 模块。

关闭一个内置插件

如果某个应用不需要项目启动提示:

import { defineConfig } from '@skyroc/web-admin-vite';

export default defineConfig({
  application: {
    plugins: {
      projectInfo: false
    }
  }
});

如果要完全禁用 admin 内置插件组:

export default defineConfig({
  application: {
    plugins: false
  }
});

谨慎使用全量禁用。当前应用依赖 TanStack Router、UnoCSS、图标注册和 auto-import 等插件,关掉后通常还要在 vite 字段里补回等价配置。

修改本地图标目录或前缀

默认目录是当前应用的 src/assets/svg-icon。如果确实要改成本应用下的其他目录,需要让三个内置插件保持一致:

import { fileURLToPath } from 'node:url';

import { defineConfig } from '@skyroc/web-admin-vite';

const iconOptions = {
  iconPrefix: 'icon',
  localIconPath: fileURLToPath(new URL('./src/assets/custom-svg-icon', import.meta.url)),
  localIconPrefix: 'icon-local'
};

export default defineConfig({
  application: {
    plugins: {
      autoImport: iconOptions,
      unocss: iconOptions,
      unpluginIcon: iconOptions
    }
  }
});

如果只是新增一个业务图标,把 SVG 放进 src/assets/svg-icon 即可,不需要改 vite.config.ts。菜单里写 menu.localIcon: '文件名',组件里写 <SvgIcon localIcon="文件名" />

常见误区

误区正确做法
直接在仓库根目录运行裸 vite使用 pnpm --filter skyroc-admin dev 等脚本,保证 process.cwd()root.env* 指向 apps/admin
只改 .env.prod 后继续跑 devdev 使用 test mode,应改 .env.test 或使用 dev:prod
开发环境代理开启后还期待浏览器请求直接打远端域名代理开启时请求层会使用 /proxy-default/proxy-{key},真实转发目标在 Vite dev server。
VITE_OTHER_SERVICE_BASE_URL 写成非法 JSON/JSON5使用对象字符串,key 对应代理前缀和请求层 other key。解析失败时其他服务会变成空对象。
把后端服务地址硬编码进 API 文件优先通过 .env.test / .env.prod 配置,再让请求实例读取 getServiceBaseURL() 的结果。
vite.config.ts 顶层平铺 Vite 配置使用 application 描述 admin preset 差异,使用 vite 放原始 Vite 配置。
apps/admin 里复制 admin-vite 内置插件组合通过 application.plugins 修改开关或参数;可复用默认行为应留在 @skyroc/web-admin-vite
新增 env 后没有类型同步更新 apps/admin/src/types/vite-env.d.ts,让 import.meta.env 可检查。

排查顺序

现象先检查
env 修改不生效是否重启了 Vite dev server,当前命令使用的 mode 是否正确。
启动端口不是预期application.server.port 是否配置,是否仍由默认 9527 生效。
代理没有创建是否是 dev server,是否不是 preview,VITE_HTTP_PROXY 是否为 Y
代理目标不对当前 mode 读取的是 .env.test 还是 .env.prodVITE_SERVICE_BASE_URL 是否被 mode 文件覆盖。
其他服务请求 undefinedVITE_OTHER_SERVICE_BASE_URL 是否能被 JSON5 解析,请求层是否使用了存在的 key。
图标或自动导入异常先看 application.plugins.unpluginIcon / unocss / autoImport 是否使用同一组图标 options,再看 VITE_ICON_LOCAL_PREFIX 等运行时配置是否被误用。
构建产物路径不对VITE_BASE_URLapplication.base 和部署路径是否一致。

相关位置

主题继续查看
启动时如何消费 BUILD_TIME、主题、布局和 i18n启动流程
项目启动、构建和预览命令快速开始
组件、菜单和动态菜单图标用法图标使用
请求实例如何使用 baseURL 和业务 code请求概览
切换真实后端和代理细节代理与后端对接
共享 Vite 预设完整 APIdocs/web-kit-docs/content/docs/admin-vite.mdxpackages/web/admin-vite/README.md

On this page