上手京东微前端框架micro

编程入门 行业动态 更新时间:2024-10-12 05:48:08

<a href=https://www.elefans.com/category/jswz/34/1765339.html style=上手京东微前端框架micro"/>

上手京东微前端框架micro

最近公司准备做一下项目整体架构的优化,采用微前端的架构,将项目拆分为一个基座主服务和N个子服务。
根据市场的反馈准备入手京东的微前端框架micro-app,所以让我调研了一下,目前体验还不错。

微前端

首先介绍一下什么是微前端。
微前端的概念是由ThoughtWorks在2016年提出的,它借鉴了微服务的架构理念,核心在于将一个庞大的前端应用拆分成多个独立灵活的小型应用,每个应用都可以独立开发、独立运行、独立部署,再将这些小型应用融合为一个完整的应用,或者将原本运行已久、没有关联的几个应用融合为一个应用。微前端既可以将多个项目融合为一,又可以减少项目之间的耦合,提升项目扩展性,相比一整块的前端仓库,微前端架构下的前端仓库倾向于更小更灵活。
它主要解决了两个问题:

  • 1、随着项目迭代应用越来越庞大,难以维护。
  • 2、跨团队或跨部门协作开发项目导致效率低下的问题。

micro-app和其它微前端框架的区别

micro-app之前,业内已经有一些开源的微前端框架,比较流行的有2个:single-spaqiankun

single-spa是通过监听url change事件,在路由变化时匹配到渲染的子应用并进行渲染,这个思路也是目前实现微前端的主流方式。同时single-spa要求子应用修改渲染逻辑并暴露出三个方法:bootstrapmountunmount,分别对应初始化、渲染和卸载,这也导致子应用需要对入口文件进行修改。因为qiankun是基于single-spa进行封装的,所以这些特点也被qiankui继承下来,并且需要对webpack配置进行一些修改。

micro-app并没有沿袭single-spa的思路,而是借鉴了WebComponent的思想,通过CustomElement结合自定义的ShadowDom,将微前端封装成一个类WebComponent组件,从而实现微前端的组件化渲染。并且由于自定义ShadowDom的隔离特性,micro-app不需要像single-spaqiankun一样要求子应用修改渲染逻辑并暴露出方法,也不需要修改webpack配置,是目前市面上接入微前端成本最低的方案。


所以综上所述micro-app的优势如下:

  1. 使用简单
    将所有功能都封装到一个类WebComponent组件内,从而实现在基座应用中嵌入一行代码即可渲染一个微前端应用。
    同时micro-app还提供了js沙箱、样式隔离、元素隔离、预加载、数据通信、静态资源补全等一系列完善的功能。
  2. 零依赖
    micro-app没有任何依赖,这赋予它小巧的体积和更高的拓展行。
  3. 兼容所有框架
    为了保证各个业务之间独立开发、独立部署的能力,micro-app做了诸多兼容,在任何技术框架中都可以正常运行。

上手实战

了解完以上内容之后,就可以着手实战一下了,实测非常简单。

因为micro-app对主服务和子服务的技术栈没有任何要求,所以,我们新建三个项目,my-app(React)my-app1(React)my-app2(Vue)

my-app是整体项目的主服务,也就是基座,my-app1my-app2都是平级的子服务。

因为是写demo,所以ReactVue项目都基于其框架提供的脚手架create-react-appvue-cli来构建,不基于脚手架的话用webpack自己构建也没有任何问题。

首先我们先建立一个干净的空文件夹,名字为micro-app-demo,通过VSCode进入这个目录。

主服务my-app的构建

通过脚手架create-react-app创建一个React项目,并启动

npx create-react-app my-app
cd my-app
npm start


启动成功,可以看到主服务地址http://localhost:3000
然后安装一下micro-app

npm i @micro-zoe/micro-app --save

下载完成之后,进入项目的入口文件,create-react-app创建的项目默认的入口文件是index.js

import microApp from '@micro-zoe/micro-app';microApp.start();

index.js完整代码。

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import microApp from '@micro-zoe/micro-app';microApp.start();
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<React.StrictMode><App /></React.StrictMode>
);// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: 
reportWebVitals();

然后主服务的配置就可以先暂停了,等子服务创建了再引入。

子服务my-app1的构建

第一个子服务my-app1也通过create-react-app构建并启动。

npx create-react-app my-app1
cd my-app1
npm start

因为默认的3000端口已经被主服务my-app用了,所以会启动子服务my-app1会提示是否要换另一端口启动。

输入y。
然后就可以看到它启动成功了。

可以看到子服务1的地址是http://localhost:3001

然后重点来了,理论上,通过micro-app构建微前端项目,在服务间不通信的前提下,子服务只需要配置跨域就可以,其他都不需要弄,可以说是完全零侵入、低成本的方案。

通过create-react-app构建的项目默认就进行了跨域的相关配置。
如果不放心,或者想更改webpack的配置,可以打开控制台,输入

npm run eject

package.json中也可以看到这个指令。
输入完之后就一直yes就行了。
可能你会遇到这种报错。

因为我们在构建完项目之后进行了一些代码的更改,所以提示你要先保存这些更改,才可以eject

git指令大家应该都熟悉

git add .
git commit -m 'your commit'

