vite.config.ts 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { fileURLToPath, URL } from 'node:url';
  2. import vue from '@vitejs/plugin-vue';
  3. import { defineConfig } from 'vite';
  4. /**
  5. * 框架运行时混合方案(移动端,README §技术栈):
  6. *
  7. * ① UMD 全局(Vue 系 + axios):index.html 按序引入 vendor/ 自托管 UMD(dev 经 publicDir 服务,
  8. * 生产经 nginx/OSS),裸标识符(ref、computed、defineStore…)经下方 define 编译期替换为
  9. * Vue.*、VueRouter.*、Pinia.* 全局访问;SFC 编译器产物的模块名 import 经 alias 重定向到
  10. * 仓库根 shims 目录(运行时取 UMD 全局转发,框架本体不进 dist)。
  11. *
  12. * ② npm 编译(Vant):Vant 4 官方无 UMD 构建,只能 import 编译进 bundle——
  13. * 故 Vant **不进** define/alias 清单(`app.use(Vant)` 在 main.ts 走 npm import),
  14. * 模板里 van-* 组件由 Vue 全局组件解析(经 alias 的 vue 转发),无需 vant shim。
  15. * dist 因此含 Vant 运行时(与 PC 端"dist 不含 ElementPlus"的差异点,由 Vant 无 UMD 决定)。
  16. */
  17. /** 可裸写的 Vue 组合式 API 标识符(编译期注入为 Vue.*)——与 PC 端同源清单 */
  18. const VUE_APIS: readonly string[] = [
  19. 'ref', 'shallowRef', 'reactive', 'shallowReactive', 'readonly', 'shallowReadonly',
  20. 'computed', 'watch', 'watchEffect', 'watchPostEffect', 'watchSyncEffect', 'effectScope',
  21. 'onMounted', 'onUnmounted', 'onBeforeMount', 'onBeforeUnmount', 'onUpdated', 'onBeforeUpdate',
  22. 'onActivated', 'onDeactivated', 'onErrorCaptured', 'onRenderTracked', 'onRenderTriggered',
  23. 'onScopeDispose', 'nextTick', 'h', 'inject', 'provide', 'toRef', 'toRefs', 'toRaw', 'toValue',
  24. 'markRaw', 'isRef', 'isReactive', 'isReadonly', 'isVNode', 'customRef', 'triggerRef', 'unref',
  25. 'createApp',
  26. ] as const;
  27. /** 可裸写的 Vue Router 标识符(注入为 VueRouter.*) */
  28. const VUE_ROUTER_APIS: readonly string[] = [
  29. 'createRouter', 'createWebHashHistory', 'createWebHistory', 'useRoute', 'useRouter',
  30. ] as const;
  31. /** 可裸写的 Pinia 标识符(注入为 Pinia.*) */
  32. const PINIA_APIS: readonly string[] = [
  33. 'defineStore', 'createPinia', 'getActivePinia', 'setActivePinia', 'storeToRefs',
  34. ] as const;
  35. const defineMap: Record<string, string> = {};
  36. for (const api of VUE_APIS) defineMap[api] = `Vue.${api}`;
  37. for (const api of VUE_ROUTER_APIS) defineMap[api] = `VueRouter.${api}`;
  38. for (const api of PINIA_APIS) defineMap[api] = `Pinia.${api}`;
  39. export default defineConfig(({ command }) => ({
  40. plugins: [vue()],
  41. /**
  42. * dev(serve):把仓库根 vendor/ 当 public 根,index.html 的 /vendor/<库>@<版本>/<文件> 直接命中,
  43. * 无需 OSS 即可联调;build:不拷贝任何框架文件进 dist(框架由 nginx/OSS 在运行时提供)。
  44. * 注:publicDir 相对 root(本 app 目录)解析,故 ../../vendor = 仓库根 vendor。
  45. */
  46. publicDir: command === 'serve' ? '../../vendor' : false,
  47. resolve: {
  48. alias: {
  49. // UMD 全局框架模块名 → 仓库根 shims 转发层(唯一落点;业务代码禁写这些 import)。
  50. // 路径基:import.meta.url 在 apps/teacher/vite.config.ts,仓库根为上两级(../../)。
  51. vue: fileURLToPath(new URL('../../shims/vue.ts', import.meta.url)),
  52. 'vue-router': fileURLToPath(new URL('../../shims/vue-router.ts', import.meta.url)),
  53. pinia: fileURLToPath(new URL('../../shims/pinia.ts', import.meta.url)),
  54. // 共享层:@unified/shared 直指源码(monorepo 源码消费,免构建)
  55. '@unified/shared': fileURLToPath(new URL('../../packages/shared/src', import.meta.url)),
  56. // 本端业务层路径别名(@ → 本 app 的 src)
  57. '@': fileURLToPath(new URL('./src', import.meta.url)),
  58. },
  59. },
  60. define: defineMap,
  61. server: {
  62. port: 5174,
  63. proxy: {
  64. // dev 联调:/api 前缀请求代理到后端 dev 地址(可用环境变量覆盖)
  65. '/api': {
  66. target: process.env.VITE_API_PROXY_TARGET ?? 'http://127.0.0.1:8080',
  67. changeOrigin: true,
  68. },
  69. },
  70. },
  71. build: {
  72. // 质量门禁:主 chunk 上限(README §质量门禁);UMD 框架误打包时体积会显著超限
  73. //(注意:Vant 经 npm 编译进 bundle 属预期,体积判据需结合 Vant 基础体量,非"零框架"判据)
  74. chunkSizeWarningLimit: 1024,
  75. },
  76. }));