前端架构演进:从单体到微前端
前端架构的发展历程
第一阶段:单体应用(Mono Repo)
├── src/
│ ├── components/
│ ├── pages/
│ ├── services/
│ ├── utils/
│ └── styles/
└── index.html
特点:
- 代码集中管理
- 部署简单
- 适合小型项目
第二阶段:组件化架构
├── src/
│ ├── components/
│ │ ├── Button/
│ │ ├── Card/
│ │ └── Modal/
│ ├── containers/
│ ├── pages/
│ └── store/
└── index.html
特点:
- 代码复用性高
- 关注点分离
- 便于团队协作
第三阶段:微前端架构
├── apps/
│ ├── shell/
│ ├── home/
│ ├── profile/
│ └── checkout/
└── packages/
└── ui-components/
特点:
- 独立开发和部署
- 技术栈无关
- 高扩展性
微前端架构模式
模式一:基座模式
javascript
// shell/src/App.js
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'home',
entry: '//localhost:8081',
container: '#container',
activeRule: '/home'
},
{
name: 'profile',
entry: '//localhost:8082',
container: '#container',
activeRule: '/profile'
}
]);
start();
模式二:路由分发模式
javascript
// router/index.js
const routes = [
{
path: '/home',
microApp: 'home'
},
{
path: '/profile',
microApp: 'profile'
}
];
模式三:构建时集成
javascript
// webpack.config.js
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'shell',
remotes: {
home: 'home@http://localhost:8081/remoteEntry.js'
}
})
]
};
状态管理方案对比
方案一:Redux
javascript
// store.js
import { createStore } from 'redux';
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};
const store = createStore(reducer, { count: 0 });
方案二:Zustand
javascript
// store.js
import create from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 }))
}));
方案三:Jotai
javascript
// store.js
import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
组件设计原则
单一职责原则
javascript
// ❌ 违反:一个组件处理多个职责
function UserProfile() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchUser().then(data => {
setUser(data);
setLoading(false);
});
}, []);
if (loading) return <Spinner />;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
// ✅ 正确:职责分离
function useUser() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchUser().then(data => {
setUser(data);
setLoading(false);
});
}, []);
return { user, loading };
}
function UserProfile() {
const { user, loading } = useUser();
if (loading) return <Spinner />;
return (
<UserCard user={user} />
);
}
可组合性
javascript
function withAuth(Component) {
return function AuthenticatedComponent(props) {
const { isLoggedIn } = useAuth();
if (!isLoggedIn) {
return <Redirect to="/login" />;
}
return <Component {...props} />;
};
}
const ProtectedPage = withAuth(MyPage);
代码组织策略
按功能组织
src/
├── features/
│ ├── auth/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── services/
│ │ └── index.js
│ └── dashboard/
│ ├── components/
│ ├── hooks/
│ └── index.js
└── shared/
├── components/
├── utils/
└── styles/
按类型组织
src/
├── components/
│ ├── Button/
│ └── Card/
├── hooks/
│ ├── useAuth.js
│ └── useFetch.js
├── services/
│ └── api.js
└── pages/
└── Home.js
性能优化策略
代码分割
javascript
const Home = React.lazy(() => import('./Home'));
const About = React.lazy(() => import('./About'));
function App() {
return (
<Suspense fallback={<Loading />}>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</Suspense>
);
}
懒加载
javascript
const Image = ({ src, alt }) => {
const [isLoaded, setIsLoaded] = useState(false);
return (
<div>
{!isLoaded && <Placeholder />}
<img
src={src}
alt={alt}
loading="lazy"
onLoad={() => setIsLoaded(true)}
/>
</div>
);
};
总结
前端架构设计是一个持续演进的过程,需要根据项目规模和团队情况选择合适的方案。关键在于:
- 保持代码的可维护性和可扩展性
- 遵循单一职责和高内聚低耦合原则
- 合理利用设计模式和最佳实践
- 持续关注性能优化和用户体验
选择适合当前项目的架构方案,才能让团队高效协作,构建出优秀的产品。