Files
my-mom-system/.cursor/plans/mom-ui_tech_stack_migration_ddb51afc.plan.md
panchengyong c28ada5050 commit content
2026-03-06 02:02:59 +08:00

19 KiB
Raw Permalink Blame History

name, overview, todos, isProject
name overview todos isProject
MOM-UI Tech Stack Migration 将 mom-backend-ui 从 Vue CLI + Vue 2 + Element UI 渐进式升级到 Vite + Vue 3 + Element Plus与 erp-frontend-vue 技术栈保持一致,方便后续合并。
id content status
phase1-vite-setup Phase 1: 创建 vite.config.js移动 index.html 到根目录,更新 package.json scripts安装 Vite + Vue 3 + @vue/compat 依赖,移除 Vue CLI/Webpack 依赖 completed
id content status
phase2-core-modules Phase 2: 更新 main.js (createApp),升级 Vue Router 4升级 Vuex 4替换 SVG 图标系统 (vite-plugin-svg-icons),修改 permission.js completed
id content status
phase3a-element-plus-deps Phase 3a: 替换 Element Plus 依赖 + 更新 main.js 导入 + 迁移公共组件 (31 个 dialog 组件) + 迁移采购入库页面 (4 个 Vue 文件) 作为验证试点 in_progress
id content status
phase3a-2-layout-components Phase 3a-2: 迁移 src/layout/ + src/components/ 中非 dialog 组件 (~38 个 Vue 文件),确保公共组件完全脱离 Element UI completed
id content status
phase3b-wm-module Phase 3b: 迁移仓库管理模块其余页面 (wm, 64 个 Vue 文件),验证整个模块功能正常 pending
id content status
phase3c-remaining-pages Phase 3c: 迁移其余所有页面 (MES 其他 98 + system 19 + monitor 8 + tool 12 + print 6 + 其他 5 = ~148 个 Vue 文件) + 全局样式修正 pending
id content status
phase4-third-party Phase 4: 更新第三方依赖为 Vue 3 兼容版本 (vuedraggable, vue-cropper, echarts, quill, axios 等) completed
id content status
phase5-cleanup Phase 5: 删除旧配置文件,迁移环境变量 (VUE_APP_ -> VITE_),移除 @vue/compat最终清理 pending
false

mom-backend-ui 技术栈升级计划

当前差异对比

维度 mom-backend-ui (当前) erp-frontend-vue (目标)
构建工具 Vue CLI 4 (Webpack) Vite 7
框架 Vue 2.6 Vue 3.5
UI 库 Element UI 2.15 Element Plus 2.x
路由 Vue Router 3.4 Vue Router 4.6
状态管理 Vuex 3.6 自定义 reactive store
语言 JavaScript TypeScript (暂保留 JS)
组件风格 Options API Composition API <script setup>
SVG 图标 svg-sprite-loader + require.context @element-plus/icons-vue

核心挑战

项目有 305 个 Vue 文件 + 225 个 JS 文件,无法一步到位。采用 Vue 3 兼容模式 (@vue/compat) 进行渐进式迁移,确保大部分 Vue 2 代码可以在 Vue 3 下运行,然后逐步修复。


Phase 1: Vite 构建工具替换 + Vue 3 兼容模式

1.1 创建 Vite 配置

mom-backend-ui/ 根目录创建 vite.config.js,参考 erp-frontend-vue/vite.config.ts 的结构:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'

export default defineConfig({
  plugins: [
    vue(),
    createSvgIconsPlugin({
      iconDirs: [path.resolve(__dirname, 'src/assets/icons/svg')],
      symbolId: 'icon-[name]'
    })
  ],
  resolve: {
    alias: { '@': path.resolve(__dirname, './src') },
    // Vue 3 compat mode
    dedupe: ['vue']
  },
  server: {
    port: 80,
    proxy: {
      '/dev-api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/dev-api/, '')
      },
      '/ureport': {
        target: 'http://localhost:8080',
        changeOrigin: true
      }
    }
  },
  css: {
    preprocessorOptions: {
      scss: { api: 'modern-compiler' }
    }
  }
})

1.2 移动并更新 index.html

