module-federation-examples icon indicating copy to clipboard operation
module-federation-examples copied to clipboard

How can I use mf in react with 「externals」?

Open qiujie8092916 opened this issue 2 years ago • 6 comments

Hi, I am using module federation to build a application

my remote webpack conf:

// remote webpack
shared: {
  ...deps,
  react: {
    singleton: true,
    import: false,
    eager: false,
    version: '0',
    requiredVersion: "*"
  },
  'react-dom': {
    singleton: true,
    import: false,
    eager: false,
    version: '0',
    requiredVersion: "*"
  },
},

my host webpack conf:

// host webpack
shared: {
  react: {
    eager: true,
    singleton: true,
    requiredVersion: "16.14.0"
  },
  'react-dom': {
    eager: true,
    singleton: true,
    requiredVersion: "16.14.0"
  }
},
//...
externals: {
  react: 'React',
  'react-dom': 'ReactDOM'
},

And I use <script> to import react and react-dom from public/index.html

I got an error: image

what should I do? thanks for your help

qiujie8092916 avatar Dec 08 '23 08:12 qiujie8092916

You can use

https://github.com/module-federation/universe/tree/main/packages/runtime https://github.com/module-federation/universe/tree/main/packages/enhanced or use rspack

i believe runtimePlugin will be what you want to look at writing. resolveShare might be the hook for you.

You can share the library as import:false

{react: {import:false}}

then in a runtimePlugin, you can use resolveShare hook,

OR

you can use federation runtime and init({mfConfig}).

import { init, loadRemote, loadShare } from '@module-federation/runtime';

init({
  name: '@demo/main-app',
  remotes: [],
  shared: {
    react: {
      version: '17.0.0',
      scope: 'default',
      lib: () => window.React,
      shareConfig: {
        singleton: true,
        requiredVersion: '^17.0.0',
      },
    },
    'react-dom': {
      version: '17.0.0',
      scope: 'default',
      lib: () => window.ReactDOM,
      shareConfig: {
        singleton: true,
        requiredVersion: '^17.0.0',
      },
    },
  },
});

ScriptedAlchemy avatar Jan 14 '24 08:01 ScriptedAlchemy

Are there any examples of better integration with umijs?

qiujie8092916 avatar Jan 24 '24 08:01 qiujie8092916

No but I can make one, or if you have a basic host remote with the framework, send me a PR and I’ll make it do whatever you’re wanting it to do.

ScriptedAlchemy avatar Jan 24 '24 10:01 ScriptedAlchemy

No but I can make one, or if you have a basic host remote with the framework, send me a PR and I’ll make it do whatever you’re wanting it to do.

Thanks a lot. We are exploring the module federation in our project. Our projects are all based on UmiJs@3 and UmiJs@4. #3608

qiujie8092916 avatar Jan 25 '24 08:01 qiujie8092916

In addition, the umd library may be dynamic, not limited to just react and react-dom. If using runtimePlugin, can dynamic umd libraries be passed in through function parameters? Similar to:

// webpack.config.ts
const externals = {
  react: "window.React",
  "react-dom": "window.ReactDOM",
};
// ...	
runtimePlugins: [require.resolve('./runtime.js')(externals)],
// runtime.js
import type { FederationRuntimePlugin } from '@module-federation/runtime/types';

export default function (umds): FederationRuntimePlugin {
  return {
    name: 'umd-library-shared-plugin',
    resolveShare(args: any) {
      const { shareScopeMap, scope, pkgName, version } = args;

      if (!Object.keys(umds).includes(pkgName)) {
        return args;
      }

      args.resolver = function () {
      	shareScopeMap[scope][pkgName][version] = eval(umds[pkgName]);
      	return shareScopeMap[scope][pkgName][version];
      };
    },
  };
}

qiujie8092916 avatar Jan 25 '24 09:01 qiujie8092916

that should work. You can probbably set import: false for react and whatever else, not externals. Since resolveShare can resolve it to window for you, webpack doesnt need to know about it import:false is "externals" via federation sharing negotiation, which you can control with that runtime plugin

ScriptedAlchemy avatar Mar 05 '24 07:03 ScriptedAlchemy