qiankun微前端

项目实践

主应用
主应用不限技术栈,只需要提供一个容器 DOM,然后注册微应用并 start 即可。

注册微应用并启动:

 // 项目入口页
/**
 * 主应用 **可以使用任意技术栈**
 * react create-react-app为例,可切换尝试
 */
 import render from './render/ReactRender';
**
  * Step1 初始化应用(可选)
  */
 render({ loading: true });
 
 const loader = (loading: boolean) => render({ loading });
 
 /**
 * Step2 注册子应用
 */
registerMicroApps([
    { // RegistrableApp
      name: 'reactApp', // 子应用唯一name
      entry: '//192.168.3.10:3001', // html entry
      container: '#subapp-viewport', // 子应用挂载点
      loader,
      activeRule: '/sub-app-react', // 子应用激活规则,对应子应用base
      // props - object - 可选,主应用需要传递给微应用的数据。
    },
    {
      name: 'vueApp',
      entry: '//192.168.3.10:8080',
      container: '#subapp-viewport',
      loader,
      activeRule: '/sub-app-vue',
      // props - object - 可选,主应用需要传递给微应用的数据。
    },
    {
      name: 'vue3App',
      entry: '//192.168.3.10:8081',
      container: '#subapp-viewport',
      loader,
      activeRule: '/sub-app-vue3',
      // props - object - 可选,主应用需要传递给微应用的数据。
    },
    {
      name: 'purehtml',
      entry: '//localhost:7104',
      container: '#subapp-viewport',
      loader,
      activeRule: '/purehtml',
    },
  ],
  // loader - (loading: boolean) => void - 可选,loading 状态发生变化时会调用的方法。
  {// LifeCycles 全局生命周期钩子函数
    // @ts-ignore
    beforeLoad: (app) => console.log('[LifeCycle] before load %c%s', 'color: green;', app.name),
    // @ts-ignore
    beforeMount: [(app) => console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name)],
    // @ts-ignore
    afterUnmount: (app) => console.log('[LifeCycle] before unmount %c%s', 'color: green;', app.name),
  },
);

// 数据通讯
const { onGlobalStateChange, setGlobalState } = initGlobalState({
  user: 'qiankun',
});

onGlobalStateChange((value, prev) => console.log('[onGlobalStateChange - master]:', value, prev));

setGlobalState({
  ignore: 'master',
  user: {
    name: 'master',
  },
});

/**
 * Step3 设置默认进入的子应用
 */
setDefaultMountApp('/sub-app-react');


/**
 * Step4 启动应用
 */
start({
  sandbox: {
    experimentalStyleIsolation: true
  }
}
);


//第一个微应用 mount 后需要调用的方法,比如开启一些监控或者埋点脚本。
runAfterFirstMounted(() => {
  console.log('[MainApp] first app mounted');
});

React 微应用

以 create react app 生成的 react 17.x 项目为例,搭配 react-router-dom 5.x。

1. 在 src 目录新增 public-path.js:

if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
2. 设置 history 模式路由的 base:

<BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? '/app-react' : '/'}>
// 入口文件 index.js 修改,为了避免根 id #root 与其他的 DOM 冲突,需要限制查找范围。


import './public-path';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

function render(props) {
  const { container } = props;
  ReactDOM.render(<App />, container ? container.querySelector('#root') : document.querySelector('#root'));
}
function storeTest(props) {
  props.onGlobalStateChange((value, prev) => console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev), true);
  props.setGlobalState({
    ignore: props.name,
    user: {
      name: props.name,
    },
  });
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

export async function bootstrap() {
  console.log('[react17] react app bootstraped');
}

export async function mount(props) {
  console.log('[react17] props from main framework', props);
  storeTest(props); // 应用拿到数据
  render(props);
}

export async function unmount(props) {
  const { container } = props;
  ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值