mom-backend-ui/public/index.html 移到项目根目录,移除 Webpack 模板语法:

  • <%= BASE_URL %> 改为 /
  • <%= webpackConfig.name %> 改为固定标题
  • 添加 <script type="module" src="/src/main.js"></script>

1.3 更新 package.json

  • 添加 "type": "module"
  • 更新 scripts
    • "dev": "vite"
    • "build": "vite build"
    • "preview": "vite preview"

1.4 安装新依赖,移除旧依赖

安装:

  • vue@^3.5 + @vue/compat@^3.5(兼容模式)
  • vite + @vitejs/plugin-vue
  • vite-plugin-svg-icons + fast-glob(替代 svg-sprite-loader
  • sass-embedded(替代 sass + sass-loader

移除:

  • @vue/cli-service, @vue/cli-plugin-babel, @vue/cli-plugin-eslint
  • vue-template-compiler
  • webpack 相关: compression-webpack-plugin, script-ext-html-webpack-plugin, svg-sprite-loader, sass-loader, less-loader
  • babel-eslint, babel-plugin-dynamic-import-node, cross-env
  • core-js

1.5 配置 @vue/compat

vite.config.js 中配置别名,让 vue 指向兼容构建:

resolve: {
  alias: {
    '@': path.resolve(__dirname, './src'),
    'vue': '@vue/compat'
  }
}

同时需要配置 @vitejs/plugin-vue 的 compat 编译器选项:

vue({
  template: {
    compilerOptions: {
      compatConfig: { MODE: 2 }
    }
  }
})

Phase 2: 更新入口文件和核心模块

2.1 更新 main.js

mom-backend-ui/src/main.jsnew Vue() 改为 createApp()

  • import { createApp } from 'vue' 替代 import Vue from 'vue'
  • const app = createApp(App) 替代 new Vue({...})
  • Vue.prototype.xxx 改为 app.config.globalProperties.xxx
  • Vue.component(...) 改为 app.component(...)
  • Vue.use(...) 改为 app.use(...)
  • app.use(store).use(router).mount('#app')

2.2 更新 SVG 图标系统

mom-backend-ui/src/assets/icons/index.js 中的 require.context 替换为 Vite 的 import.meta.glob

import 'virtual:svg-icons-register'
// SvgIcon 组件需要在 main.js 中用 app.component 注册

2.3 升级 Vue Router 3 -> 4

修改 mom-backend-ui/src/router/index.js

  • import { createRouter, createWebHistory } from 'vue-router'
  • new Router({mode: 'history', ...}) 改为 createRouter({ history: createWebHistory(), ... })
  • 移除 Vue.use(Router)
  • scrollBehavior: () => ({ y: 0 }) 改为 scrollBehavior: () => ({ top: 0 })

修改 mom-backend-ui/src/permission.js

  • router.addRoutes(accessRoutes) 改为循环调用 router.addRoute(route)
  • Message 从 Element Plus 导入

2.4 升级 Vuex 3 -> 4

修改 mom-backend-ui/src/store/index.js

  • import { createStore } from 'vuex'
  • new Vuex.Store({...}) 改为 createStore({...})
  • 移除 Vue.use(Vuex)
  • 各 modules 文件暂时不动Vuex 4 向后兼容 module 写法)

Phase 3: Element UI -> Element Plus 迁移(分步进行)

这是工作量最大的部分,影响所有 306 个 Vue 文件。为保证项目平稳升级,拆分为 3a → 3b → 3c 三步,先拿采购入库页面做试点验证,确认方案可行后再逐步扩展到全模块。

Element UI -> Element Plus 通用变更清单

以下变更适用于所有步骤,每步迁移页面时需逐项检查:

  • size 属性: size="mini" -> size="small", size="medium" -> size="default"
  • 图标: <i class="el-icon-xxx"> -> <el-icon><Xxx /></el-icon> 或对应 Element Plus 图标组件
  • v-model 变更: .sync 修饰符移除,改用 v-model:propName
    • :visible.sync -> v-modelDialog
    • :current-page.sync -> v-model:current-pagePagination
    • :page-size.sync -> v-model:page-sizePagination
  • 事件名变更: @current-change 等部分组件事件保持不变;.native 修饰符移除
  • Slot 变更: 部分具名插槽名称变化
  • 移除的属性: el-buttontype="text" 改为 linktext 属性
  • DatePicker: value-format 格式字符串变更 (如 yyyy-MM-dd -> YYYY-MM-DD)

Phase 3a: 替换依赖 + 迁移公共组件 + 采购入库页面试点

目标: 完成 Element Plus 基础切换,优先迁移 src/components 中的公共组件(避免页面迁移时遇到依赖问题),再以采购入库页面(itemrecpt)作为验证试点。

3a.1 替换依赖

3a.2 更新 main.js 中的 Element 导入

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

// 注册图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}
app.use(ElementPlus, { locale: zhCn, size: 'default' })

3a.3 更新 plugins/modal.js 中的 Element 导入

import { Message, MessageBox, Notification, Loading } from 'element-ui' 改为 import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus',并更新对应的 API 调用。

同时更新 permission.js 中的 Message 导入。

3a.4 迁移公共组件31 个包含 Dialog 的组件,优先处理)

目标: 修复所有 src/components 中使用 :visible.sync 的组件,避免页面迁移时遇到 [ElOnlyChild] 错误。

需要迁移的组件列表(按目录分组):

组件分类 文件路径 数量
Select 组件 vendorSelect, iqcSelect, noticeSelect, itemSelect, clientSelect, batchSelect, userSelect, stockSelect, machinerySelect, warehouseSelect, workstationSelect, workorderSelect, procardSelect, qcindexSelect, reportSelect, TaskSelect, defectSelect, dvsubjectSelect, calTeamSelect, oqcSelect, itemBomSelect, dvplanSelect, stocktakingplanSelect, package 31
其他 DictSelect, ImageUpload 2

关键变更点(适用所有组件):

  • :visible.sync="showFlag" -> v-model="showFlag"
  • 移除 v-if="showFlag"Element Plus dialog 自带显示控制)
  • <el-dialog> 必须有单个根元素:添加 <div class="dialog-content-wrapper"> 包裹所有 slot 默认内容
  • <div slot="footer"> -> <template #footer>

当前进度(已完成部分):

  • vendorSelect/single.vue
  • iqcSelect/single.vue
  • noticeSelect/single.vue
  • noticeSelect/lineSingle.vue (进行中)
  • itemSelect/single.vue (进行中)
  • 🔲 其余 26 个组件待迁移

3a.5 迁移采购入库页面(试点验证)

逐一修改以下 4 个文件,按照通用变更清单做 Element Plus 适配:

文件 说明
src/views/mes/wm/itemrecpt/index.vue 采购入库列表页
src/views/mes/wm/itemrecpt/form.vue 采购入库表单页
src/views/mes/wm/itemrecpt/line.vue 采购入库明细行
src/views/mes/wm/itemrecpt/detail.vue 采购入库详情页

验收标准: 启动 vite dev,能正常访问采购入库列表、新增、编辑、查看详情,无控制台报错。


Phase 3a-2: 迁移公共布局和非 Dialog 组件(~38 个 Vue 文件)

目标: 完成 src/layout/src/components/ 中剩余的非 dialog 组件迁移,确保所有公共组件脱离 Element UI。

需要迁移的文件类型

Layout 组件 (src/layout/):

  • Layout 主布局组件
  • Navbar, Sidebar, TagsView 等导航组件
  • AppMain, Settings 等布局子组件
  • 约 10-15 个文件

非 Dialog 公共组件 (src/components/):

  • Pagination分页组件
  • FileUpload文件上传
  • Editor富文本编辑器可能使用 Element UI 依赖)
  • Breadcrumb面包屑
  • SvgIconSVG 图标,已迁移)
  • Dict 相关组件(数据字典)
  • TreeSelect, Cascader 等表单组件
  • 其他工具类组件(约 20-25 个文件)

迁移要点:

  • 替换所有 Element UI 组件为 Element Plus
  • 更新 size="mini" -> size="small"
  • 移除 .native 修饰符
  • 更新图标引用方式
  • 检查并修复任何使用 $message, $alert 等全局方法的调用

验收标准: 所有 src/components/src/layout/ 文件中不再有 element-ui 导入,项目启动无 Element UI 相关警告。


Phase 3b: 仓库管理模块其余页面64 个 Vue 文件)

目标: 确认试点方案可行后,将整个仓库管理模块(views/mes/wm/)全部迁移完成。

