屎山代码拆不动?微前端来救场:一个应用变“乐高城堡”
想象你有一座巨大的乐高城堡,一开始几个人拼得很开心。后来城堡越拼越大,几百人同时在上面加砖,有人碰倒了塔楼,有人改错了城墙,整个城堡摇摇欲坠。你想拆成几个独立的小城堡,又怕它们之间连不起来。 这就是巨石前端的困境。微前端就是解决方案:把大应用拆成多个小应用(子应用),每个小应用独立开发、独立部署,最后在浏览器里组合成一个完整页面。就像乐高套装里的每个小模块,可以单独拼好,再插到一起。 如果你的项目只有三五个人,别用微前端——杀鸡不用牛刀。 微前端要解决三个问题: 不同路径对应不同子应用,比如 iframe天然隔离JS和CSS,但缺点明显:通信麻烦、SEO差、弹窗无法覆盖、全局状态不共享。 一个框架,帮你管理子应用的加载、挂载、卸载。你需要自己写如何加载子应用(比如动态script加载),以及子应用暴露的生命周期(bootstrap、mount、unmount)。 基于single-spa,内置了JS沙箱、样式隔离、HTML Entry(自动加载子应用的HTML、JS、CSS)。你只需要改几行代码,就能把一个普通应用变成微前端子应用。 不需要主应用,任意两个应用可以互相暴露和使用模块。运行时动态加载对方代码,像从冰箱里拿菜一样。 假设你有一个主应用(基座),一个子应用(React)。 在 再改webpack配置,让打包成umd格式: 搞定!子应用独立运行时正常访问,被qiankun加载时也能完美嵌入。 qiankun提供了两种沙箱: 这样子应用里修改 qiankun默认使用 如果你的项目没有明确的主应用,每个应用都可以暴露模块给其他应用,用Webpack 5的 这样两个应用独立部署,运行时动态加载对方组件,超级灵活。 微前端就像乐高积木:拆开是独立小玩具,拼起来是宏伟城堡。用得好,团队效率翻倍;用不好,调试到你怀疑人生。 如果你觉得今天的“乐高城堡”够形象,点个赞让更多人看到。明天我们将聊聊前端设计模式——单例、观察者、工厂、策略,那些让你代码更优雅的套路。我们明天见!前言
一、什么时候需要微前端?
二、微前端三大核心问题
三、常见实现方式
1. 路由分发式(Nginx反向代理)
/app1 → 应用1,/app2 → 应用2。父页面通过iframe或服务端路由组合。2. iframe:最土的“隔离神器”
3. single-spa:微前端的“老大哥”
4. qiankun:蚂蚁开箱即用的方案
5. Webpack 5 Module Federation:去中心化的“共享冰箱”
四、qiankun 实战:三步把React应用变成子应用
主应用(基座)注册子应用
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'reactApp',
entry: '//localhost:3001', // 子应用启动的地址
container: '#subapp-container',
activeRule: '/react',
},
]);
start();子应用(React)改造
src/index.js里暴露生命周期:function render(props) {
ReactDOM.render(<App />, document.getElementById('root'));
}
if (!window.__POWERED_BY_QIANKUN__) {
render(); // 独立运行时直接渲染
}
export async function bootstrap() {}
export async function mount(props) {
render(props);
}
export async function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById('root'));
}output: {
library: `${name}-[name]`,
libraryTarget: 'umd',
globalObject: 'window',
}五、JS沙箱:防止子应用污染全局
window、document都不会影响全局。六、样式隔离:你的样式别弄脏我的衣服
shadowDOM(需要子应用支持),也可以通过配置strictStyleIsolation开启。或者简单约定:子应用所有样式加namespace。七、应用间通信:传递“小纸条”
qiankun的initGlobalState。window.dispatchEvent(但注意沙箱可能隔离window)。八、常见坑点与建议
externals或Module Federation共享。history.pushState前判断是否在微前端环境,调用主应用的路由实例。loadable组件按需加载。九、Module Federation:不用主应用的“分布式”微前端
ModuleFederationPlugin。// 应用A暴露组件
new ModuleFederationPlugin({
name: 'appA',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/Button',
},
});
// 应用B消费
new ModuleFederationPlugin({
name: 'appB',
remotes: {
appA: 'appA@http://localhost:3001/remoteEntry.js',
},
});
// 在B里异步加载:import('appA/Button')十、总结:微前端不是银弹,但能救急
qiankun,复杂场景用Module Federation。