vitejs / vite-plugin-react

The all-in-one Vite plugin for React projects.
MIT License
586 stars 110 forks source link

Having "react" in optimizeDeps.include creates problems when "react" is externalized #277

Closed MilanKovacic closed 9 months ago

MilanKovacic commented 9 months ago

Describe the bug

Currently, plugin automatically sets react, and runtimes into optimizeDeps.include.

When react is externalized during development (and for example, provided through import maps) this behavior is unwanted and results in various warnings / errors.

Is there a possibility that this behavior could be made opt-in, or something similar?

Reproduction

Not relevant

Steps to reproduce

No response

System Info

Not relevant

Used Package Manager

npm

Logs

No response

Validations

ArnaudBarre commented 9 months ago

What's the need to externalized deps in dev?

MilanKovacic commented 9 months ago

One of the common use cases is when utilizing microfrontends architecture, where all microfrontends consume the same version of "react", for example, provided through import maps — to avoid issues with multiple instances of react.

Discussions on this topic:

https://github.com/vitejs/vite/issues/6582 https://github.com/vitejs/vite/issues/2483

ArnaudBarre commented 9 months ago

Yeah as you encounter this kind of need (micro-frontend, module federation, multiple dev server in dev, ...) is not supported by Vite today. I think @yyx990803 wants that to be better supported in the revamp with Rolldown, but until I'm not personally willing to add support for these feature requests that feels like Conway's low for me. As already mentioned in multiple other issues, Vite is really flexible as soon as your keep one dev server, and you can have an index.html with <div id="app1"></div><div id="app1"></div> and an index.tsx with import "../../app1/src/index.tsx"; import "../../app2/src/index.tsx"; that will boot both apps.

Anyway, if really you want to go forward with this separation of dev-servers, you can inject a plugin that does something like:

{
  name: "remove-react-optimized",
  config(config) {
    config.optimizeDeps.include = config.optimizeDeps.include.filter(
      (d) => d !== 'react' && !d.startsWith("react/"),
    )
  }
}

(Not tested but should work when added after the react plugins)