Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Federated Modules: Dynamic Remotes with synchronous imports #557

Merged

Conversation

ksrb
Copy link
Contributor

@ksrb ksrb commented Jan 6, 2021

This is part question, part PR but I thought it might make a good candidate to be merged once it works and is cleaned up, this PR is the result of issues from:

The tl;dr of these issues is to allow a remote module to be resolved at runtime, this is possible with code from webpack/webpack#11033 which this PR contains.

The aforementioned code would be utilized like so:

import { loadFromRemote } from "./loader";

const WidgetRemote = React.lazy(async () => {
  const component = await loadFromRemote({
    component: "Widget", remote: {
      url: "http://localhost:3003/remoteEntry.js",
      name: "app3",
    },
  });
  return component();
});

const App = () => (
  <Suspense fallback="Loading widget">
    <WidgetRemote />
  </Suspense>
);

However, this use case isn't ideal for code which would prefer to use synchronous imports i.e.:

import WidgetRemote from "app3/Widget";

A more realistic use case of synchronous imports would be importing a set of constants which the host module could then use to build it's own set of constants, in this case making the code asynchronous would be problematic.

The current example in this PR attempts to utilize the internal keyword mentioned by sokra to delegate the module loading to some internal logic:

new ModuleFederationPlugin({
  name: "app2",
  remotes: {
    app3: "internal ./src/loader.js"
  },
})

The result should be:
image

However, the current example is throwing the following error:
image

I did some shallow diving of webpack's internal regarding this issue but wasn't able to resolve this on my own, as far as I can tell it seems like ./src/loader.js isn't even being included in the bundle properly which resulted in me adding:

  entry: [
    "./src/index",
    // This seems necessary for module to even be available
    "./src/loader.js"
  ],

I'm also not sure if I'm providing the right 'container', any help is appreciated thanks!

@CLAassistant
Copy link

CLAassistant commented Jan 6, 2021

CLA assistant check
All committers have signed the CLA.

@ScriptedAlchemy
Copy link
Member

@ScriptedAlchemy
Copy link
Member

This is a fix, right, not an example of a problem. Just checking before mergeing

@ksrb
Copy link
Contributor Author

ksrb commented Jan 14, 2021

This is a example of a problem, not a fix.

This PR represents code that is not working using the examples of code from:
webpack/webpack#12258

Feel free to ask for more context, the issues are quite long so it might be a bit muddled 😅.

@ksrb
Copy link
Contributor Author

ksrb commented Jan 14, 2021

Just noticed the comments left by Guriqbal-Singh-Alida and jacob-ebey on the issue and his respective repo at https://github.com/jacob-ebey/fed-internal-remote-browser.

Might try integrating the code from the repo and seeing how it goes but the approach seems a bit... complicated.

@Guriqbal-Singh-Alida
Copy link

Guriqbal-Singh-Alida commented Jan 14, 2021

@ScriptedAlchemy and @ksrb please check latest comments webpack/webpack#12258 (comment) , the approach doesnot fully work specially if you are importing react in exposed module

@ScriptedAlchemy
Copy link
Member

if you find a solution please PR it, some will reload the remote containers to re-attach new sharing scopes that were lazy added

@ScriptedAlchemy ScriptedAlchemy added the help wanted Extra attention is needed label Jan 14, 2021
@Guriqbal-Singh-Alida
Copy link

Guriqbal-Singh-Alida commented Jan 15, 2021

@ScriptedAlchemy @ksrb it is solved now please check webpack/webpack#12258 (comment)

@17biubiu
Copy link

17biubiu commented Jan 22, 2021

I met the same issue, What I am more puzzled is that it is easy to develop locally, but when i build and then deploy it to server, it not work. the error is "fn is not function"
image

@ksrb ksrb force-pushed the dynamic-remotes-synchronous-imports branch from 7bf993b to 776b847 Compare February 1, 2021 20:35
@ksrb
Copy link
Contributor Author

ksrb commented Feb 1, 2021

Looked over everything and updated the PR to utilize the plugin created by matthewma7 from #566.

The end result will look like this:
image

To utilize the plugin you have to do this following:

Host (app1) webpack.config

const config = {
   ...otherConfigs
  plugins: [
    new ModuleFederationPlugin({
      name: "app1",
      remotes: {
        app2: "app2@[window.app2Url]/remoteEntry.js"
      }
    }).
    new ExternalTemplateRemotesPlugin(),
  ]
}

Host (app1) source somewhere before loading main entry file

window.app2Url = "//localhost:3002"; // Whatever the url/logic to determine your remote module is

import("./bootstrap");

The remote module doesn't have to change just make sure your global window variable for the remote url and the module name are different, aka make sure app2 and app2Url are different strings.

@ksrb
Copy link
Contributor Author

ksrb commented Feb 1, 2021

@ScriptedAlchemy feel free to close or merge this PR I think this issue has been resolved.

@jacob-ebey jacob-ebey merged commit 433f73a into module-federation:master Feb 7, 2021
@AboyL
Copy link

AboyL commented Nov 22, 2022

This plugin doesn't seem to solve the caching problem

module-federation/external-remotes-plugin#4
#2449

@Hezard
Copy link

Hezard commented Jan 11, 2023

Hi @ksrb, could you please explain how this synchronous imports work?
As, I understand ExternalTemplateRemotesPlugin enables ability to define remote containers urls via window object at runtime.
But how are we getting synchronous imports to be able to work, this looks like a webpack magic.
I checked webpack docs and I don't see anything about this kinda behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants