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

Support Webpack Module Federation #12284

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

Conversation

raspy8766
Copy link

@raspy8766 raspy8766 commented Apr 13, 2022

Module Federation Support

Description

This PR aims to support the Webpack 5 module federation plugin natively in CRA. Micro-frontends are becoming a more prevalent form of UI development for the enterprise environment. We love what create-react-app provides, but in order to get it working at the moment, we rely on these forked changes. Hopefully this PR has what you're looking for, if not I'm happy to make additional accommodations and open to suggestions.

Proposed Changes

  • Add a new optional setupModuleFederation.js file that manages the webpack Module Federation plugin
  • When the setupModuleFederation.js file is present, use the Module Federation plugin
  • Since Micro-frontend apps do not typically have their own index.html (unless they're using iframes), the index.html file along with the public folder are now optional.

Testing

Setup

  1. Execute the following bash script which performs the following:
    • Initializes a new CRA mfe app repo
    • Clones down and installs the forked repo
    • Installs local react-scripts from forked repo
yarn create react-app mfe-app && \
git clone https://github.com/HewlettPackard/create-react-app.git && \
yarn --cwd="./create-react-app" && \
yarn --cwd="./mfe-app" add file:../create-react-app/packages/react-scripts

Negative Test

  1. In the mfe-app repo, run yarn start
  2. Navigate to http://localhost:3000/webpack-dev-server and note the files listed appear as normal

Positive Test

  1. Create a src/setupModuleFederation.js file with the following contents:
module.exports = {
  name: 'test',
  library: { type: 'var', name: 'test' },
  filename: 'remoteEntry.js',
  exposes: { '.': './src/App.js' }
}
  1. Navigate to the mfe-app repo
  2. Delete the public/index.html file (optional)
  3. Run yarn start
  4. Navigate to http://localhost:3000/webpack-dev-server and notice the remoteEntry.js file

Screenshots

Webpack served assets:

image

remoteEntry.js file:

image

@facebook-github-bot
Copy link

Hi @raspy8766!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@raspy8766 raspy8766 closed this May 4, 2022
@raspy8766 raspy8766 reopened this May 4, 2022
@raspy8766 raspy8766 closed this May 5, 2022
@raspy8766 raspy8766 reopened this May 5, 2022
@mong8se
Copy link

mong8se commented May 5, 2022

Hello Hewlett Packard!

Greetings from Domino's.

Just wanted to thank you for doing this. We've been using your fork to to build out our module federation patterns and it's been great.

Hopefully this'll get merged soon.

Edit: fixed typo

@facebook-github-bot
Copy link

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-bot
Copy link

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@raspy8766
Copy link
Author

Hi @iansu @mrmckeb, my apologies with the CLA agreement delay. Had a few hoops and hurdles to go through to get that in place. Let me know if this looks good to you guys or if you have any other recommendations. Happy to augment it further where needed. Thanks!

@mikeaustin
Copy link

This feature is extremely interesting – to support module federation without having to use craco or use a separate webpack config. Any idea when this would show up in a release?

@SlowBurner
Copy link

SlowBurner commented Jun 9, 2022

@raspy8766, Thanks for sharing this!

One thing, I can't get this PR to work in the CRA development env for a Host app and a Remote app scenario without slight modification.

In the remote app, when running in the CRA development env we can not set the output.publicPath correctly in webpack.config.js. Most MF examples set output.publicPath to "auto". CRA does not allow this and it does not allow us to use a full URL in the development env.

This will cause any Remote app to use a relative path and they end up looking for their own modules inside the host that is trying to consume them. In sum, in the development env, Remote apps will have the wrong URL when you try to load their shared modules from a Host app.

webpack.config.js uses the function getPublicUrlOrPath, which gives us no control over setting output.publicPath for a Remote app within the development env.

I could be missing something, but how are you getting around this?
I guess you could use a combination of setupProxy.js and the PUBLIC_URL env property to route the request back to the correct webpackDev server.

Screen Shot 2022-06-09 at 12 03 54 PM

Screen Shot 2022-06-09 at 12 06 48 PM

Screen Shot 2022-06-09 at 12 04 07 PM

@raspy8766
Copy link
Author

@SlowBurner that's correct, we're using the PUBLIC_URL to modify the public path setting in webpack. As you can see PUBLIC_URL is directly used to set the webpack publicPath field your looking for

@SlowBurner
Copy link

@SlowBurner that's correct, we're using the PUBLIC_URL to modify the public path setting in webpack. As you can see PUBLIC_URL is directly used to set the webpack publicPath field your looking for

Cool! I got things working via PUBLIC_URL. Thanks again for the PR!

@kahboom
Copy link

kahboom commented Jul 4, 2022

thanks for your work on this @raspy8766 , really looking forward to seeing this get merged

@vish30
Copy link

vish30 commented Jul 22, 2022

Thank you @raspy8766 for your efforts to get Module Federation support in CRA. This would help many if it gets merged.

@cmnstmntmn
Copy link

hey, great job <3! any ideea when this is going to be merged?

@devi-prsd
Copy link

Is there an example on how to use this in a monorepo with a host and remotes?

@lehelp
Copy link

lehelp commented Aug 24, 2022

Great addition, would like to see it merged!

@kahboom
Copy link

kahboom commented Aug 24, 2022

@devi-prsd - there is a repo with many examples here that are essentially tiny monorepos: https://github.com/module-federation/module-federation-examples

If you mean a remote being deployed somewhere remotely from the host app (i.e. as static files on Netlify, GitHub pages), there is a post I wrote that explains how the setup could work, but you have to look past the business logic: https://kaoto.io/docs/add-custom-view/

Namely, in this project "step extensions" = remotes, and the URL of the remote gets passed in dynamically to the UI (host) from the API through a "view definition catalog" (basically just a configuration file).

Or if you'd really like a blog post for this topic, let me know.

@tobyscott25
Copy link

Wow, brilliant! Looking forward to seeing this merged!

@wrightmk
Copy link

bump

@SurjitSahoo
Copy link

SurjitSahoo commented Dec 9, 2022

I'm not able to get it to work. What am I missing?
I tried creating two apps, app1 and app2 with following steps:

yarn create react-app app1 --template=typescript && \
git clone https://github.com/HewlettPackard/create-react-app.git && \
yarn --cwd="./create-react-app" && \
yarn --cwd="./mfe-app" add file:../create-react-app/packages/react-scripts

Rename index.tsx -> bootstrap.tsx
index.tsx

import("./bootstrap.tsx")

app1/src/setupModuleFederation.js

const { dependencies } = require('../package.json');

module.exports = {
  name: "app1",
  library: { type: "var", name: "app1" },
  filename: "remoteEntry.js",
  exposes: {
    './hello': "./src/hello.tsx"
  },
  remotes: {},
  shared: {
    ...dependencies,
    react: {
      singleton: true,
      requiredVersion: dependencies.react,
    },
    "react-dom": {
      singleton: true,
      requiredVersion: dependencies["react-dom"],
    },
  }
}

app2/src/setupModuleFederation.js

const { dependencies } = require('../package.json');

module.exports = {
  name: "app2",
  library: { type: "var", name: "app2" },
  filename: "remoteEntry.js",
  exposes: {},
  remotes: {
    app1: "app1@http://localhost:3001/remoteEntry.js"
  },
  shared: {
    ...dependencies,
    react: {
      singleton: true,
      requiredVersion: dependencies.react,
    },
    "react-dom": {
      singleton: true,
      requiredVersion: dependencies["react-dom"],
    },
  }
}

app2/src/App.tsx

import Hello from 'app1/hello';

export default function App() {
  return <div><Hello /></div>
}

@douglaszaltron
Copy link

up

@nagarakesh4
Copy link

how long to merge?

@xepozz
Copy link

xepozz commented Apr 4, 2023

Up again

@hamzamihaidanielx
Copy link

up, why so hard to review the damn files??

@tobyscott25
Copy link

@allocenx Agreed, also wondering what the hold-up is ... 🤔

@maheshrajrp
Copy link

Any updates on this ?

@manohar-netomi
Copy link

Any update on this?

@tobyscott25
Copy link

I'm about to give up on react-scripts altogether and just use raw Webpack

@SurjitSahoo
Copy link

SurjitSahoo commented Jun 30, 2023

I'm about to give up on react-scripts altogether and just use raw Webpack

cool down mate! 😅
You can try mf-cra
For this same reason, I created this package and have been using it in production!

@tobyscott25
Copy link

I'm just sick of waiting on Facebook to support such a great Webpack feature when this PR has been sitting open for over a year now.

Great work on your package though, kudos! Personally, I prefer to stick to official packages, so I just made a boilerplate using raw Webpack 🙂

@SurjitSahoo
Copy link

I'd rather try to add the feature I want onto the official package with a script, than writing everything from scratch.

@AdrianGolda
Copy link

FB makes tons of money and they can't even review this simple thing?

@DrDiman
Copy link

DrDiman commented Aug 16, 2023

up

@kumarldh
Copy link

All, CRA is dead.

@sankethpb
Copy link

Hi Team
Any updates on this?

@devi-prsd
Copy link

All, CRA is dead.

probably affected by layoffs 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.