质量保障接口测试测试后端前端AI 应用DevOps【免费下载链接】metersphereMeterSphere 是新一代的开源持续测试工具内置 AI 助手让软件测试工作更简单、更高效不再成为持续交付的瓶颈。项目地址https://gitcode.com/gh_mirrors/me/metersphere点击查看免费下载MeterSphere 是新一代开源持续测试平台其 frontend 目录承载了整套基于 Vue 3 Vite TypeScript 的单页应用。本文以 frontend/README.md 为骨架结合仓库中真实的配置、源码与构建脚本系统讲解 MeterSphere 前端的 Git 提交规范、目录架构、Pinia 状态管理、Axios 网络层封装、指令集、hooks、国际化、环境变量、TailwindCSS、TS 配置以及 Vite 构建优化与本地生产调试帮助开发者在接手或改造该项目时快速对齐约定、少踩坑。一、Git 提交规范commitlint 与 Conventional CommitsMeterSphere 前端在 commitlint.config.cjs 中直接继承commitlint/config-conventional并在 package.json 的prepare脚本中通过 husky 安装钩子来强制校验 commit 消息配合lint-stagedpackage.json实现提交前自动执行 prettier、eslint、stylelint。1.1 提交消息格式仓库约定的标准格式如下Type[optional Scope]: Description [optional body] [optional footer]Type提交类型表示提交的目的或影响范围取值范围包括feat新功能A new featurefix修复 bugA bug fixdocs文档变更Documentation changesstyle代码样式调整Code style changesrefactor代码重构Code refactoringtest测试相关的变更Test-related changeschore构建过程或工具变动Build process or tooling changesperf性能优化Performance optimizationciCI/CD 相关的变动Changes to the CI/CD configuration or scriptsrevert撤销之前的提交Revert a previous commitScope作用域本次提交影响的部分代码或模块可根据项目需要选择性添加例如feat(user)表示用户模块的新功能。Description描述简明扼要地描述本次提交内容。body正文可选的详细描述可以包含更多信息和上下文。footer脚注可选的脚注通常用于引用相关的问题编号或关闭问题例如Closes #123。1.2 示例提交消息feat(user): add login functionality - Add login form and authentication logic - Implement user authentication API endpoints Closes #123该示例中提交类型为feat新功能作用域为user描述了添加登录功能的内容正文部分提供了更详细的说明并引用了问题编号。二、目录架构总览frontend目录从入口到业务模块做了清晰的职责划分整体结构如下frontend/README.md 原文结构与实际仓库保持一致├── babel.config.js // babel配置支持JSX ├── commitlint.config.js // commitlint配置校验commit信息 ├── components.d.ts // 组件注册TS声明 ├── config // 项目构建配置 │ ├── plugin // 构建插件 │ ├── utils // 构建工具方法 │ ├── vite.config.base.ts // vite基础配置 │ ├── vite.config.dev.ts // vite开发环境配置 │ └── vite.config.prod.ts // vite 生产配置 ├── index.html // 单页面html模板 ├── src │ ├── App.vue // 应用入口vue │ ├── api // 项目请求api封装 │ │ ├── http // axios封装 │ │ ├── modules // 各业务模块的请求方法 │ │ ├── requrls // 按业务模块划分的接口地址 │ ├── assets // 全局静态资源 │ │ ├── font │ │ ├── icon-font │ │ ├── images │ │ ├── style │ │ ├── svg │ ├── components // 组件 │ ├── config // 全局配置常量类、JSON │ ├── directive // 自定义指令集 │ ├── enums // 全局枚举定义 │ ├── hooks // 全局hooks集 │ ├── layout // 应用布局组件 │ ├── locale // 国际化配置 │ ├── main.ts // 项目主入口 │ ├── models // 全局数据模型定义 │ ├── router // 路由 │ ├── store // pinia状态库 │ ├── types // 全局TS声明 │ ├── utils // 公共工具方法 │ └── views // 页面模块 │ ├── modules // 页面模块 │ └── base // 公共页面403、404等 ├── env.d.ts // 环境信息TS类型声明 └── .env.development // 开发环境变量声明 └── .env.production // 生产环境变量声明 └── .eslintrc.js // eslint配置 └── .prettierrc.js // prettier配置 └── tsconfig.json // 全局TS配置需要说明的是README 中的src/views下标注为modules与base的划分在实际仓库中体现为按业务模块命名的目录如api-test、bug-management、case-management、setting、test-plan、workbench等以及存放公共页面的base目录404、403、500、not-found等从源码结构看二者是同一套约定按功能模块划分页面公共页面单独收敛。构建配置实际位于frontend/config下由 vite.config.base.ts、vite.config.dev.ts、vite.config.prod.ts 三份文件分别管理基础、开发、生产三段配置并支持通过--mode参数切换自定义环境。三、状态管理模块设计PiniaMeterSphere 前端采用Pinia作为 Vue3 状态管理方案其 API 风格与 Redux 类状态管理库类似通过模块化方式注册模块store每个 store 包含数据仓库state、数据包装过滤getter、同步/异步操作action。与 Vuex 相比Pinia 提供了 Composition API、完整支持 TS 以及可扩展的 Plugin 功能。整体模块划分为业务模块modules/*、注册入口index以及插件plugins/*。在 store/index.ts 中声明注册 pinia 并引入自定义插件import { createPinia } from pinia; import piniaPluginPersistedstate from pinia-plugin-persistedstate; import { debouncePlugin } from ./plugins; import useXXStore from ./modules/xx; const pinia createPinia(); // 插件会在实例创建后应用因此插件不能在pinia实例创建前使用 pinia.use(debouncePlugin).use(piniaPluginPersistedstate); export { useXXStore }; // 导出模块store export default pinia;然后在项目入口main.ts中使用import { createApp } from vue; import store from /store; import app from /App.vue; createApp(app).use(store).mount(#app);3.1 plugins基于 lodash 的防抖插件在 store/plugins.ts 内编写 pinia 插件并在注册时引入使用。由于 Pinia 的 TS 类型声明中每个 store 只有三个原生属性state、getters、actions使用额外属性时需先声明import { debounce } from lodash-es; import type { PiniaPluginContext } from pinia; // 首先得声明插件使用到的额外属性 declare module pinia { export interface DefineStoreOptionsBaseS, Store { debounce?: PartialRecordkeyof StoreActionsStore, number; // 防抖配置 } } // 基于lodash的防抖函数封装读取store中debounce配置的属性针对已配置的属性更改操作进行防抖处理 export const debouncePlugin ({ options, store }: PiniaPluginContext): void | Recordstring, any { if (options.debounce) { return Object.keys(options.debounce).reduce((debounceActions: Recordstring, any, action) { debounceActions[action] debounce(store[action], options.debounce![action]); return debounceActions; }, {}); } };在 store 中按如下方式配置防抖export const useStore defineStore(demo, { state: () ({ testDebounce: , }), getters: {}, actions: {}, debounce: { testDebounce: 500, // 值为防抖缓冲时间毫秒 }, });除了自研的debouncePluginstore/index.ts 还通过pinia-plugin-persistedstate为状态提供持久化能力。实际仓库中导出的模块 store 包括useAppStore、useGlobalStore、useMinderStore、useUserStore、useVisitStore等见 store/modules 目录。四、网络模块设计Axios 三层封装网络模块包含三层请求 url 封装api/requrls/*、请求方法封装api/modules/*、请求工具封装api/http/*。4.1 requrls接口地址收敛管理将项目接口地址收敛至此文件夹下管理避免出现多个重复接口 url、方便接口地址复用且方便统一处理export const LoginUrl /api/user/login; export const LogoutUrl /api/user/logout; export const GetUserInfoUrl /api/user/info; export const GetMenuListUrl /api/user/menu;实际仓库中api/requrls下按api-test、bug-management、case-management、project-management、setting、test-plan、user等业务模块拆分例如 requrls/user.ts。4.2 modules请求方法与接口地址解耦将实际请求方法按业务模块划分统一管理与接口地址解耦import axios from axios; import { LoginUrl, LogoutUrl, GetUserInfoUrl, GetMenuListUrl } from /api/requrls/user; import type { RouteRecordNormalized } from vue-router; import type { UserState } from /store/modules/user/types; import type { LoginData, LoginRes } from /models/user; export function login(data: LoginData) { return axios.postLoginRes(LoginUrl, data); } export function logout() { return axios.postLoginRes(LogoutUrl); } export function getUserInfo() { return axios.postUserState(GetUserInfoUrl); } export function getMenuList() { return axios.postRouteRecordNormalized[](GetMenuListUrl); }最终通过index.ts将请求方法暴露出去export * from ./modules/user; export * from ./modules/dashboard; export * from ./modules/message;4.3 请求工具封装axios 实例与拦截器在 api/http/index.ts 中基于axios封装了统一的MSAxios实例提供form-data/json/urlencoded格式的数据处理、自定义头部处理、响应拦截错误处理、分级提示modal、message、none以及 GET 请求防缓存。// 分级错误信息提示none为静默模式即不提示、modal为对话框提示、message为tips消息提示 // ErrorMessageMode默认为message模式通过传入请求方法的options.errorMessageMode入参判断 export type ErrorMessageMode none | modal | message | undefined; // 三种入参数据格式 export enum ContentTypeEnum { // json JSON application/json;charsetUTF-8, // form-data qs序列化处理 FORM_URLENCODED application/x-www-form-urlencoded;charsetUTF-8, // form-data upload文件流处理 FORM_DATA multipart/form-data;charsetUTF-8, } // 对上传文件请求入参格式额外定义 export interface UploadFileParams { data?: Recordable; // 除文件流外的参数 name?: string; // 文件流字段名 file: File | Blob; // 文件内容 filename?: string; // 文件名 [key: string]: any; // 其他params } // 基准返回数据格式 export interface ResultT any { code: number; type: success | error | warning; message: string; result: T; }实例默认配置了baseURL${window.location.origin}/${import.meta.env.VITE_API_BASE_URL}、超时时间300 * 1000毫秒与Content-Type并通过requestOptions提供细粒度开关见 api/http/index.ts例如isReturnNativeResponse是否返回原生响应头isTransformResponse是否对返回数据进行处理joinParamsToUrlpost 请求时是否添加参数到 urlerrorMessageMode错误提示模式none/modal/messagejoinTime是否加入时间戳防缓存withToken是否携带 token。beforeRequestHook会对 GET 请求自动追加时间戳参数_t该逻辑位于 helper.ts非 restful 时返回{ _t: now }restful 风格时返回?_t${now}。请求拦截器requestInterceptors会从本地 token 中取出sessionId与csrfToken注入X-AUTH-TOKEN、CSRF-TOKEN、Accept-Language、ORGANIZATION、PROJECT等请求头实现登录态、国际化与组织/项目上下文的下发。五、directive 指令集指令入口index.ts导入并注册定义的全部指令见 directive/index.tsimport { App } from vue; import permission from ./permission; export default { install(Vue: App) { Vue.directive(permission, permission); }, };权限指令或其他自定义指令在同级目录下创建以指令名称命名文件夹例如 directive/permission/index.tsimport { DirectiveBinding } from vue; import { useUserStore } from /store; function checkPermission(el: HTMLElement, binding: DirectiveBinding) { const { value } binding; const userStore useUserStore(); const { role } userStore; if (Array.isArray(value)) { if (value.length 0) { const permissionValues value; const hasPermission permissionValues.includes(role); if (!hasPermission el.parentNode) { el.parentNode.removeChild(el); } } } else { throw new Error(need roles! Like v-permission[admin,user]); } } export default { mounted(el: HTMLElement, binding: DirectiveBinding) { checkPermission(el, binding); }, updated(el: HTMLElement, binding: DirectiveBinding) { checkPermission(el, binding); }, };该指令通过mounted与updated两个生命周期钩子对元素进行权限校验不满足权限时直接从 DOM 中移除元素。实际仓库中还包含 outerClick、validateExpiration、validateLicense 等指令分别处理点击外部关闭、有效期校验与 License 校验场景。六、hooks业务逻辑抽象全局抽象钩子集与 Vue2 的 mixins 类似只写业务逻辑的钩子。项目大量复用vueuse/core提供的钩子函数避免重复造轮子在编写钩子功能前建议先到 vueuse 的 Function List 确认是否已有相同功能。导出钩子采用export default function useXxx命名规范以权限钩子为例hooks/usePermission.tsimport { RouteLocationNormalized, RouteRecordRaw } from vue-router; import { useUserStore } from /store; export default function usePermission() { const userStore useUserStore(); return { accessRouter(route: RouteLocationNormalized | RouteRecordRaw) { // do something }, findFirstPermissionRoute(_routers: any, role admin) { // do something }, // You can add any rules you want }; }实际仓库的 hooks 目录中已沉淀了大量可复用钩子如useTableStore、useLocalForage、useModal、useI18n、usePermission、useResponsive、useWebsocket等页面开发时可直接引用。七、layout布局组件项目布局设计模块将最上层布局组件放置此文件夹内统一管理项目各类上层布局例如左侧菜单-右侧内容布局、顶层菜单-中间内容-底部页脚布局等。典型的路由页面容器示例template !-- router-view内为实际路由切换变化的内容视为路由页面容器 -- router-view v-slot{ Component, route } !-- transition为页面切换时提供进出动画平滑过渡页面渲染 -- transition namefade modeout-in appear component :isComponent v-if!route.meta.isCache :keyroute.fullPath / !-- keep-alive提供组件状态缓存以便快速渲染组件内容 -- keep-alive v-else component :isComponent :keyroute.fullPath / /keep-alive /transition /router-view /template该模板通过route.meta.isCache决定是否启用keep-alive缓存配合transition提供平滑的页面切换动画。实际仓库中的 layout 目录包含default-layout.vue、full-page-layout.vue、no-permission-layout.vue、page-layout.vue、share-layout.vue、single-logo-layout.vue等布局分别对应登录、工作台、分享页、无权限页等不同场景。八、models全局数据模型全局数据模型将涉及请求、组件 props、状态库的公共属性抽象为数据模型在此文件夹内声明保证全局数据的类型统一、方便维护。请求模型示例export interface HttpResponseT unknown { status: number; msg: string; code: number; data: T; }也可以是业务相关模型export interface LoginData { username: string; password: string; } export interface LoginRes { token: string; }实际仓库中 models 按业务模块组织例如 models/user.ts 定义用户登录相关模型models/apiTest、models/setting 等分别承载对应业务的数据结构。九、router路由管理项目路由管理模块入口文件index.ts注册并暴露全部路由以模块命名文件夹划分模块路由放置在routes/*下见 router/routes/modulesguard/*下放置路由导航控制包含权限、登录重定向等见 router/guardapp-menus/index.ts为菜单相关的路由信息constants.ts定义路由常量包括路由白名单、重定向路由名、默认主页路由信息等。十、enums全局枚举将可枚举的类型统一管理以类型Enum命名方便维护。示例如下对应 enums/httpEnum.ts 等文件/** * description: Request result set */ export enum ResultEnum { SUCCESS 0, ERROR 1, TIMEOUT 401, TYPE success, } /** * description: request method */ export enum RequestEnum { GET GET, POST POST, PUT PUT, DELETE DELETE, } /** * description: contentTyp */ export enum ContentTypeEnum { JSON application/json;charsetUTF-8, FORM_URLENCODED application/x-www-form-urlencoded;charsetUTF-8, FORM_DATA multipart/form-data;charsetUTF-8, }实际仓库的 enums 目录包含httpEnum.ts、apiEnum.ts、caseEnum.ts、routeEnum.ts、testPlanEnum.ts、workbenchEnum.ts等按业务域划分的枚举文件。十一、locale国际化国际化模块存放项目声明的国际化配置按语种划分模块。模块入口文件为index.ts负责定义菜单、导航栏等公共的国际化配置其他按系统功能声明并导入index.ts页面组件的国际化配置在页面的目录下声明如views/dashboard/workbench/locale。入口实现对应 locale/index.tsimport { createI18n } from vue-i18n; import en from ./en-US; import cn from ./zh-CN; export const LOCALE_OPTIONS [ { label: 中文, value: zh-CN }, { label: English, value: en-US }, ]; const defaultLocale localStorage.getItem(MS-locale) || zh-CN; const i18n createI18n({ locale: defaultLocale, fallbackLocale: en-US, legacy: false, allowComposition: true, messages: { en-US: en, zh-CN: cn, }, }); export default i18n;该实现支持中英文双语默认语言从localStorage的MS-locale读取默认zh-CN并通过fallbackLocale: en-US兜底。实际仓库中 locale/zh-CN 与 locale/en-US 下按common.ts、sys.ts、settings.ts、index.ts组织文案。十二、types 与 utilstypes项目级别的类型声明与业务无关与models、enums不同这里声明的是项目模块级别的类型或工具模块的类型声明例如axios的配置声明、第三方插件不提供 TS 支持但需要我们自定义的声明等。实际仓库中 types 目录包含axios.d.ts、global.d.ts、table.d.ts、window.d.ts等。utils公共方法、工具按功能类型命名文件单个文件内工具方法的功能要对应命名。实际仓库的 utils 目录包含auth.tstoken 存取、is.ts类型判断、tree.ts、xpath.ts、serializeMap.ts等。十三、views页面模块页面模块按功能模块划分公共模块有login、base其中base模块内包含 404、403 页面等。实际仓库中 views 下的业务模块包括api-test、bug-management、case-management、project-management、setting、taskCenter、test-plan、workbench等公共页面集中在 views/baseno-project、no-resource、not-found、redirect等与 views/exception403、404、500。十四、主题配置主题配置流程如下去 Design Lab 创建主题https://arco.design/themes/home主题以ms-theme-命名开头点击页面的配置主题采用CSS 变量 Tailwind 配置变量 基于 css 变量自行计算混合色覆盖 arco-theme 变量的组合方案。实际仓库中theme/default.less 与 theme/green.less 提供了默认与绿色两套主题变量assets/style/var.less 定义了全局 less 变量并通过 vite.config.base.ts 的css.preprocessorOptions.less.modifyVars注入到所有 less 样式中。十五、.env.* 环境变量配置Vite 内置了环境变量配置功能只需在项目根目录下创建以.env.*开头的文件即可。默认.env为生产环境、.env.development为开发环境、.env.XXX为自定义XXX环境自定义环境需要在package.json的项目运行命令后加入--mode XXX。各类环境变量配置示例如下注意环境变量文件内使用注释要用#不能使用//# .env.production 为生产环境配置 NODE_ENVproduction # 代码中通过import.meta.env.NODE_ENV访问 VITE_STG1 # 自定义变量必须用VITE_开头代码中通过import.meta.env.VITE_XXX访问 # .env.development 为开发环境配置 NODE_ENVdevelopment VITE_APP_ENV dev VITE_APP_TITLE 我是标题 # .env.XXX 为自定义环境配置 VITE_MYENV 1 # 代码中通过import.meta.env.VITE_MYENV访问上述环境变量在代码中都可以用import.meta.env.VITE_XXX访问但在vite.config.ts配置文件中无法使用此方法访问——原因是该访问链是 vite 在初始化后通过读取本地.env.XXX文件并注入到import.meta中的而在vite.config.ts中 vite 此时还未初始化。应通过下面的方法访问import { defineConfig, loadEnv } from vite; // 导入loadEnv方法 loadEnv(mode, process.cwd()).VITE_XXX; // 在需要访问env里变量的地方使用此方法访问即可在实际仓库中vite.config.dev.ts 通过dotenv.config({ path: [.env.development.local, .env.development] })注入本地/开发配置环境变量先导入的配置优先级高并据此读取VITE_DEV_DOMAIN配置开发代理package.json 中的脚本分别以--config指定配置文件、以--mode指定环境模式dev、build:local--mode development、build:localProd--mode prod、report通过cross-env REPORTtrue开启分析模式。十六、TailwindCSS 配置module.exports { content: [./index.html, ./src/**/*.{html,js,vue}, ./src/*.{html,js,vue}], // 需要解析的文件路径 theme: { // 自定义主题配置 backgroundColor: { // 自定义背景色 menuHover: #272D39, headerBg: #191E29, }, textColor: (theme) ({ // 自定义字体颜色 ...theme(colors), // 这里必须解构原本有的颜色不然会导致在页面style中使用apply应用内部字体颜色类的时候报错找不到内部字体颜色类 40Gray: rgba(255,255,255,0.40), 65Gray: rgba(255,255,255,0.65), }), extend: {}, }, plugins: [], };实际仓库的 tailwind.config.mjs 中content同样覆盖了index.html与src下的 vue/js 文件且通过apply使用内部字体颜色类时必须先解构theme(colors)否则会报找不到内部字体颜色类的错误。十七、TS 配置tsconfig.jsontsconfig.json 实际配置与 README 基本一致并对 include 做了扩展{ include: [ src/**/*.ts, src/**/*.d.ts, src/**/*.tsx, src/**/*.vue, src/components.d.ts, src/auto-imports.d.ts, types/**/*.d.ts, types/**/*.ts, build/**/*.ts, mock/**/*.ts, __test__/**/*.ts, node_modules/monaco-editor/monaco.d.ts, src/views/test-plan/report/detail/alibabapuhuiti.js ], exclude: [node_modules], compilerOptions: { allowJs: true, noEmit: true, target: esnext, useDefineForClassFields: true, allowSyntheticDefaultImports: true, module: esnext, moduleResolution: node, strict: true, jsx: preserve, sourceMap: true, resolveJsonModule: true, isolatedModules: true, esModuleInterop: true, lib: [esnext, dom], skipLibCheck: true, types: [node], baseUrl: ., paths: { /*: [./src/*], #/*: [types/*] } } }关键配置说明allowJs: true允许编译器编译 JS、JSX 文件noEmit: true仅做类型检查不输出编译产物配合vue-tsc --noEmit的构建前类型检查target/module: esnext使用 ES 最新语法与 ES 模块语法strict: true开启严格模式paths路径映射/*指向./src/*#/*指向types/*与代码中import ... from /...、from #/...的写法对应。十八、Vite 配置插件详解Vite 构建生产资源使用 rollup 打包因此可以在 Vite 中使用 rollup 支持的所有插件。18.1 组件自动导入与按需加载使用unplugin-auto-import/vite插件实现自动导入、unplugin-vue-components/vite插件按需导入自定义组件具体用法如下import AutoImport from unplugin-auto-import/vite import Components from unplugin-vue-components/vite import { ArcoResolver } from unplugin-vue-components/resolvers import { vitePluginForArco } from arco-plugins/vite-vue export default () defineConfig({ plugins: [ // 自定义组件自动引入 AutoImport({ dts: src/auto-import.d.ts, // 输出声明文件地址(使用typescript时必须配置不然会导致页面使用未导入的组件时报错) resolvers: [ElementPlusResolver()], // ElementPlus自动导入 }), // 自定义组件按需引入 Components({ dts: src/components.d.ts, // 输出声明文件地址 dirs: [src/components], // 按需加载的文件夹 resolvers: [ ArcoResolver(), // ArcoDesignVue按需加载 ], }), // 样式自动导入 vitePluginForArco({}) ] })在实际仓库中基础配置 vite.config.base.ts 的AutoImport配置了imports: [vue]将 Vue 的常用 API 自动注入到.ts/.tsx/.vue/.md文件并生成src/auto-import.d.tsArco 组件按需加载由 plugin/arcoResolver.ts 封装其中dirs: []特意避免解析src/components下的业务组件。18.2 SVG 图标自动加载使用vite-plugin-svg-icons插件实现自动加载 svg 图片并通过封装 svg 组件的方式一行代码使用import { createSvgIconsPlugin } from vite-plugin-svg-icons; export default () defineConfig({ plugins: [ createSvgIconsPlugin({ // 指定svg读取的文件夹 iconDirs: [resolve(process.cwd(), src/assets/icons/svg)], // 指定icon的读取名字使用svg文件名为icon名字 symbolId: icon-[dir]-[name], }), ], });实际仓库中 vite.config.base.ts 的createSvgIconsPlugin读取src/assets/svg与public/images两个目录symbolId使用icon-[name]格式此外还通过svgLoadervite-svg-loader支持直接在组件中以组件方式引用 svg 文件。18.3 环境读取与体积分析使用 Vite 自带插件loadEnv读取环境信息做环境判断使用rollup-plugin-visualizer插件分析打包后的文件体积import { defineConfig, loadEnv } from vite; import { visualizer } from rollup-plugin-visualizer; // 这里的mode参数为package.json文件配置的环境参数使用--mode XXX如report: rimraf dist vite build --mode analyze export default ({ mode }) defineConfig({ plugins: [ // 这里通过--mode analyze配置为分析模式使用visualizer插件分析方法输出report.html分析报告 loadEnv(mode, process.cwd()).VITE_ANALYZE Y ? visualizer({ open: true, brotliSize: true, filename: report.html }) : null, ], });实际仓库中 plugin/visualizer.ts 通过 config/utils/index.ts 的isReportMode()判断是否开启分析对应npm run report脚本分析报告输出到node_modules/.cache/visualizer/stats.html同时统计gzipSize与brotliSize。18.4 其他生产构建插件plugin/compress.ts 使用vite-plugin-compression输出 gzip.gz或 brotli.br压缩产物plugin/imagemin.ts 使用vite-plugin-imagemin对 gif/png/jpeg/svg 进行压缩如 mozjpegquality: 20、pngquantquality: [0.8, 0.9]vite.config.prod.ts 还通过vitejs/plugin-legacy依据browserslist 0.5%、last 2 versions、not IE 11做旧浏览器兼容。十九、Vite 配置build 分包详解在 Vite 构建生产资源时通过rollupOptions.output.manualChunks配置分包策略与 webpack 分包机制类似import { mergeConfig } from vite; import baseConfig from ./vite.config.base; import configCompressPlugin from ./plugin/compress; import configVisualizerPlugin from ./plugin/visualizer; import configArcoResolverPlugin from ./plugin/arcoResolver; import configImageminPlugin from ./plugin/imagemin; export default mergeConfig( { mode: production, plugins: [ configCompressPlugin(gzip), configVisualizerPlugin(), configArcoResolverPlugin(), configImageminPlugin(), ], build: { rollupOptions: { output: { manualChunks: { arco: [arco-design/web-vue], chart: [echarts, vue-echarts], vue: [vue, vue-router, pinia, vueuse/core, vue-i18n], }, }, }, chunkSizeWarningLimit: 2000, }, }, baseConfig );实际仓库的 vite.config.prod.ts 将分包扩展为四组vuevue、vue-router、pinia、vueuse/core、vue-i18n、arcoarco-design/web-vue、chartecharts、vue-echarts、codeEditormonaco-editor并将chunkSizeWarningLimit设为 2000KB避免大体积 chunk 的告警干扰。将基础库、UI 组件库、图表库、代码编辑器独立成 chunk可以充分利用浏览器缓存提升首屏加载性能。二十、本地生产环境调试需先安装 docker选择对应系统版本安装然后在frontend目录下执行cd frontend/ pnpm run build:local docker build -t metersphere/ms-v3 . docker run -d -p 5100:5100 --name ms-v3 metersphere/ms-v3其中build:local脚本会先执行vue-tsc --noEmit做类型检查再以vite build --config ./config/vite.config.prod.ts --mode development构建本地生产包随后通过 Docker 镜像metersphere/ms-v3启动容器将宿主机的5100端口映射到容器内5100端口--name ms-v3为容器命名即可在浏览器中访问本地生产构建产物进行验证。仓库根目录还提供了 frontend/Dockerfile 与 frontend/nginx.conf用于容器化部署与 Nginx 托管静态资源。结语MeterSphere 前端在工程化上形成了完整的约定体系Conventional Commits 提交规范约束协作流程api/requrls modules http三层网络封装统一请求行为Pinia 插件机制防抖 持久化扩展状态管理能力Vite 插件矩阵与 manualChunks 分包策略优化构建产物环境变量、国际化、主题、TailwindCSS 与 TS 配置则保证了多环境、多语言、多主题下的可维护性。理解这套设计无论是新增业务页面、扩展请求封装还是定制构建流程都能在既有框架内快速落地。赞分享质量保障接口测试测试后端前端AI 应用DevOps【免费下载链接】metersphereMeterSphere 是新一代的开源持续测试工具内置 AI 助手让软件测试工作更简单、更高效不再成为持续交付的瓶颈。项目地址https://gitcode.com/gh_mirrors/me/metersphere点击查看免费下载相关推荐MeterSphere前端架构深度解析Vue3组件设计与Pinia状态管理实践MeterSphere前端架构深度解析Vue3组件设计与Pinia状态管理实践 MeterSphere作为一站式开源持续测试平台其前端架构采用Vue3 质量保障接口测试测试后端前端AI 应用DevOpsVue3管理系统前端工程化实践从代码规范到构建流程的完整指南Vue3管理系统前端工程化实践从代码规范到构建流程的完整指南 Vue3、Element Plus和TypeScript构建的后台管理系统在前端工程化实践中展现前端企业应用Argos Translate 离线翻译工具怎么用一条命令装好模型快速上手的完整指南Argos Translate 离线翻译工具怎么用一条命令装好模型快速上手的完整指南 Argos Translate 是一个用 Python 编写的免费开源人工智能NLP本地部署创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考