1. Basic Concepts
Micro achieve a front-end architecture, it can be divided into four parts (reference: https: //alili.tech/archive/11052bf4/)
Loader: that is, the front end of the core micro-architecture, the main application for scheduling sub decide when to show which sub-application, it can be understood as a power source.
Wrapper: With loader, existing applications can be packaged so that they can use the loader, which corresponds to the power adapter.
Main applications: typically contains entries on all child use common parts - which is equivalent electrical base
Sub-applications: number of applications displayed in the main content area of application - which is equivalent to the appliance you want to use
Therefore, such a concept is: Power (loader) → power adapter (wrapper) → ️ appliance base (host application) → ️ collector (sub-applications) ️
Overall this is a process: the user access to index.html, the browser runs loader js file, go to the loader configuration file, and then register each sub-application configuration file is, first load the main application (menus, etc. ), then the route is determined by the dynamic remote loading sub-application.
2. Preliminaries
2.1 SystemJs
SystemJS provide a common way to import modules, supporting traditional modules and modules for ES6.
SystemJs There are two versions, 6.x version is used in the browser, version 0.21 is used in the browser and node environment, the use of the two different ways. (Reference: https://github.com/systemjs/systemjs )
In the micro-services mainly act as loader.
2.2 singleSpa
single-spa applications is a set of a plurality javascript together in the front-end application framework. The main act as wrappers. (Reference: https://single-spa.js.org/docs/getting-started-overview.html )
3. Micro Services Practice
3.1 to create applications
First, create a master application iframe, the main application can simply access the service from a static resource can be.
With npm init initialization, create a index.html, write a simple hello world, install dependencies npm i serve --s.
Increase the startup command in package.json the scripts in "serve": "serve -s -l 7000". After running you can see hello world.
Then create three sub-applications, I use vue-cli2.0, respectively, to create navbar applications (used to write routing), program1 (application 1), program2 (application 2).
navbar applications only put two links just fine, as:
And routing program2 program1 sub-applications are combined with the corresponding item name prefix, have increased about a sub-route as a route to switching applications, as follows:
3.2 transformation sub-applications
First, the sub-packaging applications, the respective sub-applications need to rely npm i single-spa-vue systemjs-webpack-interop, main.js modify the file entry is as follows:
Which is a single-spa-vue vue project for the wrapper, systemjs-webpack-interop npm is a community-maintained library, which can help you make webpack and systemjs work together.
In addition to output in webpack also need to increase configuration settings
3.3 Modify the main application file
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <meta name="importmap-type" content="systemjs-importmap"> <script type="systemjs-importmap"> { "imports": { "navbar": "http://localhost:8080/app.js", "program1": "http://localhost:8081/app.js", "program2": "http://localhost:8082/app.js", "single-spa": "https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js" } } </script> <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js" as="script" crossorigin="anonymous" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/system.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/amd.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-exports.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-register.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/use-default.min.js"></script> </head> <body> <script> (function(){ System.import('single-spa') .then((res)=>{ var singleSpa=res; singleSpa.registerApplication('navbar',()=>System.import('navbar'),location=>true); singleSpa.registerApplication('program1',()=>System.import('program1'),(location)=>{ return location.hash.startsWith(`#/program1`); }); singleSpa.registerApplication('program2',()=>System.import('program2'),(location)=>{ return location.hash.startsWith(`#/program2`); }); singleSpa.start(); }) })() </script> </body> </html>
4.项目整合
以上只是在开发环境中使用,接下来尝试不分别启动服务,只启用一个服务来跑项目。大体思路是使用express搭建一个服务,将子应用全部打包到项目上作为静态资源访问,入口html使用ejs模板来实现项目配置,而不再写死。
4.1 使用express生成器生成项目
4.2 修改子应用打包配置
这样子应用就全部打包到express应用中作为静态资源使用了。
4.3 增加应用配置文件
将iframe的index.html的内容复制到express的入口ejs中。增加配置文件apps.config.json和apps.config.js。
apps.config.js作用就是根据apps.config.json在静态资源文件夹下生成一份新的配置文件,将配置文件中的资源名称通过正则匹配成完整的资源路径。并且监听文件变化来更新静态资源文件夹下的配置文件。
生成的配置文件
4.4根据这个生成的配置文件去修改ejs,将项目注册过程循环出来,而不再是写死的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <meta name="importmap-type" content="systemjs-importmap"> <script type="systemjs-importmap"> { "imports": { <%for(var i=0;i<apps.length;i++){%> "<%= apps[i].name %>":"<%= apps[i].server %><%=apps[i].resourceEntryUrl %>", <%}%> "single-spa": "https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js" } } </script> <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js" as="script" crossorigin="anonymous" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/system.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/amd.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-exports.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-register.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/use-default.min.js"></script> </head> <body> <script> (function(){ Promise.all([ System.import('single-spa'), System.import('./apps.config.json') ]) .then((res)=>{ var singleSpa=res[0]; var configs=res[1].default; configs.apps.forEach( project => { if(project.resource.length>0){ Promise.all(project.resource.map(i=>{ return System.import(project.server+i) })).then(function(){ singleSpa.registerApplication(project.name,()=>System.import(project.name),(location)=>{ return project.base?true:location.hash.startsWith(`#/${project.name}`); }); }) }else{ singleSpa.registerApplication(project.name,()=>System.import(project.name),(location)=>{ return project.base?true:location.hash.startsWith(`#/${project.name}`); }); } }); singleSpa.start(); }) })() </script> </body> </html>
实际渲染出来是
4.5 优化打包配置
因为三个子项目都用到了相同的一部分依赖,可以考虑将公用的依赖不打包进去,改为在主项目主引入来提高打包效率
修改子应用的webpack.base.config.js,增加配置项
在主应用中引入依赖
4.5 增加react应用
同样是使用webpack打包,不同是包装器不一样。其他基本上是一样的思路即可。
最终demo
转自https://www.cnblogs.com/scdisplay/p/11648701.html