前端架构演进:从单体到微前端

前端架构演进:从单体到微前端

前端架构的发展历程

第一阶段:单体应用(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>
  );
};

总结

前端架构设计是一个持续演进的过程,需要根据项目规模和团队情况选择合适的方案。关键在于:

  1. 保持代码的可维护性和可扩展性
  2. 遵循单一职责和高内聚低耦合原则
  3. 合理利用设计模式和最佳实践
  4. 持续关注性能优化和用户体验

选择适合当前项目的架构方案,才能让团队高效协作,构建出优秀的产品。

相关推荐
m4Rk_8 分钟前
【论文阅读】Agent 记忆机制(87):VizoMem——把文本历史转化为可检索的视觉记忆
论文阅读·人工智能·学习·开源·github
让学习成为一种生活方式16 分钟前
啤酒花基因组与重测序--Nature Communications
人工智能·算法
2601_9499506317 分钟前
错题总是反复错?用练题簿在线刷题,把复习重点找出来
人工智能·小程序·刷题·练习·小程序推荐
lpfasd12319 分钟前
GitHub非AI开源方向调研报告
人工智能·开源·github
知几蜗牛23 分钟前
OLMo-core 3的token gerrymandering提醒:MoE路由要按时间窗验收
人工智能
熊猫钓鱼>_>26 分钟前
MetaAI深度研究研究报告
ai·meta·大模型·llm·agent·web·metaai
知几蜗牛28 分钟前
Computer Use公共预览的安全设计:应用、动作与数据三维门禁
人工智能
tuanxiang34 分钟前
实现文本AI检测免费自建方案,绕开接口调用收费坑
人工智能·计算机视觉
打工仔折腾 AI39 分钟前
飞牛OS上用Docker Compose部署ExerciseDiary运动记录并配置远程访问
运维·人工智能·后端·python·docker·容器·ai agent 实战
原子延迟42 分钟前
红色的字压成JPEG就发糊,查到最后是色度抽样
图像处理·人工智能·计算机视觉