模块联邦

249 阅读2分钟

每个模块都可以向外暴露属性、方法给别的模块用,也可以引用其他模块的属性、方法

例如我们现在有remote这样一个项目,进行如下配置之后,就可以拥有这种功能:

    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new ModuleFederationPlugin({
            filename: 'remoteEntry.js',
            name: 'remoteVariable',
            remotes: {
                remote: "hostVariable@http://localhost:8000/remoteEntry.js"
            },
            exposes: {
                './NewsList': './src/NewsList'
            },
            shared: {
                react: { singleton: true },
                'react-dom': { singleton: true }
            }
        })

    ]

项目目录如下:

参数的意义如下:

filename:

我们虽然配置了filename: 'remoteEntry.js',但项目中实际并没有这样一个文件,可以猜测这个文件是webpack生成到内存或磁盘中用来给其他模块提供可访问的一些变量或方法用的

name:

该参数是本项目的一个标识,在其他项目中引用这个项目导出的属性、方法时就要用到这个标识,具体可参考接下来要介绍的remote参数

remotes:

用来存放要导入哪些模块,我们以上面的配置为例解释参数作用:

{
  remote: "hostVariable@http://localhost:8000/remoteEntry.js"
}

结构为kv键值对,v当中,hostVariable是要获取的远程模块的标识,这个标识就是上面的name参数,后面的地址是标识对应的项目的地址,remoteEntry.js是该项目导出属性、方法的文件,即上述filename配置的值,它的key是在当前项目中使用时的标识:

const RemoteSliders = React.lazy(() => import("remote/Sliders"));

自我总结:此处有一点需要说明,示例中给remotes赋值的对象,所示的是在本地开发时的一种引入方式,在生产环境中时,不可能配置localhost这种东西,所以,肯定是一个相对或绝对路径,例如:

{
  remote: "hostVariable@/remoteEntry.js"
}

/remoteEntry.js这个路径需要我们自己处理,让它的访问导流到我们想要的地方

exposes:

当前模块暴露给别的模块的模块引用

shared:

两个模块联邦到一起时,组件内import的依赖一定有公共的部分(例如都依赖react且版本都是16),这时就可以配置shared参数来达到复用的目的

附录: 联邦模块提出的背景,及想要解决的问题