需要迁移的子模块(按业务分组):

分组 子模块 文件数
入库 arrivalnotice (到货通知), itemrecpt (采购入库已完成), outsourcerecpt (委外入库), productrecpt (产品入库), miscrecpt (其他入库) ~15
出库 issue (生产领料), productsales (销售出库), outsourceissue (委外出库), miscissue (其他出库), itemconsume (物料消耗) ~15
退料 rtissue (生产退料), rtsales (销售退货), rtvendor (供应商退货) ~9
库存 wmstock (库存查询), stocktaking (盘点), stocktakingplan (盘点计划), transfer (调拨) ~10
基础 warehouse (仓库), location (库区), area (库位), barcode (条码), batch (批次), sn (序列号), package (包装) ~13
通知 salesnotice (销售通知), mrnotice (物料需求通知) ~5

验收标准: 仓库管理菜单下所有页面(列表/表单/详情)均可正常操作,无控制台 Element 组件报错。


Phase 3c: 其余所有页面(~148 个 Vue 文件)+ 全局样式修正

目标: 完成所有剩余页面的迁移,项目彻底脱离 Element UI。

分组 范围 文件数
MES 其他 views/mes/ 除 wm 外 (md, pro, dv, qc, report 等) ~98
系统管理 views/system/ (user, role, menu, dept, dict 等) ~19
监控 views/monitor/ (online, job, server, cache 等) ~8
工具 views/tool/ (gen, build 等) ~12
打印 views/print/ ~6
其他 views/login.vue, views/register.vue, views/index.vue ~5

3c.1 全局样式文件更新

  • 更新 mom-backend-ui/src/assets/styles/ 下的 SCSS 文件中引用 Element UI 类名的部分
  • Element Plus 的 CSS 变量命名有差异(如 --el-color-primary 等)
  • el-icon-loading spinner 等全局引用需更新

验收标准: 全站所有页面功能正常,无 Element UI 残留引用,vite build 成功。


Phase 4: 更新第三方依赖

以下 Vue 2 专属库需要更新为 Vue 3 兼容版本:

当前依赖 操作
vue-meta 2.x 移除,改用 @unhead/vuedocument.title
vuedraggable 2.x 升级到 vuedraggable@next (4.x)
vue-cropper 0.5 升级到 vue-cropper@next
@riophae/vue-treeselect 替换为 vue3-treeselect 或 Element Plus 的 TreeSelect
vue-count-to 替换为 Vue 3 兼容版本或自行实现
vue-plugin-hiprint 确认 Vue 3 兼容性,可能需要替换
echarts 4.9 升级到 5.x
@dhtmlx/trial-vue-gantt 确认 Vue 3 兼容版本
quill 替换为 @vueup/vue-quill
axios 0.24 升级到 1.x

Phase 5: 清理和收尾

5.1 移除旧配置文件

  • 删除 vue.config.js
  • 删除 babel.config.js
  • 删除 .eslintrc.js(后续可按需重新配置 ESLint flat config
  • 删除 build/ 目录preview 脚本)

5.2 移除 @vue/compat

当所有组件和功能正常运行后:

  • vite.config.js 中移除 'vue': '@vue/compat' 别名
  • 移除 compatConfig 编译器选项
  • 卸载 @vue/compat
  • 修复剩余的 Vue 2 兼容性警告

5.3 环境变量迁移

  • VUE_APP_* 环境变量需改为 VITE_* 前缀
  • process.env.VUE_APP_* 改为 import.meta.env.VITE_*
  • 创建 .env.development.env.production 文件

执行建议

  • Phase 1-2 是基础,已完成,项目可用 vite 启动和构建
  • Phase 3a 先做依赖切换 + 采购入库试点,验证迁移方案的完整流程和模式
  • Phase 3b 试点通过后,在仓库管理模块内推广,以模块为单位验证
  • Phase 3c 最后全面铺开,涵盖剩余 layout/components/views
  • Phase 4 可以与 Phase 3 并行,按需处理
  • Phase 5 在所有功能验证通过后进行
  • 整个过程中暂保留 JavaScript不转 TypeScript后续按需迁移
  • 每步完成后都应启动 vite dev 实际操作验证,确认无功能回退再进入下一步