然后再npm run eject就没问题了。

my-app1的项目目录内就多了一个config文件夹,打开其中的webpackDevServer.config.js,这就是脚手架帮我们封装的基础版的webpack的一些配置项,39-43行可以看到关于跨域的处理。


所以你不需要做额外处理。
然后为了在视觉上方便区分这几个服务,我们在主页面内都加一个h1标签。

my-app1/src/App.js

import logo from './logo.svg';
import './App.css';function App() {return (<div className="App"><header className="App-header"><img src={logo} className="App-logo" alt="logo" /><h1>子服务1 my-app1</h1><p>Edit <code>src/App.js</code> and save to reload.</p><aclassName="App-link"href=""target="_blank"rel="noopener noreferrer">Learn React</a></header></div>);
}export default App;

子服务my-app2的构建

子服务my-app2vue-cli构建一个Vue项目。

前提你要先全局安装过vue-cli,如果没有先运行以下指令安装vue-cli

npm install -g @vue/cli

然后确定本地有vue-cli的前提下运行以下指令。

vue create my-app2
cd my-app2
npm run serve

create的时候选一个默认配置的就可以,我选的vue2的默认配置。


可以看到子服务my-app2启动成功了,地址是http://localhost:8080

同样在主页面加入一个h1标签。

my-app2/src/App.vue

<template><div id="app"><h1>子服务2 my-app2</h1><img alt="Vue logo" src="./assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js App"/></div>
</template><script>
import HelloWorld from './components/HelloWorld.vue'export default {name: 'App',components: {HelloWorld}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>


通过vue-cli构建的Vue项目默认是没有进行跨域配置的,所以我们需要手动打开my-app2根目录下的vue.config.js文件,抄写一下my-app1中做的跨域处理,即以下代码:

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer: {headers: {'Access-Control-Allow-Origin': '*','Access-Control-Allow-Methods': '*','Access-Control-Allow-Headers': '*',},},
})

更改vue.config.js的配置后需要重新启动项目才能生效,所以记得讲my-app2这个子服务,停止再启动。

建立三个服务的关系

回到主服务my-app中。

你可以将my-app1my-app2这两个子服务想象成你封装的两个组件,可以任意的在任何地方进行调用。

只需要通过micro-app提供的组件来配置就可以,比如下方这种方式。

<micro-app name='app1' url='http://localhost:3000/' baseroute='/my-page'>
</micro-app

常规使用,只需要写三个属性,name子服务的应用名称(必传),url子服务的应用地址(必传),baseroute主服务分配给子服务的基础路由,(可选)。

我们在src目录下新建四个文件,三个作为页面,一个配置路由规则,给子服务们分配一下路由。

my-app/src/Page.jsx

import React from "react";const Page = () => {return (<div><h1>主服务 Page</h1></div>)
};export default Page;

my-app/src/Page1.jsx

import React from "react";const Page1 = () => {return (<div><micro-appname="my-app1"url="http://localhost:3001"baseroute="my-app1"></micro-app></div>)
};export default Page1;

my-app/src/Page2.jsx

import React from "react";const Page2 = () => {return (<div><micro-appname="my-app2"url="http://localhost:8080"baseroute="my-app2"></micro-app></div>)
};export default Page2;

my-app/src/route.js

因为create-react-app脚手架默认没有安装react-router,所以在主服务my-app里安一下。

npm install react-router-dom --save
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Page from './Page';
import Page1 from './Page1';
import Page2 from './Page2';export default function AppRoute() {return (<BrowserRouter><Routes><Route path='/' element={<Page />}></Route><Route path='/my-app1' element={<Page1 />}></Route><Route path='/my-app2' element={<Page2 />}></Route></Routes></BrowserRouter>)
}

my-app/src/App.js

import './App.css';
import AppRoute from './route';function App() {return (<div className="App"><AppRoute /></div>);
}export default App;

走到这里,理论上你就可以看效果了。

http://localhost:3000会访问主服务的默认页面,承载在Page.jsx内。


http://localhost:3000/my-app1会访问子服务1 my-app1的默认页面,承载在Page1.jsx内。


http://localhost:3000/my-app2会访问子服务2 my-app2的默认页面,承载在Page2.jsx内。


通过域名我们也可以看到,这三个页面都在主服务http://localhost:3000下可以访问的,是不是很神奇。

我有一个主服务,然后可以调用N个其他域名启动的子服务,集成在一起。

子服务理论上也可以独立运行,通过域名访问也可以看到这一点。



我分别访问http://localhost:3001http://localhost:8080这些子服务没有受到任何影响。

这就是micro-app这个微前端框架的强大之处。

总结

通过实践,我们可以发现micro-app这个微前端框架的,代码侵入性极低,我们只在主服务里写了几行关于微前端配置的代码,子服务在不进行通信的前提下,只需要配置跨域即可。

如此低成本就能将N个独立的子服务集成到一起,对于原服务也不会有任何影响。

甚至不限制任何技术栈,我们的主服务是React,子服务1是React,子服务2是Vue,也可以很轻松的进行集成。

更多推荐

上手京东微前端框架micro

本文发布于:2024-03-08 20:39:09,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1722257.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:上手   框架   京东   micro

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!