前端微前端:别让你的应用变成巨石应用

前端微前端:别让你的应用变成巨石应用

毒舌时刻

这应用做得跟巨石似的,想改个功能都得动全身。

各位前端同行,咱们今天聊聊前端微前端。别告诉我你还在维护一个巨大的单体应用,那感觉就像在没有分区的大房子里生活——能住,但乱得要命。

为什么你需要微前端

最近看到一个项目,代码量超过 100 万行,构建时间超过 10 分钟,团队协作困难。我就想问:你是在做应用还是在做代码仓库?

反面教材

// 反面教材:单体应用 // App.jsx import React from 'react'; import Header from './components/Header'; import Sidebar from './components/Sidebar'; import Dashboard from './components/Dashboard'; import Users from './components/Users'; import Products from './components/Products'; import Orders from './components/Orders'; import Settings from './components/Settings'; function App() { return ( <div> <Header /> <div> <Sidebar /> <main> <Dashboard /> <Users /> <Products /> <Orders /> <Settings /> </main> </div> </div> ); } export default App; 

毒舌点评:这代码,就像把所有东西都塞进一个大袋子里,管它有用没用。

正确姿势

1. Module Federation

// 正确姿势:Module Federation // 1. 安装依赖 // npm install webpack@5 // 2. 配置 webpack // webpack.config.js const { ModuleFederationPlugin } = require('webpack').container; module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { dashboard: 'dashboard@http://localhost:3001/remoteEntry.js', users: 'users@http://localhost:3002/remoteEntry.js', products: 'products@http://localhost:3003/remoteEntry.js', orders: 'orders@http://localhost:3004/remoteEntry.js', settings: 'settings@http://localhost:3005/remoteEntry.js', }, shared: { react: { singleton: true, requiredVersion: '^18.2.0', }, 'react-dom': { singleton: true, requiredVersion: '^18.2.0', }, }, }), ], }; // 3. 远程应用配置 // dashboard/webpack.config.js const { ModuleFederationPlugin } = require('webpack').container; module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'dashboard', filename: 'remoteEntry.js', exposes: { './Dashboard': './src/Dashboard', }, shared: { react: { singleton: true, requiredVersion: '^18.2.0', }, 'react-dom': { singleton: true, requiredVersion: '^18.2.0', }, }, }), ], }; // 4. 主机应用 // App.jsx import React, { lazy, Suspense } from 'react'; import Header from './components/Header'; import Sidebar from './components/Sidebar'; const Dashboard = lazy(() => import('dashboard/Dashboard')); const Users = lazy(() => import('users/Users')); const Products = lazy(() => import('products/Products')); const Orders = lazy(() => import('orders/Orders')); const Settings = lazy(() => import('settings/Settings')); function App() { return ( <div> <Header /> <div> <Sidebar /> <main> <Suspense fallback={<div>加载中...</div>}> <Dashboard /> <Users /> <Products /> <Orders /> <Settings /> </Suspense> </main> </div> </div> ); } export default App; 

2. Single-SPA

// 正确姿势:Single-SPA // 1. 安装依赖 // npm install single-spa single-spa-react // 2. 注册应用 // src/registerApplications.js import { registerApplication, start } from 'single-spa'; registerApplication({ name: '@my-org/dashboard', app: () => import('@my-org/dashboard'), activeWhen: (location) => location.pathname.startsWith('/dashboard'), }); registerApplication({ name: '@my-org/users', app: () => import('@my-org/users'), activeWhen: (location) => location.pathname.startsWith('/users'), }); registerApplication({ name: '@my-org/products', app: () => import('@my-org/products'), activeWhen: (location) => location.pathname.startsWith('/products'), }); registerApplication({ name: '@my-org/orders', app: () => import('@my-org/orders'), activeWhen: (location) => location.pathname.startsWith('/orders'), }); registerApplication({ name: '@my-org/settings', app: () => import('@my-org/settings'), activeWhen: (location) => location.pathname.startsWith('/settings'), }); start(); // 3. 微应用配置 // packages/dashboard/src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import singleSpaReact from 'single-spa-react'; import Dashboard from './Dashboard'; const lifecycles = singleSpaReact({ React, ReactDOM, rootComponent: Dashboard, errorBoundary(err, info, props) { return <div>应用出错了</div>; }, }); export const bootstrap = lifecycles.bootstrap; export const mount = lifecycles.mount; export const unmount = lifecycles.unmount; 

3. Qiankun

