originjs / vite-plugin-federation

Module Federation for vite & rollup
Other
2.39k stars 242 forks source link

Issue with Remix and Vite apps using Federation #609

Open anajnas66 opened 4 months ago

anajnas66 commented 4 months ago

Versions

Reproduction

[vite] Error when evaluating SSR module virtual:remix/server-build: |- TypeError [ERR_INVALID_ARG_VALUE]: The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received '\x00virtual:/__federation__'

Additional Details
**Host vite config file -** ``` import { vitePlugin as remix } from "@remix-run/dev"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; import federation from "@originjs/vite-plugin-federation"; export default defineConfig({ plugins: [ remix({ future: { v3_fetcherPersist: true, v3_relativeSplatPath: true, v3_throwAbortReason: true, }, }), federation({ name: 'hostApp', remotes: { remoteApp: "http://localhost:3000/assets/remoteEntry.js", } }), tsconfigPaths(), ], build: { modulePreload: false, target: 'esnext', minify: false, cssCodeSplit: false } }); ``` **Remote's vite.config file** - ``` import { vitePlugin as remix } from "@remix-run/dev"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; import federation from '@originjs/vite-plugin-federation' export default defineConfig({ plugins: [ remix({ future: { v3_fetcherPersist: true, v3_relativeSplatPath: true, v3_throwAbortReason: true, }, }), federation({ name: 'remoteApp', filename: 'remoteEntry.js', // Modules to expose exposes: { './Button': './app/components/button', } }), tsconfigPaths(), ], build: { modulePreload: false, target: 'esnext', minify: false, cssCodeSplit: false } }); ``` NOTE: The bundled file is accessible at http://localhost:3000/assets/remoteEntry.js ``` const exportSet = new Set(['Module', '__esModule', 'default', '_export_sfc']); let moduleMap = { "./Button":()=>{ dynamicLoadingCss(["style-BMp_cBgO.css"], false, './Button'); return __federation_import('./__federation_expose_Button-BxGtt5ih.js').then(module =>Object.keys(module).every(item => exportSet.has(item)) ? () => module.default : () => module)},}; const seen = {}; const dynamicLoadingCss = (cssFilePaths, dontAppendStylesToHead, exposeItemName) => { const metaUrl = import.meta.url; if (typeof metaUrl == 'undefined') { console.warn('The remote style takes effect only when the build.target option in the vite.config.ts file is higher than that of "es2020".'); return } const curUrl = metaUrl.substring(0, metaUrl.lastIndexOf('remoteEntry.js')); cssFilePaths.forEach(cssFilePath => { const href = curUrl + cssFilePath; if (href in seen) return seen[href] = true; if (dontAppendStylesToHead) { const key = 'css__remoteApp__' + exposeItemName; if (window[key] == null) window[key] = []; window[key].push(href); } else { const element = document.head.appendChild(document.createElement('link')); element.href = href; element.rel = 'stylesheet'; } }); }; async function __federation_import(name) { return import(name); } const get =(module) => { if(!moduleMap[module]) throw new Error('Can not find remote module ' + module) return moduleMap[module](); }; const init =(shareScope) => { globalThis.__federation_shared__= globalThis.__federation_shared__|| {}; Object.entries(shareScope).forEach(([key, value]) => { const versionKey = Object.keys(value)[0]; const versionValue = Object.values(value)[0]; const scope = versionValue.scope || 'default'; globalThis.__federation_shared__[scope] = globalThis.__federation_shared__[scope] || {}; const shared= globalThis.__federation_shared__[scope]; (shared[key] = shared[key]||{})[versionKey] = versionValue; }); }; export { dynamicLoadingCss, get, init }; ```

Steps to reproduce

What is Expected?

The host app should be able to access the Button component exposed from the remote app and render properly.

What is actually happening?

The remote app builds successfully while the host app throws the error while running "npm run build" [vite] Error when evaluating SSR module virtual:remix/server-build: |- TypeError [ERR_INVALID_ARG_VALUE]: The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received '\x00virtual:/federation'

anajnas66 commented 4 months ago

Turns out I was running my app in dev mode. On running in prod mode using the serve command, I now see a different error while building my host app.

Error: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. Received protocol 'http:'

infantito commented 3 months ago

@anajnas66, Sorry. Have you already resolved this? I'm thinking of setting up a project with remix-spa and module federation.

ajmeraaxesh commented 3 months ago

@anajnas66 @infantito did this got resolved for you?

infantito commented 3 months ago

@anajnas66 @infantito did this got resolved for you?

I'm using the React Router v6 API because remix-run was ruled out by my team. React Router V6 works well with module federation; it probably would work with Remix SPA.

marono commented 3 months ago

Hello, good I came across this thread, I'm in the same boat - started building a fleet of frontends (not going to call them micro as they're really only sections) thinking module federation can't be that hard with Remix (given it's one of the recommendations in the React docs and the newer shinier option). Unfortunately it seems to me it's an unresolved problem so far. Any pointers are welcome. Thanks!

veeramarni commented 2 weeks ago

@marono/all anyone tried on remix with SSR successfully?

lucax88x commented 6 days ago

Same.

https://github.com/lucax88x/microfrontend-poc/tree/main/shells/shell-remix

but I have a different error

Error: require is not defined
MagedEWilliam commented 6 days ago

I noticed an example in the module federation example repo: https://github.com/module-federation/module-federation-examples/tree/master/remix

https://github.com/module-federation/module-federation-examples/tree/master/rspack-remix

I'm not sure if they are working

HarishkumarSP commented 6 days ago

Hey!

I also had same issue saying Error: Only URLs with a scheme in: file and data are supported by the default ESM loader. Received protocol 'http:' while doing a build and serve as remix-serve ./build/server/index.js

But this only happened on host app and in remote it works well but unfortunately css styling didn't applied while build and serve

Any comments are appreciated.

Update: I found that the above error occurs because of the federation plugin we use and for the remote and it points out that http which we used on below

remotes: {
 remoteApp: "http://localhost:3000/assets/remoteEntry.js",
},