Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Dynamic Remotes #157

Open
jzsplk opened this issue Mar 23, 2022 · 15 comments
Open

Support for Dynamic Remotes #157

jzsplk opened this issue Mar 23, 2022 · 15 comments
Labels
enhancement New feature or request

Comments

@jzsplk
Copy link

jzsplk commented Mar 23, 2022

Is your feature request related to a problem? Please describe.

For now we have to define the remotes in host at buildtime
Is there a way that remotes can be defined dynamically at run time instead?

Describe the solution you'd like

Would like a solution for dynamic import remote component from an remote url at runtime, no need define the remote in the vite plugin conifg.
like in wepack, can ref here: webpack/webpack#11033
will this feature be in the roadmap?

Describe alternatives you've considered

Additional context

basicly same as issue #121

@jzsplk jzsplk changed the title Is your feature request related to a problem? Please describe. We want to get a list of remotes at runtime from another api service. e.g. GET /api/services. From the examples here I can only see how to do this at build time by specifying the remotes in vite.config.js or rollup config. Describe the solution you'd like We would like to dynamically load remotes at runtime, here is an example of doing it w/ webpack and their "container" model: https://github.com/module-federation/module-federation-examples/blob/master/dynamic-system-host/app1/src/App.js I've had a bit of look into some of the code in expose-dev.ts but its still early for me. Does this sound feasible? Describe alternatives you've considered Trying to use systemjs perhaps? Support for Dynamic Remotes Mar 23, 2022
@flyfishzy flyfishzy added enhancement New feature or request help wanted Extra attention is needed labels Mar 23, 2022
@flyfishzy
Copy link
Member

Not supported yet, but contributions are welcome!

@T0miii
Copy link

T0miii commented Apr 22, 2022

Hello, thank you for you work.

Is there an example how the dynamic remotes are working? Is it similar to webpacks approach?


await __webpack_init_sharing__("default");
// TODO: load the script tag somehow. e. g. with a script loader
const container = window.application_a;
// Initialize the container, it may provide shared modules
await container.init(__webpack_share_scopes__.default);
const module = await container.get("./module");

@ruleeeer
Copy link
Collaborator

Hello, thank you for you work.

Is there an example how the dynamic remotes are working? Is it similar to webpacks approach?


await __webpack_init_sharing__("default");
// TODO: load the script tag somehow. e. g. with a script loader
const container = window.application_a;
// Initialize the container, it may provide shared modules
await container.init(__webpack_share_scopes__.default);
const module = await container.get("./module");

I have released version 1.1.5, you can check the readme and demo for usage

@T0miii
Copy link

T0miii commented Apr 26, 2022

Thank you, but if i understand correclty this needs to happen on build level. And can not add Remotes in run time right?

@ruleeeer
Copy link
Collaborator

Thank you, but if i understand correclty this needs to happen on build level. And can not add Remotes in run time right?

You can try to dynamically fetch a component or register a remote by adding the following code to the compiled code,Please note that the values of the parameters from , format etc. are adjusted according to the different configurations

// dynamic is your remote name
remotesMap['dynamic'] = {
    url: "http://localhost:5003/assets/remoteEntry.js",
    format: 'esm',
    from: 'vite'
}
const comp = await __federation_method_getRemote('dynamic', '. /Button');

Or you can refer to the previous issue #121 (comment)

@T0miii
Copy link

T0miii commented Apr 28, 2022

Very nice, this is what i was looking for, ill give it a spin and come back with feedback, thx a lot.

@ruleeeer ruleeeer removed the help wanted Extra attention is needed label Apr 28, 2022
@philals
Copy link

philals commented May 2, 2022

Thanks

This test works for me:

   "@squad2": {
          external: `Promise.resolve(window.localStorage.setItem("address2","http://localhost:3002/assets/remoteEntry.js") || window.localStorage.getItem('address2'))`,
          externalType: "promise",
        },

@DileSoft
Copy link

