Tạo module MFE mới
Sử dụng script
./scripts/create-module.sh <tên_module> <port>
# Ví dụ:
./scripts/create-module.sh partner 8095
Script sẽ tạo folder apps/<tên_module>/ với cấu trúc chuẩn.
Checklist chuẩn khi init module mới
1) Tạo module app
Tối thiểu có cấu trúc:
apps/<module-name>/
├── src/
│ ├── pages/
│ ├── services/
│ ├── types/
│ ├── schema/
│ ├── config/
│ │ └── baseApi.ts
│ ├── store/
│ │ └── index.ts
│ ├── routes/
│ │ └── index.tsx
│ ├── App.tsx
│ ├── RemoteApp.tsx
│ ├── bootstrap.tsx
│ └── main.tsx
├── vite.config.ts
├── package.json
├── tsconfig.json
├── Dockerfile
├── nginx.conf
└── docker-compose.yml
mẹo
Trong App.tsx của module, dùng ToastProvider từ @vppos/core/ui/react để đồng bộ UI toast giữa các module.
2) Đăng ký module vào registry
Thêm entry vào apps/container/src/config/mfeRegistry.ts:
newModule: {
name: "new-module",
label: "Module Mới",
basePath: "/new-module",
devPort: 8090,
envKey: "NEW_MODULE",
},
3) Khai báo route/menu trong container
Thêm vào apps/container/src/config/routes.config.ts:
{
path: "/new-module",
mfeKey: "newModule",
permission: { requiredModule: null },
menu: {
id: "new-module",
label: "Module Mới",
icon: IoSettingsOutline,
order: 60,
},
children: [
{
path: "/new-module/feature",
mfeKey: "newModule",
permission: { requiredModule: null },
menu: {
id: "new-module-feature",
label: "Tính năng",
icon: IoListOutline,
order: 1,
parentId: "new-module",
},
},
],
}
4) Cấu hình Vite Module Federation
apps/<module>/vite.config.ts:
federation({
name: "<module-name>",
filename: "remoteEntry.js",
exposes: {
"./App": "./src/RemoteApp.tsx",
},
shared: {
react: { singleton: true },
"react-dom": { singleton: true },
"react-router-dom": { singleton: true, requiredVersion: "*" },
"react-redux": { singleton: true },
},
dts: false,
});
5) Cập nhật MFE gateway của container
5.1 Nginx route cho module mới
Thêm block vào apps/container/nginx.conf:
location /new-module/ {
if ($http_accept ~* "text/html") {
rewrite ^ /index.html last;
}
set $upstream_new_module ${UPSTREAM_NEW_MODULE};
rewrite ^/new-module/(.*)$ /$1 break;
proxy_pass http://$upstream_new_module;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
5.2 Envsubst trong entrypoint
Thêm biến vào apps/container/docker-entrypoint.sh:
${UPSTREAM_NEW_MODULE}
5.3 Default upstream trong Dockerfile container
Thêm vào apps/container/Dockerfile:
ENV UPSTREAM_NEW_MODULE="new-module:8090"
6) Cập nhật docker compose
6.1 Compose local của module
apps/<module>/docker-compose.yml nên có:
context: .dockerfile: DockerfileNODE_ENV=productionrestart: unless-stopped- healthcheck tới
remoteEntry.js
6.2 Compose tổng FE
Thêm service vào:
docker-compose.fe.ymlinfra/docker-compose.local.yml
Và thêm vào container.depends_on nếu cần boot đồng thời.
7) Cập nhật CI/CD
Trong .gitlab-ci.yml, thêm 2 job:
build-<module>update-<module>
Với trigger changes gồm:
apps/<module>/**/*core/**/*
8) Cập nhật K8s manifest
Bắt buộc tạo cả 2 file:
infra/k8s/<module>-deployment.yamlinfra/k8s/<module>-service.yaml
Ví dụ service:
apiVersion: v1
kind: Service
metadata:
name: new-module-frontend-service
namespace: admin-vppos
spec:
selector:
app: new-module-frontend
ports:
- port: 8090
targetPort: 8090
type: ClusterIP
Và trong infra/k8s/container-deployment.yaml thêm env upstream:
- name: UPSTREAM_NEW_MODULE
value: "new-module-frontend-service.admin-vppos.svc.cluster.local:8090"
9) Verify nhanh trước khi merge
pnpm --filter @vppos/container dev
pnpm --filter @vppos/<module> dev
Kiểm tra:
- route
/new-module/...vào được - load
remoteEntry.jsthành công - không lỗi lint/build ở module và container