如何实现多个应用之间的资源共享?
以前,npm包形表达式的抽象和引用很多。 例如,在多个APP应用之间,当业务逻辑模块和其他可以重用时,可以提取并作为npm程序包管理和使用。 但是,这带来了以下问题。
如果需要重复发布效率低下npm包中的逻辑操作,请首先释放npm包,然后为使用该npm包的每个APP应用程序更新npm包的版本,并构建每个版本以释放它过程繁琐如果涉及更多的APP应用,就会花费更多的人力和精力。
多团队协作容易不规范包含公共模块的npm软件包意味着“人人都有”作为共享资产,但实际上谁都没有。 很快就会变成充满杂乱的风格不一致的代码,没有明确的约定和技术愿景。
这些问题使我们认识到,将前端开发规模扩展到http://www.Sina.com/http://www.Sina.com /大型复杂产品是一个重要而艰巨的挑战。
因此,2016年微前端概念应运而生。
第一章什么是微前端? 1-1微前端概念micro frontend s 3360https://micro-frontend s.org /官网定义了微前端的概念:
Techniques,strategiesandrecipesforbuildingamodernwebappwithmultipleteamsthatcanshipfeaturesindependently。
据Micro Frontends官网报道,微前端的概念由多个团队的概念扩展而来,摒弃了大的单体方式,将整个前端分解成小而简单的块,这些块为http://www.Sina.com 然而,应当理解,http://www.Sina .的微处理器是将多个同时开发的小型前端APP应用集成在一起的架构模式。
值得注意的几点:
它集成了技术、战略和方法,而不是微前端3358www.Sina.com/,可能以脚手架、辅助插件和规范约束3358www.Sina.com/的形式展示,是一个宏观框架。 这个微服务现在有独立开发、测试和部署,虽然都有优势和劣势,但是应用现在的业务场景就可以了。
微前端并行聚合所有微前端方案的设计基于实际需求。 如果多个团队统一使用react技术堆栈,微前端方案的技术堆栈之间的使用可能不要求多个团队同时使用react和vue技术堆栈,则微前端技术堆栈之间的要求可能较高。
微前端的使用场景分割了巨大的APP应用,提高了APP应用的可维护性
与历史APP应用兼容,实现增量开发
1-2微前端的优势同步更新与npm数据包方式的抽取相比,意识到可独立交付的重要性。 由于微处理器是多个子APP的聚合,在多个业务APP应用依赖于同一服务APP的功能模块的情况下,只要更新服务APP应用,其他的业务APP应用就可以立即更新,因此更新流程被缩短,更新成本
增量升级迁移是一项非常耗时且困难的任务。 例如,某管理系统使用AngularJS开发维护了3年,但随着时间的推移和团队成员的变更,无论从开发成本还是使用者的需求来看,AngularJS都已经不能满足要求。 因此,小组希望更新技术堆栈,在其他框架中实现新的需求,现有项目怎么办? 直接转移是不可能的,用新框架完全改写也不现实。
使用微前端架构可以解决问题,在保留现有项目的同时,完全使用新框架开发新需求,然后使用微前端架构集成旧项目和新项目这样可以提高产品的用户体验,使团队成员在技术上取得进步,并将产品开发成本降至最低。
当前的单页面APP应用程序架构使用组件来构建用户界面。 每次开发完APP包中的各个组件和功能或修复错误后,都需要重新构建和发布整个产品,这不仅耗时而且操作繁琐。
使用微提示体系结构后,可以将无法实现的功能模块划分为独立的APP应用程序。 此时,功能模块可以单独构建并单独释放,构建时间也非常快。 APP发布后,如果不需要更改其他内容APP,它将自动更新。 也就是说,可以频繁地进行构建和释放操作。
由于微前端框架与框架无关,因此当多个团队开发一个APP应用时,每个团队都可以使用自己擅长的技术堆栈进行开发,以实现独立团队的决策。 也就是说,可以让团队适当地决定使用哪种技术,团队合作就不会僵化。
1-3微前端落地方案
strong>自组织模式:通过约定进行互调,但会遇到处理第三方依赖等问题。基座模式:通过搭建基座、配置中心来管理子应用。如基于SIngle Spa的偏通用的乾坤方案,也有基于本身团队业务量身定制的方案。
去中心模式:脱离基座模式,每个应用之间都可以彼此分享资源。如基于Webpack 5 Module Federation实现的EMP微前端方案,可以实现多个应用彼此共享资源分享。
其中,目前值得关注是去中心模式中的EMP微前端方案,既可以实现跨技术栈调用,又可以在相同技术栈的应用间深度定制共享资源,如果刚开始调研微前端的话,可以先尝试了解一下EMP微前端方案,或许会给你带来不错的使用体验
第2章 Systemjs模块化解决方案Systemjs:https://github.com/systemjs/systemjs
在微前端架构中,微应用被打包为模块,但浏览器不支持模块化,需要使用 systemjs 实现浏览器中的模块化。
systemjs 是一个用于实现模块化的 JavaScript 库,有属于自己的模块化规范。
在开发阶段我们可以使用 ES 模块规范,然后使用 webpack 将其转换为 systemjs 支持的模块。
案例:通过 webpack 将 react 应用打包为 systemjs 模块,在通过 systemjs 在浏览器中加载模块
npm install webpack@5.17.0 webpack-cli@4.4.0 webpack-dev-server@3.11.2 html-webpack-plugin@4.5.1 @babel/core@7.12.10 @babel/cli@7.12.10 @babel/preset-env@7.12.11 @babel/preset-react@7.12.10 babel-loader@8.2.2
package.json
{ "name": "systemjs-react", "scripts": { "start": "webpack serve" }, "dependencies": { "@babel/cli": "^7.12.10", "@babel/core": "^7.12.10", "@babel/preset-env": "^7.12.11", "@babel/preset-react": "^7.12.10", "babel-loader": "^8.2.2", "html-webpack-plugin": "^4.5.1", "webpack": "^5.17.0", "webpack-cli": "^4.4.0", "webpack-dev-server": "^3.11.2" }}webpack.config.js
const path = require("path")const HtmlWebpackPlugin = require("html-webpack-plugin")module.exports = { mode: "development", entry: "./src/index.js", // 入口 output: { // 出口 // 打包目录及文件 path: path.join(__dirname, "build"), filename: "index.js", // 指定构建时所需要的库 libraryTarget: "system" }, devtool: "source-map", // 服务器运行配置 devServer: { port: 9000, // 端口 // 静态资源文件夹 contentBase: path.join(__dirname, "build"), historyApiFallback: true }, module: { rules: [ { test: /.js$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { // 对应语法转换 presets: ["@babel/preset-env", "@babel/react"] } } } ] }, plugins: [ // 插件 new HtmlWebpackPlugin({ /* 打包时,不需要自动引入JS文件(<script> 标签) */ inject: false, /* 使用微前端的方式,我们需要自己加载对应的 JS 文件 */ template: "./src/index.html" }) ], // 添加打包排除选项,微前端中需要使用公共的 React ,打包是不需要的 externals: ["react", "react-dom", "react-router-dom"]}src/index.html
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>systemjs-react</title> <!-- 按照 systemjs 模块化的方式引入React框架应用 --> <script type="systemjs-importmap"> { "imports": { "react": "https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js", "react-dom": "https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js", "react-router-dom": "https://cdn.jsdelivr.net/npm/react-router-dom@5.2.0/umd/react-router-dom.min.js" } } </script> <!-- systemjs 库 --> <script src="https://cdn.jsdelivr.net/npm/systemjs@6.8.0/dist/system.min.js"></script> </head> <body> <div id="root"></div> <script> // 按照 systemp 的方式,引入具体应用 System.import("./index.js") </script> </body></html>src/index.js
import React from "react"import ReactDom from "react-dom"import App from './App.js'ReactDom.render(<App />, document.getElementById("root"))src/App.js
import React from "react"export default function App(){ return <div>React micro for systemjs</div>}后续内容随后发出,欢迎关注