It will be good if I can change remotesMap directly from code, if it will be attached to window object for example.

@T0miii
Copy link

T0miii commented May 25, 2022

Collaborator

i think with this solution you can change it in the code, but before resolveing your remote component, you would have to update the remoteMap, if i understand you correctly.

@DileSoft
Copy link

I want to use it on dev and prod both and in main code, don't manually edit generated code by plugin.

@DileSoft
Copy link

What I want exactly:

In React code made dynamic import of remote app and remote component, both names of app and component set from variables dynamically depend of props.

@DileSoft
Copy link

Maybe __federation_method_getRemote and remotesMap should be attached to window and could be accesses from anywhere.

@T0miii
Copy link

T0miii commented Feb 15, 2023

Thank you, but if i understand correclty this needs to happen on build level. And can not add Remotes in run time right?

You can try to dynamically fetch a component or register a remote by adding the following code to the compiled code,Please note that the values of the parameters from , format etc. are adjusted according to the different configurations

// dynamic is your remote name
remotesMap['dynamic'] = {
    url: "http://localhost:5003/assets/remoteEntry.js",
    format: 'esm',
    from: 'vite'
}
const comp = await __federation_method_getRemote('dynamic', '. /Button');

Or you can refer to the previous issue #121 (comment)

@ruleeeer i see that the

is exported, but when using it in the code its undefined, do we need to import someting else first?
@DileSoft did you had any success with this?

@iconag-bbasmer
Copy link

iconag-bbasmer commented Apr 27, 2023

I have setup an example for loading components completely dynamic, reading which components to load from a .json file. The only issue there is: There seems to be some kind of race condition for loading multiple components when it comes to Hooks. If I only add one component to load in the json file, then everything works fine. If I have multiple, like in the example, the components that use React functionality like Hooks fail loading with an error message telling that Hooks functionality does not exist (see vapp1 in the example).

Repo with example: https://github.com/iconag-bbasmer/vite-module-federation-test

@SepVeneto
Copy link

Thank you, but if i understand correclty this needs to happen on build level. And can not add Remotes in run time right?

You can try to dynamically fetch a component or register a remote by adding the following code to the compiled code,Please note that the values of the parameters from , format etc. are adjusted according to the different configurations

// dynamic is your remote name
remotesMap['dynamic'] = {
    url: "http://localhost:5003/assets/remoteEntry.js",
    format: 'esm',
    from: 'vite'
}
const comp = await __federation_method_getRemote('dynamic', '. /Button');

Or you can refer to the previous issue #121 (comment)

@ruleeeer i see that the

is exported, but when using it in the code its undefined, do we need to import someting else first? @DileSoft did you had any success with this?

@T0miii maybe need to add the fields remotes in plugin options, even if there is no static remote components.
like this, packages/examples/vue3-demo-esm

import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import federation from '@originjs/vite-plugin-federation'

// https://vitejs.dev/config/
export default defineConfig({
    server: {
        // host: "192.168.56.1",
        // port: 5100
    },
    cacheDir: 'node_modules/.cacheDir',
    plugins: [
        vue(),
        federation({
            name: 'layout',
            filename: 'remoteEntry.js',
+           remotes: {} ,
-           remotes: {
-               home: {
-                   external: `Promise.resolve('http://localhost:5001/assets/remoteEntry.js')`,
-                   externalType: "promise"
-               },
-               'common-lib': {
-                   external:`new Promise(resolve=>resolve('http://localhost:5002/assets/remoteEntry.js'))`,
-                   externalType:"promise"
-               },
-               'css-modules': 'http://localhost:5003/assets/remoteEntry.js'
-           },
            shared: {
                vue:{
                    // This is an invalid configuration, because the generate attribute is not supported on the host side
                },
                pinia:{
                }
            }
        })
    ],
    build: {
        target: 'esnext',
        minify: false,
        cssCodeSplit: true,
        rollupOptions: {
            output: {
                minifyInternalExports: false
            }
        }
    }
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants