今天就跟大家聊聊有關如何將隨機React應用程序轉換為微前端,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
什么是微型前端方法?微前端術語首先在2016年11月的思想技術雷達中提出來。它將微服務的概念擴展到前端開發。
該方法是通過分解應用功能來將基于瀏覽器的代碼拆分為微前端。通過制作較小且特征為中心的CodeBases,我們實現了解耦的軟件開發目標。
雖然Codebases已經解耦,但用戶體驗是連貫的。此外,每個代碼庫都可以獨立實現,升級,更新和部署。
這是微前端的天堂。無論框架和版本如何,javascript應用程序都由容器啟動。這些應用程序,遺留和新的,無縫地一起工作,并類似于一個應用程序。

在我們的示例中,我們將解決更簡單的React微型前端的情況。

在建立發起React應用程序的微型前端容器的前程工作
此容器需要具有啟動隨機反應應用程序的能力,而不知道許多細節。此外,由于微前端的概念,這層需要很薄,商業邏輯很少。
幸運的是,Cam Jackson公布了他的微觀前端工作,讓我們采用。他的工作在這個地點可以獲得:
容器:微前端演示的入口點和容器應用。
用于瀏覽餐館的微型前端:瀏覽。
從餐廳訂購食物的微型前端:餐廳訂購。
內容服務器:將靜態內容存儲微前端演示的位置。
這是微型前端工作的工作流程:
啟動內容服務器。
在特定端口啟動瀏覽和餐廳訂購應用程序。
基于URL,容器將路線到其中一個微型前端。
所選的Micro前端轉到特定端口以獲取應用程序的資產清單.JSON。從此JSON文件中,包含的main.js置于腳本標記并加載。
清單文件包含對其相應的輸出文件的所有資產文件名的映射,以便在不必解析index.html的情況下可以選擇它。該容器的核心是以下Microfrontend.js:
import React from 'react'; class MicroFrontend extends React.Component { componentDidMount() { const { name, host, document } = this.props; const scriptId = `micro-frontend-script-${name}`; if (document.getElementById(scriptId)) { this.renderMicroFrontend(); return; } fetch(`${host}/asset-manifest.json`) .then(res => res.json()) .then(manifest => { const script = document.createElement('script'); script.id = scriptId; script.crossOrigin = ''; script.src = `${host}${manifest['main.js']}`; script.onload = this.renderMicroFrontend; document.head.appendChild(script); }); } componentWillUnmount() { const { name, window } = this.props; window[`unmount${name}`](`${name}-container`); } renderMicroFrontend = () => { const { name, window, history } = this.props; window[`render${name}`](`${name}-container`, history); }; render() { return <main id={`${this.props.name}-container`} />; } } MicroFrontend.defaultProps = { document, window, }; export default MicroFrontend;第13到22行包含要啟動微型前端的代碼。通常,微前端之間沒有通信,并且容器與微前端之間的通信有限。
通常,它是從容器到微前端的一種方式。在這里,第34行通過ContainerID和歷史,因為它的微前端待呈現如下:
ReactDOM.render(<App history={history} />, document.getElementById(containerId));第18行將腳本的Crondorigin值設置為空,這相當于匿名。這意味著元素的請求將使其模式設置為CORS及其憑據模式設置為相同原點。
我們在實際代碼中修改了Came的示例。無論如何,這是我們使用的基礎?;诖?,我們可以向您展示如何將應用程序轉換為微前端。
我們為隨機反應應用程序的選擇是創建React應用程序。將其變成微前端需要五個步驟。
關于Facebook的皇冠珠寶應用程序的許多原則都在創建React應用程序的10個有趣的事實中描述。在本文中,我們強調應用這些原則。
{ "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。)

默認情況下,啟用代碼拆分。應用程序分為多個可以獨立加載到頁面上的塊。
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分支中捕獲。
讓我們來看看瀏覽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( <App history={history} />, 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( <App history={history}/>, 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(<App />, 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。
在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 = () => ( <header> <div className="center-column"> <h2> Feed me</h2> </div> <nav> <ol className="center-column"> <li> <NavLink to="/">Browse restaurants</NavLink> </li> <li> <NavLink to="/random">Surprise me</NavLink> </li> <li> <NavLink to="/createreactapp">Create React App</NavLink> </li> <li> <NavLink to="/about">About</NavLink> </li> </ol> </nav> </header> ); export default AppHeader;將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 }) => ( <MicroFrontend history={history} host={browseHost} name="Browse" /> ); const Restaurant = ({ history }) => ( <MicroFrontend history={history} host={restaurantHost} name="Restaurant" /> ); const Createreactapp = ({ history }) => ( <MicroFrontend history={history} host={createreactappHost} name="Createreactapp" /> ); const Random = () => <Redirect to={`/restaurant/${getRandomRestaurantId()}`} />; const App = () => ( <BrowserRouter> <React.Fragment> <AppHeader /> <Switch> <Route exact path="/" component={Browse} /> <Route exact path="/restaurant/:id" component={Restaurant} /> <Route exact path="/createreactapp" component={Createreactapp} /> <Route exact path="/random" render={Random} /> <Route exact path="/about" render={About} /> </Switch> </React.Fragment> </BrowserRouter> ); 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)。

這是我們的最后一步。
創建或編輯.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 ( <div className="App"> <header className="App-header"> <img src={`${process.env.REACT_APP_CONTENT_HOST}${logo}`} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); } export default App;使用此更改,徽標SVG文件以http:// localhost:4000前綴。

該應用程序現在正常工作。

看完上述內容,你們對如何將隨機React應用程序轉換為微前端有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。