这里是一些很浅很浅的东西,大佬们不要喷我=。=。
qiankun将应用分为两种:主应用,微(子)应用
一.主应用是一个基座
主应用是一个基座,承载着各个子应用。
主应用负责各个应用之间的加载,通信和调度。
带都说,这是微服务在前端的应用,不过我没做过服务端,对微服务不是很了解,因此不敢乱说。
我只做过客户端,从客户端的角度来看,这看上去就类似于iOS的组件化。将模块解耦后,通过主工程进行加载调用。这样一来有客户端背景的同学是不是就比较好理解了。
二.主应用通过注册好的配置表,去分别加载各自子应用的资源。
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
// 子应用的名称,需要唯一
name: 'reactApp',
// 需要加载资源的地址
entry: '//localhost:3000',
// 用于替换dom的id
container: '#container',
// 激活规则
activeRule: '/app-react',
},
{
name: 'vueApp',
entry: '//localhost:8080',
container: '#container',
activeRule: '/app-vue',
},
{
name: 'angularApp',
entry: '//localhost:4200',
container: '#container',
activeRule: '/app-angular',
},
]);
// 启动 qiankun
start();
这里可以看到两步:注册,启动
换句话说,注册和启动是可以分开的。
并且本身手动加载loadMicroApp
这意味着,配置表可以从远端请求下来,进行动态修改,这就能做一些非常有意思的操作了[旺柴],比如:无星的微前端之旅(四)——qiankun线上服务代理到本地
三.entry
entry虽然写的是一个地址,但实际上
指向的应该是具体的html!
指向的应该是具体的html!
指向的应该是具体的html!
重要的话说三遍
本地开发的时候,//localhost:3000 其实就是加载public文件夹中的html了。
而配置nginx上线的时候,一般都会加上
location / {
root xxxx/xxx/;
index index.html index.htm;
}
其实指向的就是html。
因为无论是开发还是打包,spa类型项目都是加载html,html再去加载js,然后再来接管前端路由的。
为什么要强调这个?
因为可能在某些场景下,不让配置nginx。
比如,将前端产物放到springboot的静态文件夹里上线,这种时候你可能就不知道这里填啥了,这里填子应用对应的html地址就行。
container
微应用的容器节点的选择器或者 Element 实例。
其dom节点内会被插入一个dom节点,用于展示子应用的html内容。
如下图,sub-apps是主应用提供的dom节点
这意味这,如果你的某些子应用是路由不敏感的,配合activeRule完全可以同屏展示。
同时,另一方面,一些需要通过cdn引入的资源依赖,只需要在主应用引入即可,子应用不需要再引入,比如阿里的iconfont等。
如果子应用有单独访问的需求,可以在script标签添加一个ignore
属性。这样主应用访问的时候,就不会引入两次。公共依赖处理等,都可以使用这种方式,详细可以往下看五.公共依赖相关
。
activeRule
这就是子应用的激活规则。
别看大量的demo中这里填写的都是路由地址,你就认为这里写的是路由。
其实不然,它只表示激活规则,具体请看文档
这意味这,如果使用function,返回true,配合不同的container,就能同时激活两个子应用。
一般情况下,最佳实践,仍然是使用子应用的packagename作为前缀来制定路由激活规则,方便部署,也方便划分。
另外使用hash路由,需要注意,path前面需要加上#/,并且最好加上如下方法,而不要直接使用string
const getActiveRule = (hash) => (location) => location.hash.startsWith(hash);
例如,有个子应用使用hash路由,前缀为sub-login,则写法如下,以避免某些情况下路由正确却不激活子应用,文档
{
name: 'sub-login',
entry: '//xxx',
container: '#container',
activeRule: getActiveRule('#/sub-login'),
},
四.子应用的js加载后怎么执行的
请求到子应用以后,通过eval直接执行子应用代码。这个大家起一个子应用,然后打个断点,在浏览器中断点滚到最上面就能看到eval的包裹了。
五.公共依赖相关
其实在我司的项目中,并没有做对应处理,但是也了解了一下相关的。
首先说这种微前端的设计预期:既然最大的价值是技术栈无关,那么还要做公共依赖,自然是不符合原本的设计预期的。
当然,也不是不能做。
结合实现方式分析一下,主应用本身是基座,那么主应用的依赖,必定是全部会被加载的,那么公共依赖,应当是加载主应用的依赖以后,就不需要加载子应用的了。
所以如果有相同依赖的情况下,子应用只需要打包的时候剔除,在主应用加载子应用的时候,子应用其实就能读到相同依赖。
但是这时候需要考虑另一个问题:子应用独立运行访问。
考虑到上述html的加载,实际上是把子应用的html内容加载到主应用的容器节点下,那意味着,如果子应用使用script标签做cdn加载,就能在子应用独立访问时,能够获取到对应依赖。
但是这样,前面的剔除操作不就白做了吗?我们需要对cdn加载的script标签添加一个ignore
属性,这样在主应用中,就依然不会加载该资源了。
来自issuse。
沙箱和css隔离我暂时还没有用到,所以没有什么要写的。