diff --git a/README.md b/README.md index 6ec75df..72c222e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ 本案例中 **[主应用]** 采取的就是OOP风格,当然如果你不熟悉上面的写法,那么可以在 【其他模块】中使用Vue2,Vue3都行,但仍然需要遵守DDD的规范进行开发! +## 架构图 + +![架构图](./doc/jgt.png) + ## 开发日记 - [x] 基于DDD理念改造 @@ -39,6 +43,7 @@ - [docker](https://www.docker.com/) - [drone](https://drone.cool/) - [nacos](https://nacos.io/?spm=5238cd80.47ee59c.0.0.189fcd36fF0ca9) +- [traefik](https://traefik.io/) - [nginx](https://nginx.org/) - [Vue3](https://cn.vuejs.org/) - [Jsx](https://legacy.reactjs.org/docs/introducing-jsx.html) @@ -68,7 +73,7 @@ └── README.md # 帮助文档 ``` -** DDD前端分层目录:** +**DDD前端分层目录:** ```txt src/ @@ -228,39 +233,21 @@ export default class Header extends TSX()(Vue) implements Props { } ``` -## ~~【失效】运行 & 打包~~ +## 部署 -```bash -# 1 下载代码 -git clone https://gitee.com/bmycode/dddmicro-frontend.git +需要后端或运维参与,请注意咨询阅读文档,大致步骤如下: -# 2 运行后端 -cd back-end # 进入 后端 文件夹 -deno install # 安装依赖 -deno run dev # 运行后端 +**全局准备工作:** -# 3 运行前端 -cd front-end # 进入 前端 文件夹 -pnpm install # 会同时为 所有模块 安装依赖 -pnpm add -g concurrently # 全局安装 并发命令执行 插件,局部安装也行,随你。 -pnpm run all # 构建 app-product 和 app-shared 并启动预览,并开发阶段启动 main-app 模块 -# 注意:命令跑完后 ctrl + c 停止,重跑一次!!因为子模块内命令并发执行预览跑在构建之前,解决办法很简单,后面再搞。 -pnpm run all -# 打开 main-app 主模块访问地址即可:[http://localhost:1300/](http://localhost:1300/) +- 1: 准备 >=8台Linux服务器,并提前安装配置好Docker,确保网络可用,建议安装 [1panel](https://1panel.cn/) +- 2: 在1台Linux服务器上,部署公司自己的 Docker Registry 镜像存储库 +- 3: 准本 N台运行 前端各模块 的Linux服务器,并提前组成N个Docker Swarm 集群,以供前端各模块部署使用 +- 4: 准本 >=3台运行 Nacos服务中心 的Linux服务器,并提前组成Docker Swarm 集群,提前运行好,确保服务可用 + - [Nacos 部署文档](./docker/nacos-cluster/README.md) +- 5: 准本 一台 运行 traefik 网关的Linux服务器,,提前运行好,确保服务可用 + - [Traefik 部署文档](./docker/traefik/README.md) -# 4 部署上线 -pnpm run build:main # 构建并预览主应用,预览打包后的主应用,没问题,ctrl + c 停止。 -# 子模块在 第三步 已经打包好了,不需要重新打包了。 -# 上传部署 各模块内的 dist/ 文件夹到服务器上,注意修改 vite.config.ts 内 plugins.federation.remotes.xxx 的地址! -# 后期会实现集中管理 地址配置,并根据环境变量动态加载!! +**前端工作:** -``` - -## 问 & 答 - -**问: 为什么vue项目要抛弃SFC写法而尝试jsx/tsx方式来编码?** -> 答:https://juejin.cn/post/6911175470255964174 - -**问:不会 vue3 jsx 语法,怎么办?** -> 答:https://juejin.cn/post/7141674726434439176 \ No newline at end of file +详细请看 **front-end/xxx/README.md** 内的帮助文档!!! diff --git a/doc/jgt.png b/doc/jgt.png new file mode 100644 index 0000000..1b1a306 Binary files /dev/null and b/doc/jgt.png differ diff --git a/doc/思路整理.md b/doc/思路整理.md new file mode 100644 index 0000000..cf6ba60 --- /dev/null +++ b/doc/思路整理.md @@ -0,0 +1,51 @@ +## 遇到的问题 + +尝试将app-product 模块进行集群部署上线的时候,我们会编写dockerfile对项目进行docker build打包 + +dockerfile 其中命令: + +```bash +RUN npx vite build --base=/app-product/ +``` + +正常流程是: + +vite build 会使用项目中的 vite.config.ts,进行前端项目的构建产生 dist 文件夹,基于nginx提供给用户访问!! + +但这时候,我们在 vite.config.ts 使用自己开发的插件 vite-plugin-nacos 将前端注册到服务中心 + +因为和服务中心链接后,插件会一直保持心跳导致无法断开,此时 `vite build` 已经 产生 dist了,但是因为心跳阻塞了docker build 的后续执行,导致项目无法打包成镜像,也就无法开展后续流程进行集群部署。 + + +## 新的改变!! + + 所有微前端都不需要进行服务注册,因为前端由浏览器访问,注册实例毫无意义,无法保持心跳,就无法检查服务的健康! + +## 新的架构 + + + + + +局域网 +所有模块之间,通过 配置发现 来获取 所依赖 远程模块 的 实际网址 + +外网 +模块通过 网关 反向代理来访问 所依赖 远程模块 + + +## 新的架构带来的新的问题 + +局域网模块 之间通过 配置发现,也会和服务注册一样,和Nacos集群保持链接,导致 vite build 无法退出。。。。 + +## 如何解决?? \ No newline at end of file diff --git a/docker/nacos-cluster/docker-compose.yml b/docker/nacos-cluster/docker-compose.yml index 5cdd0e8..16a0242 100644 --- a/docker/nacos-cluster/docker-compose.yml +++ b/docker/nacos-cluster/docker-compose.yml @@ -18,14 +18,15 @@ services: volumes: - mysql-data:/var/lib/mysql - ./mysql-schema.sql:/docker-entrypoint-initdb.d/mysql-schema.sql - command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci + command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci ports: - - "3306:3306" + - target: 3306 + published: 3306 + protocol: tcp + mode: host # 数据库通常使用 host 模式,避免路由网格开销 # 健康检查,确保数据库启动完成后再启动 Nacos healthcheck: - test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ] + test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ] interval: 5s timeout: 10s retries: 10 @@ -50,11 +51,26 @@ services: - nacos-logs:/home/nacos/logs # 暴露 Nacos 所需的端口 ports: - - "8080:8080" - - "7848:7848" - - "8848:8848" - - "9848:9848" - - "9849:9849" + - target: 8080 + published: 8080 + protocol: tcp + mode: ingress # Web 控制台使用路由网格实现负载均衡 + - target: 7848 + published: 7848 + protocol: tcp + mode: ingress # 集群通信端口 + - target: 8848 + published: 8848 + protocol: tcp + mode: ingress # 主要服务端口,使用路由网格 + - target: 9848 + published: 9848 + protocol: tcp + mode: ingress # gRPC 端口 + - target: 9849 + published: 9849 + protocol: tcp + mode: ingress # gRPC 端口 # 使用环境变量文件 environment: - MODE=cluster @@ -88,7 +104,6 @@ services: update_config: parallelism: 1 delay: 30s - # 资源限制(可选,可根据你的服务器配置调整) resources: limits: @@ -106,7 +121,10 @@ services: volumes: - ./prometheus/prometheus-cluster.yaml:/etc/prometheus/prometheus.yml ports: - - "9090:9090" + - target: 9090 + published: 9090 + protocol: tcp + mode: ingress # 监控服务使用路由网格 deploy: replicas: 1 restart_policy: @@ -116,12 +134,14 @@ services: networks: - nacos-net - # Grafana 服务 grafana: image: grafana/grafana:latest ports: - - "3000:3000" + - target: 3000 + published: 3000 + protocol: tcp + mode: ingress # Grafana 使用路由网格 deploy: # 通常 Grafana 单实例即可 replicas: 1 @@ -139,4 +159,4 @@ volumes: networks: nacos-net: - driver: overlay \ No newline at end of file + driver: overlay diff --git a/docker/nacos-cluster/nacos_config_export.zip b/docker/nacos-cluster/nacos_config_export.zip index a5e62c2..96edd87 100644 Binary files a/docker/nacos-cluster/nacos_config_export.zip and b/docker/nacos-cluster/nacos_config_export.zip differ diff --git a/docker/traefik/README.md b/docker/traefik/README.md index 33d2b0f..a6fd839 100644 --- a/docker/traefik/README.md +++ b/docker/traefik/README.md @@ -1,2 +1,10 @@ +## traefik 网关 + +部署在公网的 traefik 网关,代码放到Linux服务器,然后根据实际情况修改 `dynamic.yml` 文件, +然后在根目录执行命令即可: + +```bash docker-compose down && docker-compose up -d -docker compose down && docker compose up -d \ No newline at end of file +# 或者这个命令 +# docker compose down && docker compose up -d +``` \ No newline at end of file diff --git a/docker/traefik/dynamic.yml b/docker/traefik/dynamic.yml index 27250a5..327dfe5 100644 --- a/docker/traefik/dynamic.yml +++ b/docker/traefik/dynamic.yml @@ -1,5 +1,7 @@ http: routers: + + # 共享模块的 路由 拦截 配置 app-shared-router: rule: Host(`nacos.ddd.com`) && PathPrefix(`/app-shared`) service: app-shared-service @@ -9,8 +11,9 @@ http: tracing: true traceVerbosity: detailed entryPoints: - - web + - web + # 商品模块的 路由 拦截 配置 app-product-router: rule: Host(`nacos.ddd.com`) && PathPrefix(`/app-product`) service: app-product-service @@ -20,9 +23,9 @@ http: tracing: true traceVerbosity: detailed entryPoints: - - web + - web - # 使用域名访问前端main-app + # 使用域名访问前端 main-app 主模块 main-ddd-router: rule: Host(`main.ddd.com`) service: main-ddd-service @@ -34,7 +37,7 @@ http: entryPoints: - web - # Nacos 集群 管理后台的统一访问域名 + # Nacos 集群 管理后台的统一 访问域名 nacosui-ddd-router: rule: Host(`nacosui.ddd.com`) service: nacosui-ddd-service @@ -44,7 +47,7 @@ http: tracing: true traceVerbosity: detailed entryPoints: - - web + - web # trafik 网关 代理 内网 nacos 集群 的地址 nacos-ddd-router: @@ -56,7 +59,7 @@ http: tracing: true traceVerbosity: detailed entryPoints: - - web + - web # trafik 网关的管理后台的域名 trafikui-ddd-router: @@ -71,7 +74,7 @@ http: - web - services: + services: app-shared-service: loadBalancer: servers: @@ -80,12 +83,14 @@ http: app-product-service: loadBalancer: servers: - - url: http://192.168.31.101:1301 + - url: http://192.168.139.19:1301 + - url: http://192.168.139.120:1301 + - url: http://192.168.139.242:1301 main-ddd-service: loadBalancer: servers: - - url: http://192.168.31.101:1300 + - url: http://192.168.31.101:1300 nacosui-ddd-service: loadBalancer: diff --git a/docker/traefik/package.json b/docker/traefik/package.json index 80bd4e8..ee5cb2b 100644 --- a/docker/traefik/package.json +++ b/docker/traefik/package.json @@ -6,7 +6,7 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "axios": "^1.6.8", + "axios": "^1.12.2", "js-yaml": "^4.1.0" }, "keywords": [], diff --git a/front-end/app-product/.dockerignore b/front-end/app-product/.dockerignore new file mode 100644 index 0000000..ac4c8c6 --- /dev/null +++ b/front-end/app-product/.dockerignore @@ -0,0 +1,14 @@ +node_modules +dist +.git +.DS_Store +*.log +docker/ # 排除 docker 配置文件夹本身 +.editorconfig +.eslintrc.js +.prettierrc + +.vscode +.idea +*.swp +*.swo diff --git a/front-end/app-product/.env.development b/front-end/app-product/.env.development index 7445d77..6911310 100644 --- a/front-end/app-product/.env.development +++ b/front-end/app-product/.env.development @@ -1,7 +1,7 @@ # 请求协议 http or https(建议线上配置证书后,使用https) VITE_PREFIX=http:// -# Nacos 配置中心 ip:端口 | 域名 +# 内网 中的 Nacos 配置中心 ip:端口 | 域名 #VITE_NACOS_ADDRESS=cluster.nacos.com VITE_NACOS_ADDRESS=192.168.139.84:8848 diff --git a/front-end/app-product/.env.production b/front-end/app-product/.env.production index a0e61e6..82ba25e 100644 --- a/front-end/app-product/.env.production +++ b/front-end/app-product/.env.production @@ -1,16 +1,17 @@ # 请求协议 http or https(建议线上配置证书后,使用https) VITE_PREFIX=http:// -# Nacos 配置中心 ip:端口 | 域名 +# 内网 中的 Nacos 配置中心 ip:端口 | 域名 +#VITE_NACOS_ADDRESS=cluster.nacos.com VITE_NACOS_ADDRESS=192.168.139.84:8848 # 注册到 Nacos 的服务名称(微前端模块名称 VITE_SERVER_NAME=app-product - # 注册到 Nacos 的端口,也是前端运行的端口 VITE_SERVER_PORT=1301 + # # 说明:项目要调用哪些 微前端 模块 # 格式:VITE_MODEL_XXXX_NAME=微前端模块名称(模块 的 开发者提供) @@ -19,3 +20,4 @@ VITE_SERVER_PORT=1301 # shared 共享资源模块 VITE_MODEL_SHARED_NAME=app-shared + diff --git a/front-end/app-product/README.md b/front-end/app-product/README.md index 5d3339b..e7f99a1 100644 --- a/front-end/app-product/README.md +++ b/front-end/app-product/README.md @@ -1,10 +1,63 @@ -npm install -npm run build -npm run serve + +## app-product 商品模块(微前端模块) + +从项目中拆分出来,用于演示的微前端模块,主要实现 商品相关功能。本案例演示中提供: + +- 调用 微前端 app-shared 模块 +- 调接口,获取商品首页的数据和展示 +- 调接口,点击商品列表进入商品详情页 -构建与部署: +## 运行 -- 在构建生产环境时,先构建主模块,并将其产出(特别是 remoteEntry.js 和对应的资产文件)部署到服务器,并获取其 URL。 -- 然后,在子模块的 vite.config.ts 中,将 remotes 的 URL 更新为生产环境主模块 remoteEntry.js 的绝对 URL。 -- 最后再构建子模块。 \ No newline at end of file +下面文档分为**开发**和**上线**两部分进行说明! + +### 开发 + +```bash +# 安装依赖 +npm install + +# 开发阶段 运行 项目 +# PS:注意此命令运行的项目,【无法】被其他 微前端模块 使用,仅用于本地独立开发,独立测试 +npm run dev + + +# 启动 实时打包 & 实时预览 +# PS:注意此命令运行的项目,【可以】被其他 微前端模块 调用,可用于本地开发和微前端联合开发 +npm run dep +``` + +### 上线 + +**docker/ 文件夹说明** +- `app-product.yml` - Dcoker Swarm 集群部署配置 +- `deploy-swarm.sh` - 自动化部署脚本 +- `docker-compose.yml` - 开发阶段容器编排 +- `Dockerfile` - 打包构建前端代码为镜像 +- `nginx.conf` - 镜像内前端被访问的Nginx配置 + +前端工作: + +- 1: 编辑 前端 .env.development 和 .env.production 环境变量(只需修改一次) +- 2: 确认或编辑 docker/Dockerfile,docker/nginx.conf +- 3: 编辑 docker/deploy-swarm.sh + +还有很多细节未展开,后面再详细说,大致确认无误后。 +在前端集群的管理机上进入项目根目录,执行下面命令部署: + +```bash +# 运行自动化集群部署脚本 +./docker/deploy-swarm.sh + +# --- 其他命令 --- + +# 删除之前的部署(可选) +docker stack rm app-product + +# 查看 app-product 集群运行情况 +docker stack ps app-product + +# 持续观察服务副本数是否达到预期 +watch docker stack services app-product +``` \ No newline at end of file diff --git a/front-end/app-product/docker/Dockerfile b/front-end/app-product/docker/Dockerfile new file mode 100644 index 0000000..41d0bab --- /dev/null +++ b/front-end/app-product/docker/Dockerfile @@ -0,0 +1,21 @@ +FROM node:24-alpine AS builder +WORKDIR /app + +COPY package.json ./ + +# 直接使用 npm install 并解决依赖问题 +RUN npm install --no-audit --no-fund --legacy-peer-deps + +# 拷贝源码并构建 +COPY . . + +# 【前端修改】如果要以子路径 /app-product/ 部署,请用 base 指定前缀,同 .env中VITE_SERVER_NAME +RUN npx vite build --base=/app-product/ + +FROM nginx:alpine +# 构建产物放到 /usr/share/nginx/html/app-product +COPY --from=builder /app/dist /usr/share/nginx/html/app-product +# 覆盖 Nginx 配置,支持 SPA 子路径 +COPY docker/nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/front-end/app-product/docker/app-product.yml b/front-end/app-product/docker/app-product.yml new file mode 100644 index 0000000..8c721ef --- /dev/null +++ b/front-end/app-product/docker/app-product.yml @@ -0,0 +1,39 @@ +version: "3.8" # Docker Compose 文件版本,3.8 支持 Swarm 模式的所有功能 + +services: + app-product: + image: app-product:latest + ports: + - target: 80 # 容器内部端口 + published: 1301 # 宿主机对外暴露端口 + protocol: tcp # 协议类型 + mode: ingress # 模式:使用路由网格 + deploy: + replicas: 3 # 副本数量,在集群中运行 3 个容器实例 + placement: + max_replicas_per_node: 1 # 每个 Swarm 节点最多运行 1 个副本,确保高可用性 + restart_policy: + condition: any # 重启条件:任何情况下容器退出都重启 + delay: 5s # 重启延迟 5 秒 + max_attempts: 3 # 最大重启尝试次数 + update_config: # 滚动更新配置 + parallelism: 1 # 并行更新数量:一次只更新 1 个容器 + delay: 10s # 更新间隔:每个容器更新后等待 10 秒再更新下一个 + failure_action: rollback # 更新失败时自动回滚到上一版本 + order: start-first # 更新顺序:先启动新容器,确认健康后再停止旧容器 + rollback_config: # 回滚配置 + parallelism: 1 # 回滚时并行数量 + delay: 5s # 回滚延迟 + resources: # 资源限制 + limits: # 资源上限 + cpus: "0.50" # 最多使用 0.5 个 CPU 核心 + memory: "256M" # 最多使用 256MB 内存 + reservations: # 资源预留 + cpus: "0.25" # 预留 0.25 个 CPU 核心 + memory: "128M" # 预留 128MB 内存 + networks: + - frontend # 连接到 frontend 网络 + +networks: + frontend: # 定义 frontend 网络 + driver: overlay # 使用 overlay 网络驱动,支持跨主机通信 \ No newline at end of file diff --git a/front-end/app-product/docker/deploy-swarm.sh b/front-end/app-product/docker/deploy-swarm.sh new file mode 100755 index 0000000..6758c5a --- /dev/null +++ b/front-end/app-product/docker/deploy-swarm.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# deploy-swarm.sh + +set -e + +# 仓库用户名 +USER_NAME="bmy" +# 仓库密码 +USER_PASSWORD="lb714500." +# 仓库地址 +REGISTRY="registry.bmycode.help" +# 镜像名称 +IMAGE_NAME="${REGISTRY}/app-product" +# tag 标签 +TAG="v$(date +%Y%m%d-%H%M%S)" +# 完整路径 +FULL_IMAGE="${IMAGE_NAME}:${TAG}" +# 工作服务器列表(多个服务器) +WORKER_HOSTS=("192.168.139.120" "192.168.139.242") +WORKER_USER="root" +WORKER_PASSWORD="lb714500." + +echo "=== 1 登录私有镜像仓库 ===" +if ! echo "${USER_PASSWORD}" | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then + echo "错误: 无法登录到私有仓库 ${REGISTRY}" + exit 1 +fi + +echo "=== 2 构建 app-product 镜像 ===" +docker build \ + -f docker/Dockerfile \ + -t ${FULL_IMAGE} \ + -t ${IMAGE_NAME}:latest \ + . + +echo "=== 3 推送镜像到私有仓库 ===" +docker push ${FULL_IMAGE} +docker push ${IMAGE_NAME}:latest + +echo "=== 4 在工作服务器上拉取最新镜像 ===" +for WORKER_HOST in "${WORKER_HOSTS[@]}"; do + echo "" + echo "正在连接到工作服务器: ${WORKER_HOST}" + + if sshpass -p "${WORKER_PASSWORD}" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${WORKER_USER}@${WORKER_HOST} " + echo '在工作服务器 ${WORKER_HOST} 上登录私有仓库...' + if echo '${USER_PASSWORD}' | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then + echo '拉取最新镜像...' + docker pull ${FULL_IMAGE} + docker pull ${IMAGE_NAME}:latest + echo '镜像拉取完成' + + + echo '清理旧的 app-product 镜像...' + # 删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像 + docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \ + grep -v '${FULL_IMAGE}' | \ + grep -v '${IMAGE_NAME}:latest' | \ + grep '${IMAGE_NAME}' | \ + xargs -r docker rmi -f || true + + else + echo '错误: 无法在工作服务器上登录私有仓库' + exit 1 + fi + "; then + echo "✓ 服务器 ${WORKER_HOST} 镜像拉取成功" + else + echo "✗ 服务器 ${WORKER_HOST} 镜像拉取失败" + exit 1 + fi +done + +echo "=== 5 更新 docker-compose 文件中的镜像标签 ===" +sed "s|image: app-product:latest|image: ${FULL_IMAGE}|g" docker/app-product.yml > docker/app-product-deploy.yml + +echo "=== 6 部署到 Swarm 集群 ===" +docker stack deploy -c docker/app-product-deploy.yml app-product + +echo "=== 7 恢复原始配置文件 ===" +rm -f docker/app-product-deploy.yml + +echo "=== 8 清理本地多余镜像 ===" +# 清理本地:删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像 +echo "清理本地旧的 app-product 镜像..." +docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \ +grep -v "${FULL_IMAGE}" | \ +grep -v "${IMAGE_NAME}:latest" | \ +grep "${IMAGE_NAME}" | \ +xargs -r docker rmi -f || true + +# 清理悬空镜像 +docker image prune -f + + + +echo "=== 9 验证部署状态 ===" +docker stack ps app-product + +echo "=== 部署完成 ===" \ No newline at end of file diff --git a/front-end/app-product/docker/docker-compose.yml b/front-end/app-product/docker/docker-compose.yml new file mode 100644 index 0000000..e7a4191 --- /dev/null +++ b/front-end/app-product/docker/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3.8" + +services: + app-product: + build: + context: .. + dockerfile: docker/Dockerfile + + image: app-product:1.0.0 + container_name: app-product + ports: + - "1301:80" + restart: unless-stopped diff --git a/front-end/app-product/docker/nginx.conf b/front-end/app-product/docker/nginx.conf new file mode 100644 index 0000000..2cf8e7a --- /dev/null +++ b/front-end/app-product/docker/nginx.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name *.ddd.com; + + location /app-product/ { + alias /usr/share/nginx/html/app-product/; + try_files $uri $uri/ /app-product/index.html; + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; + add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; + } +} \ No newline at end of file diff --git a/front-end/app-product/package.json b/front-end/app-product/package.json index c357655..0fbb814 100644 --- a/front-end/app-product/package.json +++ b/front-end/app-product/package.json @@ -8,31 +8,32 @@ }, "scripts": { "dev": "vite", - "dep": "concurrently \"npm run build\" \"npm run preview\"", + "dep": "concurrently \"vite build --watch\" \"sleep 5 && npm run preview\"", "preview": "vite preview --port 1301 --strictPort", - "build": "vite build --watch", + "build": "vite build", "type-check": "vue-tsc --build" }, "dependencies": { + "less": "^4.4.1", "pinia": "^3.0.3", - "vite-plugin-nacos": "link:../vite-plugin-nacos", - "vue": "^3.5.21", + "vite-plugin-nacos": "^1.1.3", + "vue": "^3.5.22", "vue-router": "^4.5.1" }, "devDependencies": { "@element-plus/icons-vue": "^2.3.2", - "@originjs/vite-plugin-federation": "^1.4.1", "@tsconfig/node22": "^22.0.2", - "@types/node": "^22.18.6", + "@types/node": "^24.6.1", "@vitejs/plugin-vue": "^6.0.1", "@vitejs/plugin-vue-jsx": "^5.1.1", - "@vue/tsconfig": "^0.7.0", - "element-plus": "^2.11.3", + "@vue/tsconfig": "^0.8.1", + "element-plus": "^2.11.4", "npm-run-all2": "^8.0.4", "rollup-plugin-visualizer": "^6.0.3", - "typescript": "~5.8.3", - "vite": "^7.1.6", + "typescript": "~5.9.3", + "vite": "^7.1.7", + "vite-federation": "^3.4.4", "vite-plugin-vue-devtools": "^8.0.2", - "vue-tsc": "^3.0.7" + "vue-tsc": "^3.1.0" } } \ No newline at end of file diff --git a/front-end/app-product/src/App.tsx b/front-end/app-product/src/App.tsx index bda6020..8fa3b43 100644 --- a/front-end/app-product/src/App.tsx +++ b/front-end/app-product/src/App.tsx @@ -17,7 +17,7 @@ export default defineComponent({