// 正确姿势:Qiankun // 1. 安装依赖 // npm install qiankun // 2. 注册应用 // src/main.js import { registerMicroApps, start } from 'qiankun'; registerMicroApps([ { name: 'dashboard', entry: '//localhost:3001', container: '#micro-app-container', activeRule: '/dashboard', }, { name: 'users', entry: '//localhost:3002', container: '#micro-app-container', activeRule: '/users', }, { name: 'products', entry: '//localhost:3003', container: '#micro-app-container', activeRule: '/products', }, { name: 'orders', entry: '//localhost:3004', container: '#micro-app-container', activeRule: '/orders', }, { name: 'settings', entry: '//localhost:3005', container: '#micro-app-container', activeRule: '/settings', }, ]); start(); // 3. 主应用 // src/App.jsx import React from 'react'; import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'; function App() { return ( <Router> <div> <nav> <Link to="/dashboard">仪表盘</Link> <Link to="/users">用户</Link> <Link to="/products">产品</Link> <Link to="/orders">订单</Link> <Link to="/settings">设置</Link> </nav> <div></div> </div> </Router> ); } export default App; // 4. 微应用配置 // packages/dashboard/src/main.js import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; let instance = null; function render(props) { const { container } = props; instance = createApp(App); instance.use(router); instance.mount(container ? container.querySelector('#app') : '#app'); } if (!window.__POWERED_BY_QIANKUN__) { render({}); } export async function bootstrap() { console.log('dashboard bootstraped'); } export async function mount(props) { console.log('dashboard mounted', props); render(props); } export async function unmount() { console.log('dashboard unmounted'); instance.unmount(); instance = null; } 

毒舌点评:这才叫前端微前端,将应用拆分成多个独立的微应用,团队协作更高效,构建时间更短,再也不用担心巨石应用的问题了。

Read more

OpenClaw 最强技能 self-improving-agent 详解:让 AI 从错误中自主学习

OpenClaw 最强技能 self-improving-agent 详解:让 AI 从错误中自主学习

self-improving-agent 是 OpenClaw 生态中最受欢迎的技能,下载量突破 268k。它能让 AI 记住犯过的错误和解决方案,实现持续自我改进。本文将深入讲解其工作原理、安装配置、实战案例和高级用法。 1 引言 在使用 AI 助手的过程中,你是否遇到过这样的困扰: * 今天教 AI 用 sudo 解决权限问题,明天它又忘了 * 同一个 API 文档链接打不开,它下次还给你这个链接 * 重复解释同样的工作流程,效率极低 这些问题源于传统 AI 助手的无状态特性——每次对话都是全新的开始,不会从历史交互中学习。 self-improving-agent 技能正是为了解决这个问题而生的。它通过记录错误、解决方案和用户反馈,让 AI 能够持续学习和改进。 2 self-improving-agent 是什么? 2.1 官方定义 self-improving-agent

task:全网最牛的AI 白嫖教程,用 trae “套娃”安装Claude code

task:全网最牛的AI 白嫖教程,用 trae “套娃”安装Claude code

task:全网最牛的AI 白嫖教程,用 trae “套娃”安装Claude code 背景 之前一直没有动手处理 AI 编程软件的事情,一直还停留在拉取 github 然后本地安装的“刻板映像”中,而实际情况是在我拥有 AI-IDE 窗口之后,很多工具都可以互相接通,所以我从最开始下载cursor 安装,逐渐转换为cursor 只是我的一个窗口,最终目的是用 安装Claude code。 描述 认知跃迁,从“本地安装工具”的静态思维 → 转向“AI-IDE 为统一入口”的动态集成范式。本质是将 Cursor 视为「AI 编程操作系统」的 Shell,而非终点。核心转变:工具即服务,窗口即接口。 准备怎么干 摸黑开始,

【实测】OpenClaw 爆火背后:国内这几款“执行式AI”平替,谁才是真正的生产力黑马?

【实测】OpenClaw 爆火背后:国内这几款“执行式AI”平替,谁才是真正的生产力黑马?

摘要:最近 GitHub 上 OpenClaw(大龙虾)斩获 21 万 Star,正式宣告 AI 进入“执行代理”元年。但冷静下来看,高昂的 API 账单、复杂的 Docker 配置以及对国内办公软件(钉钉/飞书)的“水土不服”,让很多开发者直呼“玩不起”。本文将深度拆解国内主流 Agent 平台,并引入 RPA 领军者“实在Agent”进行破坏性实测,看看谁才是真正能落地的生产力工具。 1. 行业现状:Agent 落地为何成了“极客的玩具”? 在过去的一周里,AI 圈的口号已经从“Chat”转向了“Act”。OpenClaw 的爆火证明了用户不再满足于“

@anthropic-ai/claude-code 快速上手指南

本文重点:快速启动项目、配置 API、常用操作,让开发者立即开始实战,命令清单放在最后参考。 一、安装及配置秘钥 说明:Claude Code 依赖 git 和 npm,这里不赘述基础安装。 1.1 安装 Claude Code 升级或首次安装: npminstall-g @anthropic-ai/claude-code ⚠️ 不同版本支持的命令略有差异,最终以 /help 输出为准。 1.2 配置 API 配置文件路径: 系统路径WindowsC:\Users\用户名\.config\claude-code\config.jsonLinux/Mac~/.config/claude-code/config.json 参考:https://platform.