npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@fescotech/tao

v0.2.0

Published

道-微前端中以iframe形式加载子应用

Readme

Tao - 道

Tao 是一个基于 iframe 实现的微前端集成方案,可以在主应用中以 iframe 的形式集成子应用,同时提供了与 qiankun 子应用共用的通信 api,与 qiankun 一起承载微前端的架构实现。

安装

npm i -S @fescotech/tao@latest

api 说明

目前提供包括加载子应用、通信等 4 个接口

  • loadMicroAppIframe: 加载 iframe 子应用
  • getAppMode: 获取 app 当前运行模式
  • initIframeBridge: 初始化 iframe 通信 bridge
  • callMasterApi: 子应用通过该接口调用主应用暴露的 api

loadMicroAppIframe(app)

手动加载/卸载 iframe 子应用

参数

  • app - object - 必选,微应用的基础信息

    • name - string - 必选,微应用的名称,确保在应用间唯一
    • entry - string - 必选,微应用的入口地址, 如 //localhost:8080
    • container - string - 必选,微应用的容器节点选择器,如 #iframe-container
    • props - object - 可选,初始化时传递给微应用的数据

返回值

微应用的实例,实例包含以下属性/接口,可根据实际情况在合适时机调用

  • 挂载应用 - mount(): Promise
  • 卸载应用 - unmount(): Promise
  • 应用启动结果 - bootstrapPromise: Promise
  • 应用挂载结果 - mountPromise: Promise
  • 应用卸载结果 - unmountPromise: Promise

用法/示例

以 react 主应用中加载一个 iframe 子应用为例

import { loadMicroAppIframe } from "@fescotech/tao";
import React from "react";

class App extends React.Component {
  microApp = null;

  componentDidMount() {
    this.microApp = loadMicroAppIframe({
      name: "app1",
      entry: "//localhost:8080",
      container: "#iframe-container",
      props: {
        message: "hello",
      },
    });
  }

  componentWillUnmount() {
    this.microApp.unmount();
  }

  render() {
    return <div id="iframe-container"></div>;
  }
}

getAppMode()

获取应用当前运行模式

返回值

应用当前运行模式 - string

  • __independent__: 独立运行
  • __iframe_micro_app__: 微前端 iframe 子应用模式
  • __qiankun_micro_app__: 微前端-乾坤子应用模式

用法/示例

import { getAppMode } from "@fescotech/tao";

const appMode = getAppMode();

initIframeBridge(appName)

初始化 iframe 通信 bridge,使用 postMessage 在 iframe 之间实现跨域通信

仅在子应用以 iframe 方式集成时需要初始化该 iframe 通信 bridge

参数

  • appName - string - 可选,子应用初始化时传入子应用名称,主应用初始化时无需传参

返回值

iframe 通信 bridge 实例,实例包含 send 和 extends 两个接口,在一个 iframe 中通过 extends 注册接口,然后在其他 iframe 中就可以通过 send 调用对应接口,进行消息互通。

  • 发送消息 - send(targetName,method,data,callback,type): Function

    • targetName - string - 必选,目标窗口名称
    • method - string - 必选,接口名称
    • data - object - 必选,消息数据
    • callback - function - 可选,消息回调
    • type - string - 可选,消息类型
  • 注册接口 - extends(name,func): Function

    • name - string - 必选, 接口名称
    • func - function - 必选,接口函数

用法/示例

比如,主应用初始化 call_master_api 接口,以供子应用调用

IframeBridgeInstance.extends("call_master_api",function (data) {
  console.log("调用主应用接口:",data);
  const method = data.method;
  const params = data.params;
  const result = window.__FESCOIE_TAO_MASTER_APIS__[method](params);
  console.log(
    `调用主应用__FESCOIE_TAO_MASTER_APIS__.${method},参数params:[${JSON.stringify(
      params
    )}],返回结果: `,
    result
  );
  return result;
});

然后在 iframe 子应用中同样初始化 iframe 通信 bridge 后,调用已在主应用注册的 call_master_api 方法

IframeBridgeInstance.send(
  "master",
  "call_master_api",
  { method: api,params },
  (data) => {
    console.log(data);
  }
);

callMasterApi(api,params)

调用主应用暴露的 api 从而实现子应用向主应用通信。主应用提供接口集合并暴露,按照一定的约定方式供子应用调用,屏蔽 iframe 子应用和 qiankun 子应用的通信差异。

参数

  • api - sting - 必选,调用 api 名称,必须已经在主应用的 window.FESCOIE_TAO_MASTER_APIS 中暴露出来
  • params - object - 可选,调用 api 的参数

返回值

接口调用返回值 - promise

用法/示例

1. 主应用定义接口集合并调用@fescotech/tao 中的 initMasterApis 进行初始化
// 主应用 main.js
import { message } from "antd";
import { initMasterApis } from "@fescotech/tao";

// 主应用暴露给子应用的api集合
const masterApi = {
  // 获取用户信息
  getUserInfo: function (params: any) {
    let userInfo;
    if (params.type === "1") {
      userInfo = {
        type: "1",
        name: "李四",
        age: 18,
      };
    } else {
      userInfo = {
        type: "0",
        name: "张三",
        age: 18,
      };
    }
    return userInfo;
  },
  // 弹出消息
  showMessage: function (params: any) {
    message.success(params.text);
  },
};

// 初始化api集合
initMasterApis(masterApi);
2.子应用初始化 iframe 通信通道
  • 引入 tao 中的 initFrameBridge 并初始化
  • name 参数为包名,需与在主应用注册的应用名称一致。
  • 如果子应用确定不会以 iframe 形式接入,则可跳过此步骤
// main.js中
import { initIframeBridge } from "@fescotech/tao";
const { name } = require("../package.json");
initIframeBridge(name);

3.子应用调用主应用 api

  • iframe 子应用和 qiankun 子应用调用方式相同

  • 调用前需引入 tao 中的 callMasterApi,然后使用此接口调用主应用 api,返回 promise

以 Vue2 子应用为例

import { callMasterApi } from "@fescotech/tao";

export default {
  data() {
    return {
      userInfo: {},// 用户信息
    };
  },
  methods: {
    // 从主应用获取用户信息
    getUserInfoFromMaster() {
      callMasterApi("getUserInfo",{ type: "1" })
        .then((res) => {
          if (res.code === 0) {
            this.userInfo = res.data;
          }
        })
        .catch((error) => {
          console.log(`子应用中调用主应用接口getUserInfo error: `,error);
        });
    },
    // 主应用弹出消息
    async showMessageInMaster() {
      await ("showMessage",{ text: "消息来自子应用!" });
    },
  },
};