likes
comments
collection
share

微前端(wujie)源码解析-4.wujie-core

作者站长头像
站长
· 阅读数 5

wujie-core源码解析

前言

生命周期

当我们使用无界组件承载子应用时,会进入无界子应用的生命周期,下图展示了无界实例的生命周期。我们不需要立马弄明白所有的东西,随着后续的深入分析,它的参考价值会越来越高。

微前端(wujie)源码解析-4.wujie-core

我们在使用wujie的时候是通过组件的方式使用的,所以Vue的生命周期也是贯穿于其中的。但是,它也有一些特殊的生命周期,比如beforeLoadbeforeMountbeforeUnmountafterUnmountafterLoad,这些生命周期是wujie独有的

  • beforeLoad:子应用开始加载静态资源前执行
  • beforeMount:在子应用挂载之前执行
  • afterMount:在子应用挂载之后执行
  • beforeUnmount:在子应用卸载之前执行
  • afterUnmount:在子应用卸载之后执行

除此之外还有activateddeactivated钩子函数,这两个钩子函数在保活模式下会启用,这里我们不做过多的阐述,虽然无界提供了很多钩子函数,但对于多数场景而言,我们并不需要关心这些钩子函数。

目录结构

wujie-core的目录结构如下:

├── src
    ├── common.ts // 一些公共的方法
    ├── constant.ts // 常量
    ├── effect.ts // 一些副作用方法,比如重写了head和body的部分API
    ├── entry.ts // 和子应用入口文件相关的操作
    ├── event.ts // 事件相关
    ├── iframe.ts // iframe相关
    ├── index.ts // 入口文件
    ├── plugin.ts // 插件相关
    ├── proxy.ts // 代理相关
    ├── sandbox.ts // js沙箱相关
    ├── shadow.ts // css沙箱相关
    ├── sync.ts // 同步路由操作
    ├── template.ts // 模板相关
    ├── utils.ts // 工具函数

可以看到,wujie-core的目录命名非常友好,结构非常清晰,每个文件都有自己的职责,各个模块相互支撑,最终支撑起了整个应用, 我们分析源码的时候不需要深入分析每个文件,只要对这块有个了解就可以,在分析主流程的时候,每个文件都会涉及到。

源码分析

我们还是以官方的例子为切入点,来分析wujie的源码

<template>
  <WujieVue width="100%" height="100%" name="vue2" :url="'//localhost:7200/'" :sync="true"></WujieVue>
</template>

上面的例子是无界提供的一个路由页面,WujieVue组件承载了子应用的信息,当我们点击菜单vue2时,会渲染上面的路由页面,子应用的挂载也就是在这个时候进行的 在上一篇文章,我们知道了wujie-vue2是对wujie的封装,最终又是通过wujiestartApp来实现应用的挂载。那么接下来我们就来分析下wujiestartApp方法

export async function startApp(startOptions: startOptions): Promise<Function | void> {
    const sandbox = getWujieById(startOptions.name);
    const cacheOptions = getOptionsById(startOptions.name);
    // 合并缓存配置
    const options = mergeOptions(startOptions, cacheOptions);
    const {
        name,
        url,
        html,
        replace,
        fetch,
        props,
        attrs,
        degradeAttrs,
        fiber,
        alive,
        degrade,
        sync,
        prefix,
        el,
        loading,
        plugins,
        lifecycles,
    } = options;
    // 已经初始化过的应用,快速渲染
    if (sandbox) {
        // 沙箱存在,则进入这里的流程
        // ...do something
        // return sandbox.destroy
    }

    // 创建子应用沙箱
    const newSandbox = new WuJie({ name, url, attrs, degradeAttrs, fiber, degrade, plugins, lifecycles });
    // 执行beforeLoad钩子
    newSandbox.lifecycles?.beforeLoad?.(newSandbox.iframe.contentWindow);
    // 获取子应用的html以及外链的js和css
    const { template, getExternalScripts, getExternalStyleSheets } = await importHTML({
        url,
        html,
        opts: {
            fetch: fetch || window.fetch,
            plugins: newSandbox.plugins,
            loadError: newSandbox.lifecycles.loadError,
            fiber,
        },
    });
    
    // 处理css
    const processedHtml = await processCssLoader(newSandbox, template, getExternalStyleSheets);
    // 激活沙箱
    await newSandbox.active({ url, sync, prefix, template: processedHtml, el, props, alive, fetch, replace });
    // 启动子应用
    await newSandbox.start(getExternalScripts);
    return newSandbox.destroy;
}

上面的代码中注释了一些判断逻辑,不影响我们对主流程的分析,代码执行的逻辑也很清晰,主要做了以下4件事情:

  • 创建子应用沙箱
  • 获取子应用的html以及外链的js和css
  • 沙箱激活
  • 启动子应用,渲染子应用

这4步是wujie的主流程,这里先有个大致的了解,后续的章节我们也将围绕这4个步骤来展开分析

总结

本篇文章我们对wujie-core的源码做了一个宏观上的分析,首先我们通过分析生命周期对无界的运作机制有了更清晰的认识, 然后我们又对目录结构做了一个简单的介绍,最后我们分析了一个子应用的挂载流程,这样的话,我们对wujie-core的源码有了一个大致的了解, 从下一篇文章开始,我们将对wujie-core的沙箱、实例激活、实例启动等进行详细的分析。

如果觉得本文有帮助 记得点赞三连哦 十分感谢!

系列链接

转载自:https://juejin.cn/post/7314756012535513107
评论
请登录