第13到22行包含要启动微型前端的代码。通常,微前端之间没有通信,并且容器与微前端之间的通信有限。
通常,它是从容器到微前端的一种方式。在这里,第34行通过ContainerID和历史,因为它的微前端待呈现如下:
ReactDOM.render(, document.getElementById(containerId));
第18行将脚本的Crondorigin值设置为空,这相当于匿名。这意味着元素的请求将使其模式设置为CORS及其凭据模式设置为相同原点。
我们在实际代码中修改了Came的示例。无论如何,这是我们使用的基础。基于此,我们可以向您展示如何将应用程序转换为微前端。
5个步骤将随机反应应用程序转换为微前端
我们为随机反应应用程序的选择是创建React应用程序。将其变成微前端需要五个步骤。
关于Facebook的皇冠珠宝应用程序的许多原则都在创建React应用程序的10个有趣的事实中描述。在本文中,我们强调应用这些原则。
第1步:修改package.json以设置端口并使用“React-App-Rewifire”
{ "name": "my-app", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.4.0", "@testing-library/user-event": "^7.2.1", "react": "^16.12.0", "react-dom": "^16.12.0", "react-scripts": "3.4.0", "react-app-rewired": "2.1.5" }, "scripts": { "start": "PORT=4000 react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
在第12行中,添加react-app-rewired作为依赖项,这允许在不弹出它的情况下自定义应用程序。
在第15行中,应用程序的启动端口已从默认端口3000更改为所选的4000 - 这避免了由于容器本身在端口3000上运行以来端口冲突。
从15号线到第17行,反应脚本由Reft-App-Rewifired替换。
使用新端口,创建React应用程序显示UI如下所示。(我们欺骗了一点。使用React-App-Rewired需要在应用程序运行之前更改步骤2。)
步骤2:使用config-overrides.js禁用代码拆分
默认情况下,启用代码拆分。应用程序分为多个可以独立加载到页面上的块。
http:// localhost:4000 / asset-manifest.json 显然显示该应用程序已被捆绑。
此加载优化会导致挂载和卸载Micro Front-Ender的问题。我们需要通过创建或编辑config-overrides.js来禁用块,如下所示:
module.exports = { webpack: (config, env) => { config.optimization.runtimeChunk = false; config.optimization.splitChunks = { cacheGroups: { default: false, }, }; return config; }, };
之后,http:// localhost:4000 / asset-manifest.json显示没有块。
如果未从Create React应用程序生成React应用程序,则可以通过修改WebPack配置来完成步骤1和步骤2。
如果使用我们的改进的MicroFrontend.js,则不必在步骤1中使用React-App-Rewifirew,并且可以完全跳过步骤2。5步减少到3.5。详细信息描述于“您不必对微前端丢失优化”中。
此保存在此回购的ChunkOptimization分支中捕获。
第3步:在SRC / index.js中进行更改以定义渲染和卸载功能
让我们来看看浏览Micro前端的SRC / index.js:
import 'react-app-polyfill/ie11'; import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { unregister } from './registerServiceWorker'; window.renderBrowse = (containerId, history) => { ReactDOM.render(, document.getElementById(containerId), ); unregister(); }; window.unmountBrowse = containerId => { ReactDOM.unmountComponentAtNode(document.getElementById(containerId)); };
window.RenderBrowse和window.unmountBrowse定义。这些方法由容器的Microfrontend.js调用。需要为Create React应用程序的SRC / index.js 定义类似的方法。
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; // render micro frontend function window.renderCreatereactapp = (containerId, history) => { ReactDOM.render(, document.getElementById(containerId) ); serviceWorker.unregister(); }; // unmount micro frontend function window.unmountCreatereactapp = containerId => { ReactDOM.unmountComponentAtNode(document.getElementById(containerId)); }; // Mount to root if it is not a micro frontend if (!document.getElementById('Createreactapp-container')) { ReactDOM.render( , document.getElementById('root')); } // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister();
从第7行到第19行,窗口.RenderCreateActApp和Window.unmountCreaterActApp正在添加。
第23线变为条件。如果它是一个独立的应用程序,它将被呈现为根元素。如果它是一个微型前端,它将通过window.rendercreateActapp呈现给ContainID。
第4步:使用src / setupproxy.js设置CORS规则
在Web浏览器中启动Micro前端时,我们获得了CORS错误:
Access to fetch at ‘http://localhost:4000/asset-manifest.json' from origin ‘http://localhost:3000' has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.
必须通过创建或编辑src / setupproxy.js来设置以下代理。
module.exports = app => { app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); next(); }); };
在进行第5步之前,我们为容器做了一些额外的工作。
在.env文件中,需要添加新的Host
React_App_CreateActApp_Host。端口4000需要匹配创建React App正在运行的Real Port。
REACT_APP_BROWSE_HOST=http://localhost:3001 REACT_APP_RESTAURANT_HOST=http://localhost:3002 REACT_APP_CREATEREACTAPP_HOST=http://localhost:4000 REACT_APP_CONTENT_HOST=http://localhost:5000
需要对.env.生产需要做类似的变化:
REACT_APP_BROWSE_HOST=https://browse.demo.microfrontends.com REACT_APP_RESTAURANT_HOST=https://order.demo.microfrontends.com REACT_APP_CREATEREACTAPP_HOST=https://createreactapp.demo.microfrontends.com REACT_APP_CONTENT_HOST=https://content.demo.microfrontends.com
在App Header.is中添加导航链接,以使UI可访问。这是可选的。
import React from 'react'; import { NavLink } from 'react-router-dom'; import './AppHeader.css'; const AppHeader = () => (); export default AppHeader; Feed me
将CreateAteActApp及其路由添加到Container的App.js中:
import React from 'react'; import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom'; import AppHeader from './AppHeader'; import MicroFrontend from './MicroFrontend'; import About from './About'; const { REACT_APP_BROWSE_HOST: browseHost, REACT_APP_RESTAURANT_HOST: restaurantHost, REACT_APP_CREATEREACTAPP_HOST: createreactappHost, } = process.env; let numRestaurants = 0; fetch(`${process.env.REACT_APP_CONTENT_HOST}/restaurants.json`) .then(res => res.json()) .then(restaurants => { numRestaurants = restaurants.length; }); const getRandomRestaurantId = () => Math.floor(Math.random() * numRestaurants) + 1; const Browse = ({ history }) => (); const Restaurant = ({ history }) => ( ); const Createreactapp = ({ history }) => ( ); const Random = () => ; const App = () => ( ); export default App;
现在让我们试着展示我们的微型前端。
内容服务器:NPM启动。
浏览Micro前端:NPM开始。
餐厅订购微型前端:NPM开始。
Create React App Micro前端:NPM开始。
容器:NPM开始。
转到localhost:3000 / createActapp来启动页面。
哎呀,React spinning 日志在哪里?
让我们重新审视http:// localhost:4000 / asset-manifest.json。Micro前端的徽标是一个单独的文件:
{ "files": { "main.js": "/static/js/bundle.js", "main.js.map": "/static/js/bundle.js.map", "index.html": "/index.html", "static/media/logo.svg": "/static/media/logo.5d5d9eef.svg" }, "entrypoints": [ "static/js/bundle.js" ] }
我们忘了抓住它!
查看此徽标SVG文件的来源,该文件被设置为/static/media/logo.5d5d9eef.svg。此文件可在Create React App(HTTPS:// localhost:4000)中使用,但不在容器中(http:// localhost:3000)。
这是我们的最后一步。
步骤5:在.env文件中配置内容主机并将其用来前缀静态内容
创建或编辑.env以设置内容主机:
REACT_APP_CONTENT_HOST=http://localhost:4000
当Micro前端使用静态内容时,它需要在HTML中的%React_App_Content_host%前缀,并在JavaScript中的
Process.env.reacect_app_content_host。
在这里,我们在src / app.js中更改了第9行:
import React from 'react'; import logo from './logo.svg'; import './App.css'; function App() { return (); } export default App;Edit
Learn Reactsrc/App.js
and save to reload.
使用此更改,徽标SVG文件以http:// localhost:4000前缀。
该应用程序现在正常工作。