vite-plugin-federation icon indicating copy to clipboard operation
vite-plugin-federation copied to clipboard

Shared dependancies trying to load directly from `node_modules` instead of Vite Dev Server

Open iamdriz opened this issue 1 year ago • 6 comments

Versions

  • vite-plugin-federation: "^1.3.2"
  • vite: "^4.5.0"

Steps to reproduce

We're using Vite Ruby (https://vite-ruby.netlify.app/) to run a Ruby on Rails application with a Vite front-end. In this app we want to pull in some external remotes apps using vite-plugin-federation. However it seems that the shared option causes some issues when it tries to load in the dependancies such as react etc.

Our vite.config.js on our HOST application is as follows:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import RubyPlugin from "vite-plugin-ruby";
import FullReload from "vite-plugin-full-reload";
import federation from "@originjs/vite-plugin-federation";

export default defineConfig({
  plugins: [
    react(),
    RubyPlugin(),
    FullReload(["config/routes.rb", "app/views/**/*"]),
    federation({
      name: "host",
      remotes: {
        remote_app: "http://localhost:5000/assets/remoteEntry.js",
      },
      shared: ["react", "react-dom"],
    }),
  ],
  build: {
    target: "esnext",
    minify: false,
    cssCodeSplit: false,
    modulePreload: false,
  },
});

Our vite.config.js on our REMOTE application is as follows:

import { defineConfig } from "vite";
import federation from "@originjs/vite-plugin-federation";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [
    react(),
    federation({
      name: "remoteApp",
      filename: "remoteEntry.js",
      exposes: {
        "./App": "./src/App",
      },
      shared: ["react", "react-dom"],
    }),
  ],
  build: {
    target: "esnext",
    minify: false,
    cssCodeSplit: false,
    modulePreload: false,
  },
  preview: {
    host: "localhost",
    port: 5000,
    strictPort: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
  },
});

What is actually happening?

When we start the application we get a 404 error when it tries to load react.js:

__x00__virtual:__federation__:20 
        
        
       GET http://localhost:3000/node_modules/.vite/deps/react.js?v=0ab3fa3a net::ERR_ABORTED 404 (Not Found)
get @ __x00__virtual:__federation__:20
get @ __x00__virtual:__federation__:29
getSharedFromRuntime @ __federation_fn_import.js:385
importShared @ __federation_fn_import.js:363
(anonymous) @ __federation_expose_App.849a9f8f.js:35
remoteApp:1 Uncaught TypeError: Failed to fetch dynamically imported module: http://localhost:3000/node_modules/.vite/deps/react.js?v=0ab3fa3a

What is Expected?

It should be loading that file from:

http://localhost:3000/vite-dev/@fs/Users/cameron/Projects/app/node_modules/.vite/deps/react.js?v=0ab3fa3a

Looking into the source code (Chrome DevTools) this is due to the code using window.location.origin to load the file and NOT prefixing it with the vite-dev server location:

image

As this 'share' code is generated by this plugin, I'm assuming its an issue with how that wrapShareScope is generated. Possible this file/line here: https://github.com/originjs/vite-plugin-federation/blob/7b88529a80caa396b4e2cab6b8f120093578ac47/packages/lib/src/dev/remote-development.ts#L406

How can I resolve this? Are we able to pass some additional configuration to make this look at the correct location? As this is a big blocker and prevents any shared dependancies such as React, etc.

iamdriz avatar Nov 09 '23 16:11 iamdriz

I've added a temporary hack into our Rails app that intercepts requests to /node_modules and then redirects to the Vite Dev Server which works, so it is a case of handling this URL to make it work... it would be better to have this handled by the plugin... any ideas why it's failing to do this out of the box and defaulting to the location.origin?

iamdriz avatar Nov 10 '23 09:11 iamdriz

seeing the same issue, one remote MFE that is running on 1.3.2 is not using the original server path to load a missing dependency and using the host's URL. But a different remote MFE running 1.2.0 is loading from the correct base href if a shared dependency is missing

liu351 avatar Nov 14 '23 22:11 liu351

Same thing. Can't make it work. 404 for the shared vue package..

Actually, it's quite a bad situation, because we have our main project builded via nuxt3 wich is being runned on vite. And we need to somehow make it work with federation plugin.

I hope for response in not too long time... sadly it's 2 weeks already without any answer what to do :(

Dodje avatar Nov 20 '23 10:11 Dodje

In order to make this in Rails I've had to add this controller:

class NodeModulesController < ApplicationController
  def show
    redirect_to "#{request.protocol}#{request.host_with_port}/vite-dev/@fs#{Rails.root}#{request.path}"
  end
end

And then a route that captures any requests to /nodules_modules from the client:

get '/node_modules(/*path)', to: 'node_modules#show'

iamdriz avatar Nov 24 '23 14:11 iamdriz

Same issue, workaround with proxy in vite.config

server: {
      port: 3001,
      proxy: {
        '^/node_modules': {
          target: 'http://localhost:3001',
          changeOrigin: true,
          rewrite: path => [process.cwd(), path].join(''),
        }
      }
    },

pslamavertice avatar Feb 13 '24 10:02 pslamavertice