EMP 实现多版本 Mobx 模块共享

1,864 阅读1分钟

本文主要探讨使用Mobx的模块共享可行性

创建 mobx5 以及 mobx 6 项目 分别如下 :

  • react typescript mobx5 共享 demo模块 demo
  • react typescript mobx6 主入口 demo

核心问题是建立 react react-dom 的共享,emp 配置如下:

// mobx5/emp-config.js [mobx6同理]
/**
 * @type {import('@efox/emp-cli').EMPConfig}
 */
module.exports = {
  webpack({webpackEnv}) {
    return {
      devServer: {
        port: 8005,
      },
    }
  },
  async moduleFederation({webpackEnv}) {
    return {
      name: 'mobx5',
      filename: 'emp.js',
      remotes: {
        mobx6: 'mobx6@http://127.0.0.1:8006/emp.js',
      },
      exposes: {
        './Demo': 'src/Demo',
      },
      shared: {
        // * 公用同一个 react 以及 react-dom
        react: {eager: true, singleton: true, requiredVersion: '^17.0.1'},
        'react-dom': {eager: true, singleton: true, requiredVersion: '^17.0.1'},
      },
    }
  },
}

业务代码实现

mobx5/src/Demo.tsx 代码如下

import React from 'react'
import {observer} from 'mobx-react'
import CounterStore from 'src/CounterStore'
const Counter = observer(() => {
  return (
    <div>
      <h1>mobx5</h1>
      <p> mobx: 5.15.7</p>
      <p>mobx-react: 6.3.1</p>
      <Random />
      <span>Count: {CounterStore.data.count}</span>
      <button type="button" onClick={() => CounterStore.inc()}>
        +1
      </button>
    </div>
  )
})

export default Counter

mobx5/src/CounterStore.tsx 代码如下

// 使用 mobx5 的写法
import {decorate, observable, configure, action} from 'mobx'
configure({isolateGlobalState: true})
class Store {
  data = {
    count: 0,
  }
  inc() {
    this.data.count += 1
  }
}
decorate(Store, {
  data: observable,
  inc: action,
})

export default new Store()


mobx6/src/Demo.tsx 代码如下

import React from 'react'
import {observer} from 'mobx-react'
import CounterStore from 'src/CounterStore'
import Mobx from 'mobx5/Demo'
const Counter = observer(() => {
  return (
    <div>
      <h1>mobx6</h1>
      <p> mobx: 6.3.2</p>
      <p>mobx-react: 7.2.0</p>
      <span>Count: {CounterStore.data.count}</span>
      <button type="button" onClick={() => CounterStore.inc()}>
        +1
      </button>
      <Mobx />
    </div>
  )
})
const Demo = () => (
  <>
    <Counter />
  </>
)
export default Demo


mobx6/src/CounterStore.tsx 代码如下

// 使用 mobx6 的写法
import {makeAutoObservable, configure} from 'mobx'
configure({isolateGlobalState: true})
class Store {
  data = {
    count: 0,
  }

  constructor() {
    makeAutoObservable(this)
  }

  inc() {
    this.data.count += 1
  }
}

export default new Store()


演示

Mobx5 独立展示

image.png

Mobx6 连接 Mobx5 后的展示

image.png

注意项

lerna workspace 下需要支持多mobx版本并存 需要在package.json里面添加:

  "resolutions": {
    "mobx": "^6.3.2",
    "mobx-react": "^7.2.0"
  }

总结

react 开发过程中 mobx、redux 多版本的问题普片存在,目前除了 mobx 多版本案例外、也有react 多版本案例 具体可以参考 : demo 更多问题可以提出Issue