originjs / vite-plugin-federation

Module Federation for vite & rollup
Other
2.34k stars 240 forks source link

Building host side fails with hoisted dependencies in monorepo when using lerna #276

Open SampsaKaskela opened 1 year ago

SampsaKaskela commented 1 year ago

Versions

Reproduction

https://github.com/SampsaKaskela/vite-plugin-federation-lerna-hoist

Build fails and you get error. If you remove federation plugin from vite config then build will be successful. There are couple of ways to work around with current version:

Both of these are very taunting tasks to do with large amount of dependencies so this probably should be automated.

Steps to reproduce

Setup lerna monorepo and bootstrap it using --hoist argument. Add federation plugin to package vite config and define remotes for it so plugin sees the app as host side. (remote side builds fine) Also define shared dependencies. Try to build the package.

What is Expected?

Package should build successfully.

What is actually happening?

Build fails due to trying to look versions of shared dependencies from packages local node_modules directory instead from hoisted node_modules directory at project root.

vite v3.2.2 building for production...
transforming (1) ..\..\node_modules\react\cjs\react.production.min.jsnode:internal/modules/cjs/loader:933
  const err = new Error(message);
              ^

Error: Cannot find module 'F:\Programming\vite-plugin-federation-lerna-hoist\packages\project1\node_modules\react\package.json'
Require stack:
- F:\Programming\vite-plugin-federation-lerna-hoist\node_modules\@originjs\vite-plugin-federation\dist\index.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at F:\Programming\vite-plugin-federation-lerna-hoist\node_modules\@originjs\vite-plugin-federation\dist\index.js:1947:143
    at async Object.buildStart (F:\Programming\vite-plugin-federation-lerna-hoist\node_modules\@originjs\vite-plugin-federation\dist\index.js:1947:39) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'F:\\Programming\\vite-plugin-federation-lerna-hoist\\node_modules\\@originjs\\vite-plugin-federation\\dist\\index.js'
  ]
}
brendonwai commented 1 year ago

I've had the same problem. After some debugging, it seem that on the host side if a version is not specified, it defaults to looking for the package in node_modules under the project directory.

image

So if you have a monorepo setup where most of your packages are hoisted to root level this fails. Seems like a bug to me, but setting the version for each shared package works for me.

          react: {
            version: '^17.0.2',
          },
          'react-dom': {
            version: '^17.0.2',
          },
SampsaKaskela commented 1 year ago

Would the solution be to implement the Node module resolution algorithm to this so that it would go to parent folder if the package.json is not found? I could maybe look into this if this would be seen as acceptable solution.