Skip to content
joey edited this page Sep 3, 2021 · 2 revisions

Remote端暴露模块

  • Remote端需要实现2个特性:
    1. 提供remoteEntry.js入口文件给Host端
    2. 以配置的模块为入口单独打包chunk
  • 相关的配置为exposes选项,例如
exposes: {
        './Content': './src/components/Content.vue',
        './Button': './src/components/Button.js',
      },

实现原理

  • remoteEntry.js

remoteEntry.js需要暴露出 init(), get()两个函数供Host使用

let moduleMap = {
"./Button":()=>{return import('./button.js')},};
    const get =(module, getScope) => {
        return moduleMap[module]();
    };
    const init =(shareScope, initScope) => {
        let global = window || node;
        global.__rf_var__shared= shareScope;
    };

export { get, init };

init()做一些shareScope初始化的工作。get()会根据传入的模块名动态加载模块。

我们通过Rollup 的 emitFile()接口产生remoteEntry.js文件。同时需要根据配置构造一个moduleMap对象。

如果我们在生成的文件中一开始就这样定义moduleMap

let moduleMap = {
	"./Button":()=>{ return import('./src/components/Button.js') }
};

在Rollup中一切都没问题,但是在Vite中会将动态import自动提取为preload,这会导致Host加载remoteEntry.js时就提前加载了button.js。并且目前社区还不提供开关控制 #4097 。所以目前的解决方案是先使用__f__import__作为别名,最后在generateBundle()时替换回来。

同时这样操作后原始的文件名'./src/components/Button.js'并不会被rollup处理了,因此需要我们在generateBundle()阶段替换为最终的dist文件。

  • 单独打包chunk

我们需要将配置的exposes模块单独打包为chunk,供host调用时加载。

Rollup有几种方式可以实现Code Splitting

经过试验我们使用的是multiple entry points方式,在options()钩子中根据exposes改写rollup的input配置,例如示例的exposes会生成:

input: {
    Content: './src/components/Content.vue',
    Button: './src/components/Button.js'
}
Clone this wiki locally