本模块包含的功能:

diff --git a/front-end/app-product/vite.config.ts b/front-end/app-product/vite.config.ts index e2e50e3..7e36fc4 100644 --- a/front-end/app-product/vite.config.ts +++ b/front-end/app-product/vite.config.ts @@ -2,7 +2,7 @@ import { defineConfig, loadEnv } from 'vite'; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx' import vueDevTools from 'vite-plugin-vue-devtools' -import federation from '@originjs/vite-plugin-federation'; +import federation from 'vite-federation'; import { fileURLToPath, URL } from "node:url"; import { visualizer } from 'rollup-plugin-visualizer'; import { reg, init } from 'vite-plugin-nacos'; @@ -10,9 +10,13 @@ import { reg, init } from 'vite-plugin-nacos'; export default defineConfig(async ({ mode }) => { const env = loadEnv(mode, process.cwd()); const { VITE_MODEL_SHARED_URL } = await init(env) + + // console.log("VITE_MODEL_SHARED_URL: ", VITE_MODEL_SHARED_URL); + return { plugins: [ reg(), + federation({ name: env.VITE_SERVER_NAME, remotes: { diff --git a/front-end/app-shared/package-lock.json b/front-end/app-shared/package-lock.json deleted file mode 100644 index 414f4f4..0000000 --- a/front-end/app-shared/package-lock.json +++ /dev/null @@ -1,1388 +0,0 @@ -{ - "name": "app-shared", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "app-shared", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "axios": "^1.12.2" - }, - "devDependencies": { - "@originjs/vite-plugin-federation": "^1.4.1", - "typescript": "~5.8.0", - "vite": "^7.0.6" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/android-arm/-/android-arm-0.25.10.tgz", - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/android-x64/-/android-x64-0.25.10.tgz", - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@originjs/vite-plugin-federation": { - "version": "1.4.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/@originjs/vite-plugin-federation/-/vite-plugin-federation-1.4.1.tgz", - "integrity": "sha512-Uo08jW5pj1t58OUKuZNkmzcfTN2pqeVuAWCCiKf/75/oll4Efq4cHOqSE1FXMlvwZNGDziNdDyBbQ5IANem3CQ==", - "dev": true, - "license": "MulanPSL-2.0", - "dependencies": { - "estree-walker": "^3.0.2", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0", - "pnpm": ">=7.0.1" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.2.tgz", - "integrity": "sha512-uLN8NAiFVIRKX9ZQha8wy6UUs06UNSZ32xj6giK/rmMXAgKahwExvK6SsmgU5/brh4w/nSgj8e0k3c1HBQpa0A==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.2.tgz", - "integrity": "sha512-oEouqQk2/zxxj22PNcGSskya+3kV0ZKH+nQxuCCOGJ4oTXBdNTbv+f/E3c74cNLeMO1S5wVWacSws10TTSB77g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.2.tgz", - "integrity": "sha512-OZuTVTpj3CDSIxmPgGH8en/XtirV5nfljHZ3wrNwvgkT5DQLhIKAeuFSiwtbMto6oVexV0k1F1zqURPKf5rI1Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.2.tgz", - "integrity": "sha512-Wa/Wn8RFkIkr1vy1k1PB//VYhLnlnn5eaJkfTQKivirOvzu5uVd2It01ukeQstMursuz7S1bU+8WW+1UPXpa8A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.2.tgz", - "integrity": "sha512-QkzxvH3kYN9J1w7D1A+yIMdI1pPekD+pWx7G5rXgnIlQ1TVYVC6hLl7SOV9pi5q9uIDF9AuIGkuzcbF7+fAhow==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.2.tgz", - "integrity": "sha512-dkYXB0c2XAS3a3jmyDkX4Jk0m7gWLFzq1C3qUnJJ38AyxIF5G/dyS4N9B30nvFseCfgtCEdbYFhk0ChoCGxPog==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.2.tgz", - "integrity": "sha512-9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.2.tgz", - "integrity": "sha512-+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.2.tgz", - "integrity": "sha512-df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.2.tgz", - "integrity": "sha512-iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.50.2.tgz", - "integrity": "sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.2.tgz", - "integrity": "sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.2.tgz", - "integrity": "sha512-Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.2.tgz", - "integrity": "sha512-82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.2.tgz", - "integrity": "sha512-4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.2.tgz", - "integrity": "sha512-9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.2.tgz", - "integrity": "sha512-HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xvw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.2.tgz", - "integrity": "sha512-nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KYA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.2.tgz", - "integrity": "sha512-eFUvvnTYEKeTyHEijQKz81bLrUQOXKZqECeiWH6tb8eXXbZk+CXSG2aFrig2BQ/pjiVRj36zysjgILkqarS2YA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.2.tgz", - "integrity": "sha512-cBaWmXqyfRhH8zmUxK3d3sAhEWLrtMjWBRwdMMHJIXSjvjLKvv49adxiEz+FJ8AP90apSDDBx2Tyd/WylV6ikA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.2.tgz", - "integrity": "sha512-APwKy6YUhvZaEoHyM+9xqmTpviEI+9eL7LoCH+aLcvWYHJ663qG5zx7WzWZY+a9qkg5JtzcMyJ9z0WtQBMDmgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://repo.huaweicloud.com/repository/npm/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.12.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://repo.huaweicloud.com/repository/npm/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.25.10", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild/-/esbuild-0.25.10.tgz", - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.10", - "@esbuild/android-arm": "0.25.10", - "@esbuild/android-arm64": "0.25.10", - "@esbuild/android-x64": "0.25.10", - "@esbuild/darwin-arm64": "0.25.10", - "@esbuild/darwin-x64": "0.25.10", - "@esbuild/freebsd-arm64": "0.25.10", - "@esbuild/freebsd-x64": "0.25.10", - "@esbuild/linux-arm": "0.25.10", - "@esbuild/linux-arm64": "0.25.10", - "@esbuild/linux-ia32": "0.25.10", - "@esbuild/linux-loong64": "0.25.10", - "@esbuild/linux-mips64el": "0.25.10", - "@esbuild/linux-ppc64": "0.25.10", - "@esbuild/linux-riscv64": "0.25.10", - "@esbuild/linux-s390x": "0.25.10", - "@esbuild/linux-x64": "0.25.10", - "@esbuild/netbsd-arm64": "0.25.10", - "@esbuild/netbsd-x64": "0.25.10", - "@esbuild/openbsd-arm64": "0.25.10", - "@esbuild/openbsd-x64": "0.25.10", - "@esbuild/openharmony-arm64": "0.25.10", - "@esbuild/sunos-x64": "0.25.10", - "@esbuild/win32-arm64": "0.25.10", - "@esbuild/win32-ia32": "0.25.10", - "@esbuild/win32-x64": "0.25.10" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://repo.huaweicloud.com/repository/npm/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://repo.huaweicloud.com/repository/npm/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://repo.huaweicloud.com/repository/npm/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://repo.huaweicloud.com/repository/npm/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.50.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/rollup/-/rollup-4.50.2.tgz", - "integrity": "sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.50.2", - "@rollup/rollup-android-arm64": "4.50.2", - "@rollup/rollup-darwin-arm64": "4.50.2", - "@rollup/rollup-darwin-x64": "4.50.2", - "@rollup/rollup-freebsd-arm64": "4.50.2", - "@rollup/rollup-freebsd-x64": "4.50.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.50.2", - "@rollup/rollup-linux-arm-musleabihf": "4.50.2", - "@rollup/rollup-linux-arm64-gnu": "4.50.2", - "@rollup/rollup-linux-arm64-musl": "4.50.2", - "@rollup/rollup-linux-loong64-gnu": "4.50.2", - "@rollup/rollup-linux-ppc64-gnu": "4.50.2", - "@rollup/rollup-linux-riscv64-gnu": "4.50.2", - "@rollup/rollup-linux-riscv64-musl": "4.50.2", - "@rollup/rollup-linux-s390x-gnu": "4.50.2", - "@rollup/rollup-linux-x64-gnu": "4.50.2", - "@rollup/rollup-linux-x64-musl": "4.50.2", - "@rollup/rollup-openharmony-arm64": "4.50.2", - "@rollup/rollup-win32-arm64-msvc": "4.50.2", - "@rollup/rollup-win32-ia32-msvc": "4.50.2", - "@rollup/rollup-win32-x64-msvc": "4.50.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://repo.huaweicloud.com/repository/npm/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/vite": { - "version": "7.1.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/vite/-/vite-7.1.5.tgz", - "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - } - } -} diff --git a/front-end/app-shared/package.json b/front-end/app-shared/package.json index a868171..e2097df 100644 --- a/front-end/app-shared/package.json +++ b/front-end/app-shared/package.json @@ -7,24 +7,24 @@ "license": "ISC", "scripts": { "dev": "vite", - "dep": "concurrently \"npm run build\" \"npm run preview\"", + "dep": "concurrently \"vite build --watch\" \"npm run preview\"", "preview": "vite preview --port 1333 --strictPort", - "build": "vite build --watch", + "build": "vite build", "type-check": "vue-tsc --build" }, "dependencies": { "@element-plus/icons-vue": "^2.3.2", - "@originjs/vite-plugin-federation": "1.3.8", "axios": "^1.12.2", - "element-plus": "^2.11.3", + "element-plus": "^2.11.4", "vite-plugin-nacos": "link:../vite-plugin-nacos", - "vue": "^3.5.21" + "vue": "^3.5.22" }, "devDependencies": { "@vitejs/plugin-vue": "^6.0.1", "@vitejs/plugin-vue-jsx": "^5.1.1", "rollup-plugin-visualizer": "^6.0.3", - "typescript": "~5.8.3", - "vite": "^7.1.6" + "typescript": "~5.9.3", + "vite": "^7.1.7", + "vite-federation": "^3.4.4" } -} +} \ No newline at end of file diff --git a/front-end/app-shared/vite.config.ts b/front-end/app-shared/vite.config.ts index 9e36aa2..ee48271 100644 --- a/front-end/app-shared/vite.config.ts +++ b/front-end/app-shared/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, loadEnv, UserConfig } from 'vite' -import federation from "@originjs/vite-plugin-federation"; +import federation from "vite-federation"; // @ts-ignore import vueJsx from '@vitejs/plugin-vue-jsx' @@ -17,6 +17,7 @@ export default defineConfig(async ({ mode }): Promise => { reg(), federation({ name: env.VITE_SERVER_NAME, + transformFileTypes: ['.css', '.less'], exposes: { "./config": "./src/config/index.ts", "./infra": "./src/infra/index.ts", diff --git a/front-end/main-app/.env.production b/front-end/main-app/.env.production index 50e20f0..f20963d 100644 --- a/front-end/main-app/.env.production +++ b/front-end/main-app/.env.production @@ -1,12 +1,17 @@ # 请求协议 http or https(建议线上配置证书后,使用https) VITE_PREFIX=http:// -# Nacos 配置中心 ip:端口 | 域名 -VITE_NACOS_ADDRESS=cluster.nacos.com -#VITE_NACOS_ADDRESS=192.168.139.84:8848 +# +# Nacos 集群的地址 +# 注意: +# 1: 内网微前端模块,直接填内网Nacos IP:端口 就行 +# 2: main-app位于公网,填 网关的公网地址 +# + +# 网关地址 +VITE_NACOS_ADDRESS=nacos.ddd.com:80 +# VITE_NACOS_ADDRESS=192.168.139.84:8848 -# traefik 网关的地址 -VITE_TRAEFIK_ADDRESS=192.168.31.101 # 注册到 Nacos 的服务名称(微前端模块名称) VITE_SERVER_NAME=main-app diff --git a/front-end/main-app/package.json b/front-end/main-app/package.json index b8c5b19..0751787 100644 --- a/front-end/main-app/package.json +++ b/front-end/main-app/package.json @@ -13,20 +13,20 @@ "dependencies": { "pinia": "^3.0.3", "vite-plugin-nacos": "link:../vite-plugin-nacos", - "vue": "^3.5.21", + "vue": "^3.5.22", "vue-facing-decorator": "^4.0.1", "vue-router": "^4.5.1" }, "devDependencies": { "@element-plus/icons-vue": "^2.3.2", - "@originjs/vite-plugin-federation": "^1.4.1", - "@types/node": "^24.5.2", + "@types/node": "^24.6.1", "@vue3-oop/plugin-vue-jsx": "^1.5.1", - "element-plus": "^2.11.3", + "element-plus": "^2.11.4", "rollup-plugin-visualizer": "^6.0.3", "tslib": "^2.8.1", - "typescript": "~5.8.3", - "vite": "^7.1.6", + "typescript": "~5.9.3", + "vite": "^7.1.7", + "vite-federation": "^3.4.4", "vite-plugin-vue-devtools": "^8.0.2" } -} +} \ No newline at end of file diff --git a/front-end/main-app/vite.config.ts b/front-end/main-app/vite.config.ts index a2321b6..ca71997 100644 --- a/front-end/main-app/vite.config.ts +++ b/front-end/main-app/vite.config.ts @@ -2,7 +2,7 @@ import path from 'path' import { defineConfig, loadEnv, ConfigEnv, mergeConfig } from 'vite' import vueJsx from '@vue3-oop/plugin-vue-jsx' -import federation from '@originjs/vite-plugin-federation'; +import federation from 'vite-federation'; import { reg, init } from 'vite-plugin-nacos'; import { visualizer } from 'rollup-plugin-visualizer'; diff --git a/front-end/vite-plugin-nacos/package.json b/front-end/vite-plugin-nacos/package.json index e16391e..401baa8 100644 --- a/front-end/vite-plugin-nacos/package.json +++ b/front-end/vite-plugin-nacos/package.json @@ -1,6 +1,6 @@ { "name": "vite-plugin-nacos", - "version": "1.1.0", + "version": "1.1.3", "description": "Vite 插件,实现Nacos服务注册与发现插件,用于模块联邦", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -8,17 +8,18 @@ "dist" ], "scripts": { - "build": "tsc -w", - "prepublishOnly": "npm run build" + "build": "tsc", + "prepublishOnly": "npm run build", + "push": "npm run build && npm publish" }, "dependencies": { "chalk": "^5.6.2", "nacos": "^2.6.0" }, "devDependencies": { - "@types/node": "^24.5.2", - "typescript": "~5.8.3", - "vite": "^7.1.6" + "@types/node": "^24.6.1", + "typescript": "~5.9.3", + "vite": "^7.1.7" }, "keywords": [ "nacos", @@ -27,4 +28,4 @@ ], "author": "", "license": "MIT" -} +} \ No newline at end of file diff --git a/front-end/vite-plugin-nacos/src/index.ts b/front-end/vite-plugin-nacos/src/index.ts index 19c00b1..dae0233 100644 --- a/front-end/vite-plugin-nacos/src/index.ts +++ b/front-end/vite-plugin-nacos/src/index.ts @@ -1,56 +1,96 @@ // 从插件实现文件导入 export * from './vite-plugin-nacos'; export * from './utils'; -import { log } from 'console'; import { nacosServiceManage } from './nacosServiceManage'; import { mergeConfig } from 'vite'; export const init = async (env: Record) => { - const nacos = await nacosServiceManage.create({ - serverList: env.VITE_NACOS_ADDRESS, - serviceName: env.VITE_SERVER_NAME, - port: Number(env.VITE_SERVER_PORT) - }); + const serverList = env.VITE_NACOS_ADDRESS; + const serviceName = env.VITE_SERVER_NAME; + const port = Number(env.VITE_SERVER_PORT); - if (env.VITE_SERVER_NAME === "main-app") { - log("不需要服务发现,进行配置发现...") - - const baseUrl = await nacos.getConfig("baseUrl", "DEFAULT_GROUP") - const baseUrlConfig = baseUrl ? JSON.parse(baseUrl) : {}; - baseUrlConfig.httpTimeOut = await nacos.getConfig("httpTimeOut", "DEFAULT_GROUP") - - // 将新配置处理一下,需要 JSON.stringify - const customizeEnv: Record> = { define: {} }; - Object.keys(baseUrlConfig).forEach(key => { - customizeEnv.define[`import.meta.env.VITE_${key.toUpperCase()}`] = JSON.stringify(baseUrlConfig[key]); - }); - - // 将老配置处理一下,需要 JSON.stringify - const existingDefine: Record> = { define: {} } - Object.keys(env).forEach(key => { - existingDefine.define[`import.meta.env.${key}`] = JSON.stringify(env[key]) - }) - - return mergeConfig(existingDefine, customizeEnv) - - } else { - log("进行服务发现,获取依赖模块的地址...") - let modelName = [] - for (const key in env) { - if (key.includes("VITE_MODEL_")) modelName.push(env[key]) - } - - const modelUrl: Record = {} - - if (modelName.length !== 0) { - for (const val of modelName) modelUrl[`VITE_MODEL_${val.replace("app-", "").toUpperCase()}_URL`] = await nacos.find(val) - } - - log("modelUrl: ", modelUrl) - return modelUrl + if (!serverList || !serviceName || Number.isNaN(port)) { + throw new Error('[vite-plugin-nacos] 缺少必要环境变量:VITE_NACOS_ADDRESS / VITE_SERVER_NAME / VITE_SERVER_PORT'); } + const nacos = await nacosServiceManage.create({ + serverList, + serviceName, + port + }); + + const isMain = serviceName === 'main-app'; + + if (isMain) { + console.log('[vite-plugin-nacos] 不需要服务发现,进行配置发现...'); + + // 并发获取配置并稳健解析 + const [baseUrlRaw, httpTimeOut] = await Promise.all([ + nacos.getConfig('baseUrl', 'DEFAULT_GROUP'), + nacos.getConfig('httpTimeOut', 'DEFAULT_GROUP') + ]); + + let baseUrlConfig: Record = {}; + if (baseUrlRaw) { + try { + baseUrlConfig = JSON.parse(baseUrlRaw); + } catch (e) { + console.warn('[vite-plugin-nacos] baseUrl 配置不是有效 JSON,忽略解析,使用空对象'); + baseUrlConfig = {}; + } + } + if (typeof httpTimeOut !== 'undefined' && httpTimeOut !== null) { + baseUrlConfig.httpTimeOut = httpTimeOut; + } + + // 将新配置处理成 define,需要 JSON.stringify + const customizeEnv = Object.keys(baseUrlConfig).reduce>((acc, key) => { + acc[`import.meta.env.VITE_${key.toUpperCase()}`] = JSON.stringify(baseUrlConfig[key]); + return acc; + }, {}); + + // 将现有 env 处理成 define,需要 JSON.stringify + const existingDefine = Object.keys(env).reduce>((acc, key) => { + acc[`import.meta.env.${key}`] = JSON.stringify(env[key]); + return acc; + }, {}); + + // 使用 mergeConfig 合并 define 字段 + const merged = mergeConfig({ define: existingDefine }, { define: customizeEnv }); + + await closeAllNacos(serviceName); + return merged; + } + + // 非主模块:进行服务发现 + console.log('[vite-plugin-nacos] 进行 配置发现,获取依赖模块的地址...'); + const modelNames: string[] = []; + for (const key in env) { + if (key.includes('VITE_MODEL_') && env[key]) { + modelNames.push(env[key]); + } + } + + // 去重 + const uniqueModelNames = Array.from(new Set(modelNames)); + const modelUrl: Record = {}; + if (uniqueModelNames.length > 0) { + const results = await Promise.all(uniqueModelNames.map(async (val) => { + const url = await nacos.getConfig(val, 'DEFAULT_GROUP'); + const envKey = `VITE_MODEL_${val.replace('app-', '').toUpperCase()}_URL`; + return [envKey, url] as const; + })); + for (const [k, v] of results) modelUrl[k] = v; + } -} \ No newline at end of file + console.log('[vite-plugin-nacos] modelUrl: ', modelUrl); + await closeAllNacos("other-model"); + return modelUrl; +} + +/** 手动关闭所有 Nacos 客户端(提供给外部在需要时调用) */ +export async function closeAllNacos(serviceName: string) { + await nacosServiceManage.destroyAll(); +} diff --git a/front-end/vite-plugin-nacos/src/nacosServiceManage.ts b/front-end/vite-plugin-nacos/src/nacosServiceManage.ts index 4650229..ab7551e 100644 --- a/front-end/vite-plugin-nacos/src/nacosServiceManage.ts +++ b/front-end/vite-plugin-nacos/src/nacosServiceManage.ts @@ -37,12 +37,12 @@ export class nacosServiceManage { const configKey = this.getConfigKey(option); if (this.instanceMap.has(configKey)) { - logger.log(`[nacos-federation] 已存在 ${ option.serviceName } 的Nacos实例,直接复用`); + logger.log(`[nacos-federation] 已存在 ${option.serviceName} 的Nacos实例,直接复用`); return this.instanceMap.get(configKey)!; } const instance = new nacosServiceManage(option); - await instance.initClient(); + // await instance.initClient(); await instance.initConfig(); this.instanceMap.set(configKey, instance); @@ -65,7 +65,7 @@ export class nacosServiceManage { */ private static getConfigKey(option: RegisterOptions): string { const namespace = option.namespace || 'public'; - return `${ option.serverList }-${ namespace }-${ option.serviceName }`; + return `${option.serverList}-${namespace}-${option.serviceName}`; } /** @@ -90,7 +90,7 @@ export class nacosServiceManage { async getConfig(dataId: string, group: string = "DEFAULT_GROUP") { const res = await this.configClient.getConfig(dataId, group) console.log() - console.log(`${ chalk.blue('[nacos-cluster-federation] 配置发现:') }\n ${ chalk.green('➜') } ${ chalk.green(dataId) } 的配置为: ${ chalk.green(res) }`) + console.log(`${chalk.blue('[nacos-cluster-federation] 配置发现:')}\n ${chalk.green('➜')} ${chalk.green(dataId)} 的配置为: ${chalk.green(res)}`) return res; } @@ -103,7 +103,7 @@ export class nacosServiceManage { const instances = await this.nacosClient.getAllInstances(serviceName); // console.log("instances: ", instances); if (instances.length === 0) { - throw new Error(`[nacos-federation] 未发现服务 ${ serviceName } 的实例`); + throw new Error(`[nacos-federation] 未发现服务 ${serviceName} 的实例`); } return formatServiceUrl(instances[0].ip, instances[0].port); } @@ -128,7 +128,7 @@ export class nacosServiceManage { await this.nacosClient.registerInstance(serviceName, { port, ip }) logger.log() logger.log(chalk.blue("[nacos-cluster-federation] 服务注册:")) - logger.log(` ${ chalk.green('➜') } ${ chalk.green(serviceName) } (${ formatServiceUrl(ip, port) }) 已注册到配置中心!`); + logger.log(` ${chalk.green('➜')} ${chalk.green(serviceName)} (${formatServiceUrl(ip, port)}) 已注册到配置中心!`); } /** @@ -136,16 +136,44 @@ export class nacosServiceManage { */ public async destroy() { const configKey = nacosServiceManage.getConfigKey(this.initOptions); - // 注销Nacos服务实例 - const { serviceName, port } = this.initOptions; - const ip = getLocalIP(); - // @ts-ignore - await this.nacosClient.deregisterInstance(serviceName, { ip, port }); - logger.log(`[nacos-federation] 服务 ${ serviceName } 已从Nacos注销`); + // 注销 Nacos 命名客户端(如已初始化) + try { + if (this.nacosClient) { + const { serviceName, port } = this.initOptions; + const ip = getLocalIP(); + // @ts-ignore + await this.nacosClient.deregisterInstance(serviceName, { ip, port }); + // @ts-ignore + if (typeof this.nacosClient.close === 'function') { + // @ts-ignore + await this.nacosClient.close(); + } + logger.log(`[nacos-federation] 服务 ${serviceName} 已从Nacos注销`); + } + } catch (e) { + logger.warn('[nacos-federation] deregister warn:', e); + } + + // 关闭配置客户端(如已初始化) + try { + if (this.configClient && typeof (this.configClient as any).close === 'function') { + await (this.configClient as any).close(); + } + } catch (e) { + logger.warn('[nacos-federation] configClient close warn:', e); + } // 从缓存中移除实例 nacosServiceManage.instanceMap.delete(configKey); } - + /** 销毁所有实例:用于构建结束/进程退出时清理 */ + public static async destroyAll(): Promise { + const tasks: Promise[] = []; + for (const [, instance] of nacosServiceManage.instanceMap) { + tasks.push(instance.destroy().catch(err => logger.warn('[nacos-federation] destroyAll warn:', err))); + } + await Promise.allSettled(tasks); + nacosServiceManage.instanceMap.clear(); + } } \ No newline at end of file diff --git a/front-end/vite-plugin-nacos/src/vite-plugin-nacos.ts b/front-end/vite-plugin-nacos/src/vite-plugin-nacos.ts index 21cd0aa..5c60043 100644 --- a/front-end/vite-plugin-nacos/src/vite-plugin-nacos.ts +++ b/front-end/vite-plugin-nacos/src/vite-plugin-nacos.ts @@ -1,6 +1,5 @@ import { loadEnv, Plugin, UserConfig } from 'vite'; -import { NacosConfigClient, NacosNamingClient } from 'nacos'; -import { getLocalIP, dependModel, formatServiceUrl } from './utils'; +import { getLocalIP } from './utils'; import chalk from 'chalk'; const logger = console; @@ -39,51 +38,12 @@ export function reg(options?: Partial): Plugin { strictPort: true, cors: true }, - // TODO dist 上线到服务器后,http://192.168.31.101:1301/ 会出问题 - // http(https)://前端运行的服务器所在ip/前端模块名 - base: `${env.VITE_PREFIX}${getLocalIP()}:${env.VITE_SERVER_PORT}/${baseUrl}` + // base: `${env.VITE_PREFIX}${getLocalIP()}:${env.VITE_SERVER_PORT}/${baseUrl}` + base: `/${baseUrl}` }; }, async configResolved(config) { const env = config.env; - - // const registerOptions: RegisterOptions = { - // serverList: env.VITE_NACOS_ADDRESS || options?.serverList!, - // serviceName: env.VITE_SERVER_NAME || options?.serviceName!, - // port: Number(env.VITE_SERVER_PORT || options?.port), - // namespace: options?.namespace || 'public' - // }; - // - // // 验证必要配置 - // if (!registerOptions.serverList) { - // throw new Error('[nacos-cluster-federation] 缺少Nacos服务列表配置,请设置VITE_NACOS_ADDRESS环境变量或插件选项'); - // } - // - // if (!registerOptions.serviceName) { - // throw new Error('[nacos-cluster-federation] 缺少服务名称配置,请设置VITE_SERVER_NAME环境变量或插件选项'); - // } - // if (!registerOptions.port) { - // throw new Error('[nacos-cluster-federation] 缺少服务端口配置,请设置VITE_SERVER_PORT环境变量或插件选项'); - // } - - // // 初始化Nacos实例 - // nacosInstance = await nacosServiceManage.create(registerOptions); - // - // const baseUrl = await nacosInstance.getConfig("baseUrl", "DEFAULT_GROUP") - // const baseUrlConfig = baseUrl ? JSON.parse(baseUrl) : {}; - // - // baseUrlConfig.httpTimeOut = await nacosInstance.getConfig("httpTimeOut", "DEFAULT_GROUP") - // - // - // const customizeEnv: Record = {}; - // Object.keys(baseUrlConfig).forEach(key => { - // const envKey = `import.meta.env.VITE_${ key.toUpperCase() }`; - // customizeEnv[envKey] = JSON.stringify(baseUrlConfig[key]); - // }); - // - // // @ts-ignore - // Object.assign(config.define, customizeEnv); - // Logs(env) }, async closeBundle() { // // 服务关闭时注销Nacos实例 diff --git a/front-end/vite-plugin-nacos/test.ts b/front-end/vite-plugin-nacos/test.ts deleted file mode 100644 index 77943e2..0000000 --- a/front-end/vite-plugin-nacos/test.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { nacosServiceManage } from "./src"; - -const main = async () => { - const nacos = new nacosServiceManage.create({}) -} diff --git a/package.json b/package.json index b2c6454..3360aa3 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,11 @@ "author": "", "license": "ISC", "scripts": { + "update": "pnpm -r update --latest", "init": "pnpm install", "all": "concurrently \"pnpm run build\" \"pnpm run dev:main\"", "build": "pnpm --parallel --filter app-product --filter app-shared dep", "dev:main": "pnpm --filter main-app dev", "build:main": "pnpm --filter main-app dep" } -} +} \ No newline at end of file