webpack / webpack-dev-server

Serves a webpack app. Updates the browser on changes. Documentation https://webpack.js.org/configuration/dev-server/.
MIT License
7.79k stars 1.43k forks source link

Webpack module federation breaks with multiple entrypoints #2692

Open codepunkt opened 4 years ago

codepunkt commented 4 years ago

This time it's @sokra who told me this is probably the place to open an issue.

Code

https://github.com/codepunkt/module-federation-examples/tree/dynamic-host-remote

Expected Behavior

Using webpack-dev-server instead of webpack should still support module federation with additional content tacked onto the remoteEntry by defining it as an additional entry.

Actual Behavior

Running "yarn start" to start webpack-dev-server breaks module federation and thus breaks the app in development mode.

For Bugs; How can we reproduce the behavior?

  1. clone repository
  2. ensure you're on branch "dynamic-host-remote"
  3. run yarn on repo root
  4. go into "dynamic-host-remote" directory
  5. run yarn start in "dynamic-host-remote" directory
  6. open localhost:3001 in the browser
  7. encounter an error in the browser console that happens when executing app2/remoteEntry.js with the additional contents that were added to this entrypoint by webpack-dev-server
  8. OPTIONAL: run yarn build && yarn serve and revisit localhost:3001 to see production build working just fine.
alexander-akait commented 3 years ago

WIP

tianyingchun commented 3 years ago
  ok() {
    sendMessage("Ok");

    if (options.overlay) {
      hide();
    }
  // below code is removed in v4.0.0, recovery it  it works
   // if (options.initial) {
     // return (options.initial = false);
    //}

    reloadApp(options, status);
  },

above code while first start up webpack dev server it will always invoke reloadApp but it should not call reloadApp while first enter ok()

alexander-akait commented 3 years ago

We move options.initial in reloadApp, because it is break lazy compilation, it is weird check, now check inside reloadApp

tianyingchun commented 3 years ago

no idea, but it seems that, i can't see anything about initial status in reloadApp maybe there missed something

 const isInitial = status.currentHash.indexOf(webpackHash) === 0;

  if (isInitial) {
    const isLegacyInitial =
      webpackHash === "" && hot === false && liveReload === true;

    if (isLegacyInitial) {
      status.previousHash = status.currentHash;
    }

    return;
  }
alexander-akait commented 3 years ago

I can't reproduce your problem, please create reproducible test repo

tianyingchun commented 3 years ago

ok, i try to create an demo repo now. :)

tianyingchun commented 3 years ago

this demo i need spend some time, do you have tried for multiple webpack compiler? @alexander-akait

alexander-akait commented 3 years ago

Yes, works fine everywhere, even more we have tests on this

alexander-akait commented 3 years ago

