Giter Site home page Giter Site logo

mini-micro-app's Introduction

mini-micro-app

微前端框架micro-app简单实现,参考 simple-micro-app,用来了解微前端的实现原理

核心原理

micro-app借鉴了webComponent的**,以组件化的方式加载子应用。以html作为资源入口,通过加载远程html,解析dom结构获取js、css静态资源来渲染微前端应用。微应用与主应用是运行在同一个window下,就要考虑主应用与子应用的样式隔离、js作用域的隔离、数据通信等问题。

渲染子应用

mini-micro-app的核心功能基于webComponentCustomElement进行构建。CustomElement用于创建自定义标签,并提供了渲染、卸载、属性变化等钩子。通过钩子就可以知道微应用的渲染时机。自定义标签同时也是一个容器,微应用的元素和样式的作用域都在容器中,形成了封闭的环境。

通过监听自定义标签micro-app的生命周期函数connectedCallback得知标签被渲染,加载子应用的html,并转换为dom结构。递归的提取dom中的scriptlink标签,并远程加载标签对应的静态资源内容,然后插入到dom中。最后通过自定义标签的appendChilddom插入到document中,完成子应用的渲染。

js 沙箱

js沙箱通过Proxy代理子应用的全局对象,防止应用之间的全局变量的冲突,同时记录和清空了子应用的副作用函数(通过addEventListener添加的事件),还可以向子应用注入全局变量。

当子应用实例化时,会创建应用对应的js沙箱,沙箱会创建proxy代理。通过with语法将子应用的window代理到proxy

将子应用的window代理到proxy后,子应用对window的属性访问、添加实际操作的是proxy,从而实现了js作用域的隔离,避免了全局变量的冲突。

css 隔离

样式隔离是指对子应用的linkstyle元素的css内容进行格式化处理,确保子应用的样式只作用于自身,不影响外部。

渲染过程中将link远程引入的css文件转换为了style标签,子应用中只会存在style标签,实现隔离的方式就是在style的每一条css规则前加上micro-app[name=xx]前缀。通过添加css前缀的方式让css只作用于子应用。

style元素插入到文档中,浏览器会为style创建CSSStyleSheet样式表,该样式表的cssRules属性包含了一组用于描述样式规则的CSSRule对象,通过该对象就可以对样式规则进行访问和修改。

数据通信

子应用本身是可以独立运行的,通信系统不应该对子应用侵入的太深,所以采用了发布订阅模式。micro-app是以组件化的**实现微前端的,我们在写vue或者react组件时,传递数据或注册监听都是以组件属性方式添加的,我们希望micro-app也能实现这种效果。

自定义元素无法支持对象类型的属性,只能传递字符串,例如<micro-app data={x: 1}> 会转换为 <micro-app data='[object Object]'>,想要以组件化形式进行数据通信必须让元素支持对象类型属性,为此我们需要重写micro-app原型链上setAttribute方法处理对象类型属性。

主应用通过micro-appdata属性发送数据,重写后的setAttribute方法会拦截data属性的变化,结合发布订阅将变化后的数据发送给子应用的监听。子应用通过全局注入的microApp属性注册数据变化的监听。

子应用通过全局注入的dispath向父应用传递数据,dispatch方法中则会构造一个CustomEvent自定义事件,以自定义事件的方式向主应用发送数据。父应用这边则通过监听与子应用协商好的自定义事件拿到子应用的数据。

项目结构

    ├── examples
    │   ├── vue2            // 主应用
    │   └── vue3            // 子应用
    ├── package.json
    ├── readme.md
    └── src                 // 微前端实现
        ├── app.js          // 子应用对应的微前端实例
        ├── data.js         // 数据通信
        ├── element.js      // micro-app自定义元素
        ├── index.js        // 应用入口
        ├── sandBox.js      // js沙箱
        ├── scopedcss.js    // css隔离
        ├── source.js       // 子应用静态资源加载
        └── utils.js        // 辅助函数

使用

# 分别进入examples/vue2、vue3 安装依赖
npm i

# 分别进入exapmles/vue3、vue3 启动项目
npm run serve

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.