Triển khai micro frontend
/ 3 min read
Table of Contents
Vấn đề
Repo web-admin của bọn mình càng ngày càng phình to. Nó đã to đến mức mà pipeline thường xuyên chạy vài giờ đồng hồ. Và tần xuất timeout khi build repo càng ngày càng nhiều lên.
Đồng thời repo web-admin là repo share giữa rất nhiều team. Việc share repo giữa nhiều team dẫn tới conflict code nhiều hơn và đội core web tốn nhiều thời gian để review code hơn.
FE leader đưa ra quyết định ứng dụng micro frontend để giải quyết các vấn đề trên.
Trong bài post này mình chia sẻ về các bước để triển khai micro frontend với Vite/React/TaildwindCSS.
Triển khai
init web-admin
# init by vitenpm create vite@latest web-admin -- --template react-tscd web-admin# install dependenciesnpm install# install tailwindcss(V4)npm install tailwindcss @tailwindcss/vite# install vite-plugin-federationnpm install @originjs/vite-plugin-federation# install react-router(V7)npm install react-routerXem chi tiết init web-admin ở đây
init remote mfe-web-auth
# init by vitenpm create vite@latest mfe-web-auth -- --template react-tscd mfe-web-auth# install dependenciesnpm install# install vite-plugin-federationnpm install @originjs/vite-plugin-federation# install concurrentlynpm install -D concurrentlyUpdate package.json scripts
"dev:watch": "vite build --watch","serve": "vite preview --port=4001","dev": "concurrently \"npm run dev:watch\" \"npm run serve\""add mfe-web-auth components and exposes it
viết các components giống như đang triển khai bình thường.
Notes:
main.tsxrender null
import { StrictMode } from 'react';import { createRoot } from 'react-dom/client';
createRoot(document.getElementById('root')!).render( <StrictMode>{null}</StrictMode>);- update
vite.config.tsđể expose các components cần thiết
import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';import federation from '@originjs/vite-plugin-federation';
// https://vite.dev/config/export default defineConfig({ plugins: [ react(), federation({ name: 'mfe-web-auth', filename: 'remoteEntry.js', exposes: { './pages': './src/exposes/pages.tsx', './hooks': './src/exposes/hooks.ts', './features': './src/exposes/features.ts', }, shared: ['react', 'react-dom', 'react-router'], }), ], build: { target: 'esnext', },});Xem example triển khai mfe-web-auth ở đây
import/load remote-mfe into web-admin
- update
vite.config.tsđể khai báo remote-mfe
import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';import federation from '@originjs/vite-plugin-federation';
// https://vite.dev/config/export default defineConfig({ plugins: [ react(), federation({ name: 'web-admin', filename: 'remoteEntry.js', remotes: { 'mfe-web-auth': 'http://localhost:4001/assets/remoteEntry.js', }, shared: ['react', 'react-dom', 'react-router'], }), ], server: { port: 4000, }, build: { target: 'esnext', },});- khai báo remote types
declare module 'mfe-web-auth/pages' { export function LoginPage(): JSX.Element;}
declare module 'mfe-web-auth/features' { export function AuthProvider({ children, }: { children: React.ReactNode; }): JSX.Element;
export function ProtectedRoute({ children, permissions, }: { children: React.ReactNode; permissions: string[]; }): JSX.Element;}- import remote components/hooks vào host app
import { lazy, Suspense } from 'react';
const RemoteLoginPage = lazy(() => import('mfe-web-auth/pages').then(({ default: module }) => ({ default: module.LoginPage, })));
export const LoginPage = () => { return ( <Suspense fallback={null}> <RemoteLoginPage /> </Suspense> );};