You can try to debug it, go to node_modules/webpack-dev-server/client/reloadApp.js and put console.log(webpackHash);console.log(status) and put logs here (don't forget preserve them in dev tools)

tianyingchun commented 3 years ago

webpackHash: "ee67c9096e15366640d4", status: {isUnloading: false, currentHash: "b83ab9f474a182a21a82"}

alexander-akait commented 3 years ago

It is on initial run? very weird, it means somebody change your hash of build

tianyingchun commented 3 years ago

yes only the first initial run, while i update my code and save, it works fine.

tianyingchun commented 3 years ago

could you give suggestions?

alexander-akait commented 3 years ago

No idea, maybe non official plugin break, hash should not changed on initial run, please create reproducible test repo

tianyingchun commented 3 years ago

ok i have created demo repo for reproduce this issue.

alexander-akait commented 3 years ago

Great, can you provide a link?

tianyingchun commented 3 years ago

wait me moment, it seem that i can't commit github now, authentication failed. https://github.com/tianyingchun/webpack-dev-server-demo-2692

tianyingchun commented 3 years ago

i have updated repo demo here please check it . https://github.com/tianyingchun/webpack-dev-server-demo-2692

  1. npm install
  2. node serve.js
  3. open url: http://localhost:5000

you can see the page infinite loop reload now

alexander-akait commented 3 years ago

Thanks, I will look at this in near time

alexander-akait commented 3 years ago

oh, you have multiple hmr with different hashes, it is weird usage, to be honestly, ideally you should run dev server on each compiler

alexander-akait commented 3 years ago

we plan for webpack-dev-server@4.1 implement plugin support so you will put plugins: [new DevServer(options)] for the each compiler

alexander-akait commented 3 years ago

Or use multiple entries...

alexander-akait commented 3 years ago

i.e. you have only one hmr code and web socket connection, but handle them different compilers (so web socket gets hashes from first and from second compilers), it is not safe generally, before it works only because we have bug in runtime logic, after fix it you got the problem

alexander-akait commented 3 years ago

Can you clarify why do you use single dev server for multi compiler mode? What is use case? Why do not run two dev servers?

tianyingchun commented 3 years ago

yes, we have huge complex project with multiple modules in one repo, we setup configurations to allow us start serve for these individual modules one or more ,because these modules is individual SPA application;

  1. we want to startup one server with the same host && port like http://localhost:5000/
  2. we attached customized middleware in dev Server pipeline /pages/*
  3. we don't want to start serve for each module with different dev server, because it has different access url.
  4. also has more reason, because webpack it has support multi compilers, i think dev-server should support we pass multi compilers with hot
tianyingchun commented 3 years ago

we plan for webpack-dev-server@4.1 implement plugin support so you will put plugins: [new DevServer(options)] for the each compiler

for this, do dev-server start only one or multi dev server for multi modules?

alexander-akait commented 3 years ago

also has more reason, because webpack it has support multi compilers, i think dev-server should support we pass multi compilers with hot

Sorry, it is impossible by design, you can't have the same HMR code for multi compilers, it is invalid and weird, before you don't have bug due our invalid logic for initial, in fact you should have gotten this problem much earlier, we support multi compiler mode, but your case has multiple independent builds with the same HMR, even more new features like lazyCompilation, buildless mode (future) will not work too

alexander-akait commented 3 years ago

Even more, you have only one web socket connection, therefore hash from one build will be already rewrite hash from other build, in theory we can pass unique name of compiler and implement multiple statuses, but it is more work then you think, also many plugins (for dev server) can break your HMR

alexander-akait commented 3 years ago

yes, we have huge complex project with multiple modules in one repo, we setup configurations to allow us start serve for these individual modules one or more ,because these modules is individual SPA application;

in this case you should use multi entry mode (it will optimize your code even better) or module federation

tianyingchun commented 3 years ago

ok, i have rewrite my codebase to startup multi dev-server with multi port and dynamic organize them into express server page proxy.

BTW it seems that we can't disabled logger.info() message via dev-server config, or webpack stats.logging= false.

tianyingchun commented 3 years ago

And does webpack-dev-server provider @types for v4.0.0?

snitin315 commented 3 years ago

And does webpack-dev-server provider @types for v4.0.0?

No, but it is in our roadmap.

alexander-akait commented 3 years ago

@tianyingchun for logger we have the special option https://webpack.js.org/configuration/other-options/#level, we decide don't have a lot of different logger options as were before and focus only on one

IgorStetsiuk commented 2 years ago

This time I'll be that guy... do we have any updates on this?

Have one question regarding Hot Module Replacement. Seems it doesn’t work properly. I used CRA with react-scripts v 5.0.0 and CRACO to override the webpack config in order to set up my module federation and that’s everything is fine (build, test, start commands)… Thought when it comes to the local development I need manually hard reload pages to reflect changes, and it’s really inconvenient.

I'm thinking to build React app from a scratch and playing around with webpack config but that is not what I wanted to do as we already have a pretty well config provided by CRA only need to override it for Module Federation config is that correct?

Does somebody know whether CRA (latest version 5) is able to work with hot module reload? What configuration do I miss? Thank you!

ScriptedAlchemy commented 2 years ago

This time I'll be that guy... do we have any updates on this?

Have one question regarding Hot Module Replacement. Seems it doesn’t work properly. I used CRA with react-scripts v 5.0.0 and CRACO to override the webpack config in order to set up my module federation and that’s everything is fine (build, test, start commands)… Thought when it comes to the local development I need manually hard reload pages to reflect changes, and it’s really inconvenient.

I'm thinking to build React app from a scratch and playing around with webpack config but that is not what I wanted to do as we already have a pretty well config provided by CRA only need to override it for Module Federation config is that correct?

Does somebody know whether CRA (latest version 5) is able to work with hot module reload? What configuration do I miss?

Thank you!

This is a very hard problem to solve. An easy workaround I use is I'll fetch all remote urls on a poll and hash them. If any hash based on the contents changes, I window reload the page. Simple but easy way to get live reloading.

HMR is not easy since webpack needs to know both where something exists and where it's consumed. All graphs would need to be interlinked

IgorStetsiuk commented 2 years ago

@ScriptedAlchemy Hello! Thank you for your reply. Wouldn't you mind sharing a piece of that config where you "fetch all remote URLs on a poll and hash them"? I'm not super aware of how to set up such config in webpack and it sounds a bit difficult to me to implement that so maybe some samples would be really helpful to me to understand that configuration and make live reloading in my case. Thank you again!

ScriptedAlchemy commented 2 years ago

Fetch(jsUrl).then(text).then(md5hashFronString)

Store it on some object and put the fetch in a setInterval.

xujie-phper commented 2 years ago

any updates, i face the same issue when use module federation

rdenman commented 1 year ago

Since this issue is still open, I'll link to my (pretty damn hacky) "solution" for HMR I posted in another thread: https://github.com/webpack/webpack/issues/11240#issuecomment-1505935214

It's very far from perfect, but it does the job in a pinch

ssuvorov commented 11 months ago

20 October 2023 👀