彻底搞懂 Module Federation:Webpack 模块联邦的加载原理与最佳实践
MF是在webpack5出来后提出来的新概念,解决模块级别复用问题。简单分为两种应用, 老版本的mf无法在webpack低版本等不支持module federation的构建插件中消费远程模块,而且导出模块和消费模块都是纯构建行为,加载过程被构建工具插件封装,只需要在代码中引入远程模块进行消费即可。 对原本项目的构建模式要求比较高。所以Module Federation2.0提出了Federation Runtime方法。提供高级Api在代码中动态引入消费远程模块,不受构建框架限制。具体的共享依赖复用、远程模块加载等行为全都封装到Runtime中。 目前Module Federation提供两种注册模块和加载模块的方式: 在构建工具对应的配置项中,增加module-federation插件配置 这里生产者通过配置exposes导出了Content和Button两个组件。 对于消费者提供了js api进行模块注册和模块加载,可以脱离构建插件使用,在 <!----> <!----> <!----> <!----> https://chromewebstore.google.com/detail/module-federation/ae... 官方发布的module-federation-examples,包含了很多不同构建框架之间结合使用的场景, 这里我们主要拿一个最简单的demo查看使用,依赖关系简单,方便对照分析后面的原理解析部分。 module-federation-examples/vue3-demo at master · module-federation/module-federation-examples 项目可以拆分成两个文件夹 <!----> <!----> 大白话解释一下,共享组件单独打包成一个异步chunk里面,共享的依赖会在加载组件之前进行前置加载,中间有一些复杂的依赖版本号比较,依赖库加载的逻辑通过 这里的加载模块流程分析准备分三部分,首先介绍最基础的webpack异步模块加载流程,后面分别介绍module federation两个引入方式对应不同的加载流程 按需加载,也叫异步加载、动态导入,即只在有需要的时候才去下载相应的资源文件。 在 webpack 中可以使用 home文件夹目录结构 App.vue组件里面进行组件注册时,使用import方法引入 本地开发环境配置修改后,重新进行构建,可以看到从请求html到后续的js、css文件加载顺序。 Request initiator chain <!----> 构建后的startUp 入口函数 <!----> <!----> <!----> 先从入口index.js文件开始看,里面只有一行代码,异步引入main.js模块, 但是构建后的startUp入口文件,里面包含了很多基础依赖库,只有在代码最后出现了index.js引入相关代码, 再把里面的代码简化一下,只保留关键的引入部分。 直接看到最后一行代码,通过\_\_webpack\_require\_\_方法引入index.js文件,这里也可以认为是一般的同步加载模块部分 继续看\_\_webpack\_require\_\_函数实现,先从\_\_webpack\_module\_cache\_\_缓存变量中获取moduleId为 缓存数据结构中factory字段存放模块里面的具体代码实现,通过\_\_webpack\_modules\_\_[moduleId]获取代码实现部分,最后执行。 接着看\_\_webpack\_modules\_\_变量,其实在文件最开头已经定义好了,这里才是真正存放原始的'src/index.js'文件,经过构建后的代码,可以具体看一下 简单看原始的 这里可以暂时理解成去异步请求main.js文件,等main.js文件请求完成后,进入then里面,执行 也就是进行一般的同步加载模块,类似前面加载 接着关键看 如何把main.js执行完成后,把自身代码实现设置到 遍历\_webpack\_require\_\_.f对象上挂载的所有方法,并执行。 两个方法 <!----> 接着看 push里面的内容跟. self是指向当前 window 对象的引用,在Service Workers和Web Workers非window场景下也适用 从[入口的js文件中]寻找 self["webpackChunkvue3\_demo\_home"]的实现。 上面代码有两个关键点: Module Federation 加载跟按需加载最大的区别是它需要处理共享模块和共享依赖, 如何进行依赖前置是很大的问题。 还是用前面的vue3-demo示例,现在设置上ModuleFederationPlugin插件,主要看Layout目录下的文件,从消费者角度看模块加载流程,入口文件还是 Request initiator chain 从请求链路入口js后面多了remoteEntry,提前加载了共享组件Content、Button <!----> 构建后的startUp 入口函数 <!----> <!----> 前面流程跟webpack异步模块的加载流程相同,简单过一下 到遍历执行\_webpack\_require\_\_.f上所有方法时,开始不同了, 多了\_\_webpack\_require\_\_.f.remotes 和\_\_webpack\_require\_\_.f.resumes方法, 项目里面 接着从moduleToHandlerMapping 对象里面,寻找共享依赖的加载和版本对比逻辑, 通过 <!----> 在执行 继续走到init方法,里面有 执行到register里面,可以看到还是将共享依赖,包括具体版本号,设置到了全局变量 里面包括了依赖的 具体到我们的demo,可以看一下 <!----> register后,接着就是加载远程应用 其实通过 加载完成后,执行加载模块remoteEntry.js里面暴露的init方法, 把当前上下文中的 接下来执行init函数时,需要明确一下是在remoteEntry.js这个文件上下文中执行的。里面也有一套同样的webpack模块加载函数和存储变量,虽然命名一样。 init方法里面,通过内部\_\_webpack\_require\_\_.S进行存储共享依赖,name也是对应'default',直接复用前面注册在S上的vue依赖,再次调用\_\_webpack\_require.I\_\_, 注册自己的依赖。 里面的这段很重要shareScope是在host应用中把 所以等价于 消费者和生产者里面注册的模块是同一个所以注册完成后\_\_webpack\_require\_\_.S里面还是只有一个3.3.7版本的vue 到这里共享依赖初始化完成了。 继续执行f上挂载的方法remoes,此时src/main.js模块,没有在chunkMapping里面没有映射到对应的共享依赖,直接跳过了remotes方法,继续走后面的处理逻辑,这里可以直接跳过,最后通过\_\_webpack\_require\_\_.f.j 函数加载src/main.js文件。同前面异步加载逻辑一样,放到\_\_webpack\_module\_\_变量里面, main.js里面引用Content和Button组件,构建时转换成 可以发现 data[2]表示依赖的远程应用资源 这个require在前面已经执行完成了,主要请求remoteEntry.js文件,存在缓存,直接从 正在promise.then方法里面,执行传入的next函数,也就是第5个参数 继续执行handleFunction函数 <!----> <!----> <!----> 这里external就是第一次执行\_\_webpack\_require\_\_("webpack/container/reference/home", 0),返回的promise结果,也就是远程应用remoteEntry.js里面的内容 回到remoteEntry.js里面,可以发现get方法 继续递归,这个get方法执行完成后,promise.then里面的next方法,也就是onFactory函数, 把获取到的./Content函数主体,从远程应用的上下文,重新赋值到当前host应用的\_\_webpack\_modules\_\_变量下, 后续再遇到引入./Content组件的场景,直接从\_\_webpack\_modules\_\_上获取, [回到src\_main\_js的实现部分],继续引入Button.js组件,执行后续操作 官方提供的Runtime API进行模块注册和加载,很大程度上打破了构建工具的限制,在一些老版本的项目上,也可以直接使用共享模块。从构建插件转向自定义的API提供加载,同时提供了更多的自定义配置和生命钩子函数。 深入理解API模型加载,可以发现实际上面模拟了前面构建时加载里面的动态创建script标签和通过全局的S变量进行共享库传递等核心功能。 Request initiator chain 跟前面module federation构建时加载流程有一点区别,remoteEntry.js文件的请求发起者是前置的基础库,也就是@module-federation/runtime-core。这是因为修改成Runtime API形式,使用官方库提供的loadRemote方法动态加载组件,而构建版本通过插件,在构建时已经将发起请求的逻辑注入到了前置的main.js文件中了。 这里主要关注host,也就是消费者(Layout)应用,在使用官方提供的API动态加载时的流程,所以在host应用中去掉webpack配置文件中的ModuleFederationPlugin 插件。 在入口main.js里面修改引入远程的组件的方法(红色部分为改动) 用了init和loadRemote两个Runtime API 大部分代码跟构建时类似,只有在正式初始化和加载远程组件时,需要调用前置加载的module-federation/runtime-core基础库 http://localhost:3001/vendors-node_modules_pnpm_mini-css-extr... 分析这里的init和loadRemote API就不用从入口文件加载开始,按照顺序分析,重点关注方法本身就行,也就是 还是看一下原始的main.js里面,init和loadRemote方法构建后源码; 提前获取@module-federation/runtime module,这个module在前置的公共chunk里面,也就是demo里面对应的http://localhost:3001/vendors-node_modules_pnpm_mini-css-extr... 文件。 异步模块加载的流程这里就不细讲了,聚焦到@module-federation/runtime仓库。 <!----> 查看源码位置:core/packages/runtime/src/index.ts at cfae7c06bd0f19aea0757fb2bcb7088ac29457cb · module-federation/c 官方文档里面推荐使用createInstance方法取代init. init方法只做 一次单实例的前置校验,通过getGlobalFederationInstance方法,判断相同name命名的实例是否已经注册过。没有注册则用createInstance 传入配置项初始化一个实例 实例对应的构造函数ModuleFederation,在另一个依赖里面 前面参数传递到这里的constructor并执行。 创建完成后 core/packages/runtime-core/src/global.ts at cfae7c06bd0f19aea0757fb2bcb7088ac29457cb · module-federa 函数初始化在外层,具体代码:core/packages/runtime/src/index.ts at cfae7c06bd0f19aea0757fb2bcb7088ac29457cb · module-federation/c 继续转到runtime-core的实例构造函数里面查看真正的loadRemote方法。 core/packages/runtime-core/src/core.ts at cfae7c06bd0f19aea0757fb2bcb7088ac29457cb · module-federati remoteHandle.loadRemote管理整个远程应用加载的执行顺序,并最终返回共享组件的具体内容。 通过 核心逻辑都在Module.get函数里面,后面主要分析这个get方法 Module实例可以简单理解成管理和加载远程模块remoteEntry.js的构造函数, 具体看Module 构造函数后面的get方法 core/packages/runtime-core/src/module/index.ts at cfae7c06bd0f19aea0757fb2bcb7088ac29457cb · module- module.get里面也包括了对应的生命周期钩子函数,主要关注几个核心的流程,注意这里的钩子函数主要方便用户进行自定义的远程模块加载,而我们主要讨论的是runtime-core提供的默认加载顺序,所以暂时忽略这些钩子的影响 <!----> core/packages/runtime-core/src/utils/load.ts at cfae7c06bd0f19aea0757fb2bcb7088ac29457cb · module-fe 这里有个钩子loadEntryHook.emit,就是支持用户自定义加载remoteEntry.js函数,如果没有配置,则继续判断是否在浏览器环境,是则通过loadEntryDom进行动态创建script标签。 loadEntryDom里面区别了不同的加载方法,默认走到loadEntryScript, 加载并执行remoteEntry.js 拿到remoteEntryExports内容后,继续Module.get后面的逻辑,后面开始处理远程应用的共享依赖shareScope了,其中shareScrope是我们初始化配置,同时也支持钩子函数设置,最后将处理的shareScope传入remoteEntryExports.init,开始共享依赖库跨应用传递 这里对应了前面构建时加载的[module.init], 有点类似 回到remoteEntry.js文件,再看一次里面的init和get方法 这里执行的init函数 如何进行共享依赖呢?其实获取保存宿主传递过来的shareScope, 这里共享依赖init函数就执行完成后,继续Module.get函数后面的流程 关键的一步就是执行 继续到 到这里远程组件才真正获取完成。moduleFactory返回给宿主。 <!----> <!----> <!---->1. 概述
1.1 基本概念

1.2 接入方案
1.2.1 介绍
module-federation.config.ts 文件中声明)runtime 的 api 进行模块注册和加载。运行时注册模块 插件中注册模块 可脱离构建插件使用,在 webpack4 等项目中可直接使用纯运行时进行模块注册和加载 构建插件需要是 webpack5 或以上 支持动态注册模块 不支持动态注册模块 不支持 import 语法加载模块 支持 import 同步语法加载模块 支持 loadRemote 加载模块 支持 loadRemote 加载模块 设置 shared 必须提供具体版本和实例信息 设置 shared 只需要配置规则即可,无须提供具体版本及实例信息 shared 依赖只能供外部使用,无法使用外部 shared 依赖 shared 依赖按照特定规则双向共享 可以通过 runtime 的 plugin 机制影响加载流程 目前不支持提供 plugin 影响加载流程 不支持远程类型提示 支持远程类型提示 1.2.2 构建时接入
1.2.2.1 消费者配置
1.2.2.1.1 webpack构建配置
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = (env = {}) => ({
mode: 'development',
cache: false,
...
plugins: [
new ModuleFederationPlugin({
name: 'layout',
filename: 'remoteEntry.js',
remotes: {
home: 'home@http://localhost:3002/remoteEntry.js',
},
exposes: {},
shared: {
vue: {
singleton: true,
},
},
}),
],
})
1.2.2.1.2 页面引入
const Content = defineAsyncComponent(() => import('home/Content'));
const Button = defineAsyncComponent(() => import('home/Button'));
1.2.2.2 生产者webpack配置
1.2.2.2.1 webpack构建配置
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = (env = {}) => ({
mode: 'development',
cache: false,
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new ModuleFederationPlugin({
name: 'home',
filename: 'remoteEntry.js',
remotes: {
home: 'home@http://localhost:3002/remoteEntry.js',
},
exposes: {
'./Content': './src/components/Content',
'./Button': './src/components/Button',
},
shared: {
vue: {
singleton: true,
},
},
}),
],
});
1.2.3 Runtime接入
webpack4 等项目中可直接使用纯运行时进行模块注册和加载。生产者还是用对应的构建插件进行配置,需要单独打包出remoteEntry.js入口文件1.2.3.1 核心API
1.2.3.1.1 Init
// 可以只使用运行时加载模块,而不依赖于构建插件
// 当不使用构建插件时,共享的依赖项不能自动设置细节
import { init, loadRemote } from '@module-federation/enhanced/runtime';
init({
name: '@demo/app-main',
remotes: [
{
name: "@demo/app1",
// mf-manifest.json 是在 Module federation 新版构建工具中生成的文件类型,对比 remoteEntry 提供了更丰富的功能
// 预加载功能依赖于使用 mf-manifest.json 文件类型
entry: "http://localhost:3005/mf-manifest.json",
alias: "app1"
},
{
name: "@demo/app2",
entry: "http://localhost:3006/remoteEntry.js",
alias: "app2"
},
],
});
// 使用别名加载
loadRemote<{add: (...args: Array<number>)=> number }>("app2/util").then((md)=>{
md.add(1,2,3);
});
1.2.3.1.2 loadRemote
import("remote name/expose")语法直接加载,并且构建插件会自动将其转换为loadRemote("remote name/expose")用法。import { init, loadRemote } from '@module-federation/enhanced/runtime';
init({
name: '@demo/main-app',
remotes: [
{
name: '@demo/app2',
alias: 'app2',
entry: 'http://localhost:3006/remoteEntry.js',
},
],
});
// remoteName + expose
loadRemote('@demo/app2/util').then((m) => m.add(1, 2, 3));
// alias + expose
loadRemote('app2/util').then((m) => m.add(1, 2, 3));
1.2.3.1.3 registerRemotes
function registerRemotes(remotes: Remote[], options?: { force?: boolean }) {}
type Remote = (RemoteWithEntry | RemoteWithVersion) & RemoteInfoCommon;
interface RemoteInfoCommon {
alias?: string;
shareScope?: string;
type?: RemoteEntryType;
entryGlobalName?: string;
}
interface RemoteWithEntry {
name: string;
entry: string;
}
interface RemoteWithVersion {
name: string;
version: string;
}
1.2.3.1.4 registerPlugins
import { registerPlugins } from '@module-federation/enhanced/runtime'
import runtimePlugin from 'custom-runtime-plugin.ts';
registerPlugins([runtimePlugin()]);
1.3 调试工具
1.3.1 安装Module Federation插件

1.3.2 插件提供了Devtools面板

1.3.3 查看远程依赖关系

2. 实战示例
介绍一下 简单的host-remote模式开发,及开发体验
2.1 项目目录
vue3-demo/
├── home(remote)
│ ├── src
│ │ ├── App.vue -- 入口组件 components: { Content: defineAsyncComponent(() => import('./components/Content')),
│ │ ├── components
│ │ │ ├── Button.js。 -- 业务组件Button
│ │ │ └── Content.vue -- 业务组件Content
│ │ ├── index.js. -- import('./main.js');
│ │ └── main.js -- const app = createApp(App);app.mount('#app');
│ └── webpack.config.js -- expose:{Content, Button}
│
├── layout(host)
│ ├── src
│ │ ├── Layout.vue -- 使用业务组件Content,
│ │ ├── index.js -- import('./main.js');
│ │ └── main.js -- const Content = defineAsyncComponent(() => import('home/Content'));
│ └── webpack.config.js -- remotes:{home: 'home@http://home.com/remoteEntry.js'}
└── package.json
2.2 核心代码块
2.2.1 Remote
2.2.1.1 src/index.js
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
import('./main.js');
2.2.1.2 src/main.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');
2.2.1.3 webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = (env = {}) => ({
target: 'web',
entry: path.resolve(__dirname, './src/index.js'),
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new ModuleFederationPlugin({
name: 'home',
filename: 'remoteEntry.js',
remotes: {
home: 'home@http://localhost:3002/remoteEntry.js',
},
exposes: {
'./Content': './src/components/Content',
'./Button': './src/components/Button',
},
shared: {
vue: {
singleton: true,
},
},
}),
],
devServer: {
port: 3002,
},
});
2.2.2 Host
2.2.2.1 src/index.js
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
import('./main.js');
2.2.2.2 src/main.js
import { createApp, defineAsyncComponent } from 'vue';
import Layout from './Layout.vue';
const Content = defineAsyncComponent(() => import('home/Content'));
const Button = defineAsyncComponent(() => import('home/Button'));
const app = createApp(Layout);
app.component('content-element', Content);
app.component('button-element', Button);
app.mount('#app');
2.2.2.3 wepback.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = (env = {}) => ({
entry: path.resolve(__dirname, './src/index.js'),
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new ModuleFederationPlugin({
name: 'layout',
filename: 'remoteEntry.js',
remotes: {
home: 'home@http://localhost:3002/remoteEntry.js',
},
exposes: {},
shared: {
vue: {
singleton: true,
},
},
}),
],
devServer: {
port: 3001,
},
});
2.3 示例截图

3. 原理分析
not magic, just async chunk
shared字段进行配置。3.1 webpack异步模块加载流程
3.1.1 按需加载
import 和 require.ensure 来引入需要动态导入的代码,还是用前面的vue3-demo示例,现在只关注home目录,并且把webpack配置中的ModuleFederationPlugin插件去掉。vue3-demo/
├── home(remote)
│ ├── src
│ │ ├── App.vue -- 入口组件 components: { Content: defineAsyncComponent(() => import('./components/Content')),
│ │ ├── components
│ │ │ ├── Button.js -- 业务组件Button
│ │ │ └── Content.vue -- 业务组件Content
│ │ ├── index.js. -- import('./main.js');
│ │ └── main.js -- const app = createApp(App);app.mount('#app');
│ └── webpack.config.js
components: {
Content: defineAsyncComponent(() => import('./components/Content')),
Button: defineAsyncComponent(() => import('./components/Button')),
},
3.1.2 初始化请求链路
3.1.3 源码与构建后代码对照
3.1.3.1 入口html文件
3.1.3.1.1 源码
<div id="app"></div>
3.1.3.1.2 构建后代码
<head>
<script defer src="main.js"></script>
</head>
<div id="app"></div>
3.1.3.2 入口index.js文件
3.1.3.2.1 源码
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
import('./main.js');
3.1.3.2.2 构建后代码
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
**********************/
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_pnpm_mini-css-extract-plugin_2_9_2_webpack_5_96_1__swc_core_1_9_2_webpac-fe6f3f"), __webpack_require__.e("src_main_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./main.js */ "./src/main.js"));
/***/ })
})
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId,
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };
/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); });
/******/ module = execOptions.module;
/******/ execOptions.factory.call(module.exports, module, module.exports, execOptions.require);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = __webpack_module_cache__;
/******/
/******/ // expose the module execution interceptor
/******/ __webpack_require__.i = [];
/******/
/************************************************************************/
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/get javascript chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".js";
/******/ };
/******/ })();
/******/
/******/
/******/ /* webpack/runtime/get mini-css chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.miniCssF = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".css";
/******/ };
/******/ })();
/******/
/******/
/******/
/******/ /* webpack/runtime/load script */
/******/ (() => {
/******/ var inProgress = {};
/******/ var dataWebpackPrefix = "vue3-demo_home:";
/******/ // loadScript function to load a script via script tag
/******/ __webpack_require__.l = (url, done, key, chunkId) => {
/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
/******/ var script, needAttach;
/******/ if(key !== undefined) {
/******/ var scripts = document.getElementsByTagName("script");
/******/ for(var i = 0; i < scripts.length; i++) {
/******/ var s = scripts[i];
/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }
/******/ }
/******/ }
/******/ if(!script) {
/******/ needAttach = true;
/******/ script = document.createElement('script');
/******/
/******/ script.charset = 'utf-8';
/******/ script.timeout = 120;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key);
/******/
/******/ script.src = url;
/******/ }
/******/ inProgress[url] = [done];
/******/ var onScriptComplete = (prev, event) => {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
/******/ clearTimeout(timeout);
/******/ var doneFns = inProgress[url];
/******/ delete inProgress[url];
/******/ script.parentNode && script.parentNode.removeChild(script);
/******/ doneFns && doneFns.forEach((fn) => (fn(event)));
/******/ if(prev) return prev(event);
/******/ }
/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
/******/ script.onload = onScriptComplete.bind(null, script.onload);
/******/ needAttach && document.head.appendChild(script);
/******/ };
/******/ })();
/******/
/******/
/******/
/******/ /* webpack/runtime/css loading */
/******/ (() => {
/******/ if (typeof document === "undefined") return;
/******/ var createStylesheet = (chunkId, fullhref, oldTag, resolve, reject) => {
/******/ var linkTag = document.createElement("link");
/******/
/******/ linkTag.rel = "stylesheet";
/******/ linkTag.type = "text/css";
/******/ if (__webpack_require__.nc) {
/******/ linkTag.nonce = __webpack_require__.nc;
/******/ }
/******/ var onLinkComplete = (event) => {
/******/ // avoid mem leaks.
/******/ linkTag.onerror = linkTag.onload = null;
/******/ if (event.type === 'load') {
/******/ resolve();
/******/ } else {
/******/ var errorType = event && event.type;
/******/ var realHref = event && event.target && event.target.href || fullhref;
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + errorType + ": " + realHref + ")");
/******/ err.name = "ChunkLoadError";
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
/******/ err.type = errorType;
/******/ err.request = realHref;
/******/ if (linkTag.parentNode) linkTag.parentNode.removeChild(linkTag)
/******/ reject(err);
/******/ }
/******/ }
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
/******/ linkTag.href = fullhref;
/******/
/******/
/******/ if (oldTag) {
/******/ oldTag.parentNode.insertBefore(linkTag, oldTag.nextSibling);
/******/ } else {
/******/ document.head.appendChild(linkTag);
/******/ }
/******/ return linkTag;
/******/ };
/******/ var findStylesheet = (href, fullhref) => {
/******/ var existingLinkTags = document.getElementsByTagName("link");
/******/ for(var i = 0; i < existingLinkTags.length; i++) {
/******/ var tag = existingLinkTags[i];
/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");
/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return tag;
/******/ }
/******/ var existingStyleTags = document.getElementsByTagName("style");
/******/ for(var i = 0; i < existingStyleTags.length; i++) {
/******/ var tag = existingStyleTags[i];
/******/ var dataHref = tag.getAttribute("data-href");
/******/ if(dataHref === href || dataHref === fullhref) return tag;
/******/ }
/******/ };
/******/ var loadStylesheet = (chunkId) => {
/******/ return new Promise((resolve, reject) => {
/******/ var href = __webpack_require__.miniCssF(chunkId);
/******/ var fullhref = __webpack_require__.p + href;
/******/ if(findStylesheet(href, fullhref)) return resolve();
/******/ createStylesheet(chunkId, fullhref, null, resolve, reject);
/******/ });
/******/ }
/******/ // object to store loaded CSS chunks
/******/ var installedCssChunks = {
/******/ "main": 0
/******/ };
/******/
/******/ __webpack_require__.f.miniCss = (chunkId, promises) => {
/******/ var cssChunks = {"src_main_js":1};
/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);
/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {
/******/ promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(() => {
/******/ installedCssChunks[chunkId] = 0;
/******/ }, (e) => {
/******/ delete installedCssChunks[chunkId];
/******/ throw e;
/******/ }));
/******/ }
/******/ };
/******/
/******/ var oldTags = [];
/******/ var newTags = [];
/******/ var applyHandler = (options) => {
/******/ return { dispose: () => {
/******/ for(var i = 0; i < oldTags.length; i++) {
/******/ var oldTag = oldTags[i];
/******/ if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);
/******/ }
/******/ oldTags.length = 0;
/******/ }, apply: () => {
/******/ for(var i = 0; i < newTags.length; i++) newTags[i].rel = "stylesheet";
/******/ newTags.length = 0;
/******/ } };
/******/ }
/******/ __webpack_require__.hmrC.miniCss = (chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList) => {
/******/ applyHandlers.push(applyHandler);
/******/ chunkIds.forEach((chunkId) => {
/******/ var href = __webpack_require__.miniCssF(chunkId);
/******/ var fullhref = __webpack_require__.p + href;
/******/ var oldTag = findStylesheet(href, fullhref);
/******/ if(!oldTag) return;
/******/ promises.push(new Promise((resolve, reject) => {
/******/ var tag = createStylesheet(chunkId, fullhref, oldTag, () => {
/******/ tag.as = "style";
/******/ tag.rel = "preload";
/******/ resolve();
/******/ }, reject);
/******/ oldTags.push(oldTag);
/******/ newTags.push(tag);
/******/ }));
/******/ });
/******/ }
/******/
/******/ // no prefetching
/******/
/******/ // no preloaded
/******/ })();
/******/
/******/ /* webpack/runtime/jsonp chunk loading */
/******/ (() => {
/******/ // no baseURI
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
/******/ var installedChunks = __webpack_require__.hmrS_jsonp = __webpack_require__.hmrS_jsonp || {
/******/ "main": 0
/******/ };
/******/
/******/ __webpack_require__.f.j = (chunkId, promises) => {
/******/ // JSONP chunk loading for javascript
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ if(true) { // all chunks have JS
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ var loadingEnded = (event) => {
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
/******/ installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
/******/ if(installedChunkData) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ installedChunkData[1](error);
/******/ }
/******/ }
/******/ };
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
/******/ }
/******/ }
/******/ }
/******/ };
/******/
/******/ // no prefetching
/******/
/******/
/******/
/******/
/******/ // install a JSONP callback for chunk loading
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0;
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
/******/ for(moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) var result = runtime(__webpack_require__);
/******/ }
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ installedChunks[chunkId][0]();
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/
/******/ }
/******/
/******/ var chunkLoadingGlobal = self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || [];
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // module cache are used so entry inlining is disabled
/******/ // startup
/******/ // Load entry module and return exports
/******/ __webpack_require__("../../node_modules/.pnpm/webpack-dev-server@5.0.4_webpack-cli@5.1.4_webpack@5.96.1/node_modules/webpack-dev-server/client/index.js?protocol=ws%3A&hostname=0.0.0.0&port=3002&pathname=%2Fws&logging=info&overlay=true&reconnect=10&hot=true&live-reload=true");
/******/ __webpack_require__("../../node_modules/.pnpm/webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4/node_modules/webpack/hot/dev-server.js");
/******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
/******/
/******/ })()
;
//# sourceMappingURL=main.js.map
3.1.3.3 main.js文件
3.1.3.3.1 源码
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');
3.1.3.3.2 构建后代码
"use strict";
(self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || []).push([["src_main_js"], {
/***/
"../../node_modules/.pnpm/mini-css-extract-plugin@2.9.2_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-2.use[0]!../../node_modules/.pnpm/css-loader@7.1.2_@rspack+core@1.1.1_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/css-loader/dist/cjs.js!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/stylePostLoader.js!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css": /*!*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ../../node_modules/.pnpm/mini-css-extract-plugin@2.9.2_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-2.use[0]!../../node_modules/.pnpm/css-loader@7.1.2_@rspack+core@1.1.1_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/css-loader/dist/cjs.js!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/stylePostLoader.js!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css ***!
*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/***/
( (module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
if (true) {
(function() {
var localsJsonString = undefined;
// 1758629789554
var cssReload = __webpack_require__(/*! ../../../node_modules/.pnpm/mini-css-extract-plugin@2.9.2_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/mini-css-extract-plugin/dist/hmr/hotModuleReplacement.js */
"../../node_modules/.pnpm/mini-css-extract-plugin@2.9.2_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/mini-css-extract-plugin/dist/hmr/hotModuleReplacement.js")(module.id, {});
// only invalidate when locals change
if (module.hot.data && module.hot.data.value && module.hot.data.value !== localsJsonString) {
module.hot.invalidate();
} else {
module.hot.accept();
}
module.hot.dispose(function(data) {
data.value = localsJsonString;
cssReload();
});
}
)();
}
/***/
}
),
/***/
"./src/App.vue": /*!*********************!*\
!*** ./src/App.vue ***!
*********************/
/***/
( (module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */
});
/* harmony import */
var _App_vue_vue_type_template_id_7ba5bd90_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./App.vue?vue&type=template&id=7ba5bd90&scoped=true */
"./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true");
/* harmony import */
var _App_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./App.vue?vue&type=script&lang=js */
"./src/App.vue?vue&type=script&lang=js");
/* harmony import */
var _App_vue_vue_type_style_index_0_id_7ba5bd90_scoped_true_lang_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css */
"./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css");
/* harmony import */
var _Users_liqi_fe_module_federation_examples_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/exportHelper.js */
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/exportHelper.js");
;
const __exports__ = /*#__PURE__*/
(0,
_Users_liqi_fe_module_federation_examples_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_3__["default"])(_App_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__["default"], [['render', _App_vue_vue_type_template_id_7ba5bd90_scoped_true__WEBPACK_IMPORTED_MODULE_0__.render], ['__scopeId', "data-v-7ba5bd90"], ['__file', "src/App.vue"]])
/* hot reload */
if (true) {
__exports__.__hmrId = "7ba5bd90"
const api = __VUE_HMR_RUNTIME__
module.hot.accept()
if (!api.createRecord('7ba5bd90', __exports__)) {
console.log('reload')
api.reload('7ba5bd90', __exports__)
}
module.hot.accept(/*! ./App.vue?vue&type=template&id=7ba5bd90&scoped=true */
"./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true", __WEBPACK_OUTDATED_DEPENDENCIES__ => {
/* harmony import */
_App_vue_vue_type_template_id_7ba5bd90_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./App.vue?vue&type=template&id=7ba5bd90&scoped=true */
"./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true");
( () => {
console.log('re-render')
api.rerender('7ba5bd90', _App_vue_vue_type_template_id_7ba5bd90_scoped_true__WEBPACK_IMPORTED_MODULE_0__.render)
}
)(__WEBPACK_OUTDATED_DEPENDENCIES__);
}
)
}
/* harmony default export */
const __WEBPACK_DEFAULT_EXPORT__ = (__exports__);
/***/
}
),
/***/
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=script&lang=js": /*!*****************************************************************************************************************************************************************************************************************************************************************!*\
!*** ../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=script&lang=js ***!
*****************************************************************************************************************************************************************************************************************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */
});
/* harmony import */
var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */
"../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js");
// import Content from "./components/Content";
// import Button from "./components/Button";
/* harmony default export */
const __WEBPACK_DEFAULT_EXPORT__ = ({
components: {
Content: (0,
vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)( () => __webpack_require__.e(/*! import() */
"src_components_Content_vue").then(__webpack_require__.bind(__webpack_require__, /*! ./components/Content */
"./src/components/Content.vue"))),
Button: (0,
vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)( () => __webpack_require__.e(/*! import() */
"src_components_Button_js").then(__webpack_require__.bind(__webpack_require__, /*! ./components/Button */
"./src/components/Button.js"))),
},
// components: {
// Content,
// Button,
// },
setup() {
const count = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0);
const inc = () => {
count.value++;
}
;
return {
count,
inc,
};
},
});
/***/
}
),
/***/
"./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css": /*!*****************************************************************************!*\
!*** ./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css ***!
*****************************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */
var _node_modules_pnpm_mini_css_extract_plugin_2_9_2_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_mini_css_extract_plugin_dist_loader_js_clonedRuleSet_2_use_0_node_modules_pnpm_css_loader_7_1_2_rspack_core_1_1_1_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_css_loader_dist_cjs_js_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_stylePostLoader_js_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_App_vue_vue_type_style_index_0_id_7ba5bd90_scoped_true_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/.pnpm/mini-css-extract-plugin@2.9.2_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-2.use[0]!../../../node_modules/.pnpm/css-loader@7.1.2_@rspack+core@1.1.1_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/css-loader/dist/cjs.js!../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/stylePostLoader.js!../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css */
"../../node_modules/.pnpm/mini-css-extract-plugin@2.9.2_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-2.use[0]!../../node_modules/.pnpm/css-loader@7.1.2_@rspack+core@1.1.1_webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/css-loader/dist/cjs.js!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/stylePostLoader.js!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css");
/***/
}
),
/***/
"./src/App.vue?vue&type=script&lang=js": /*!*********************************************!*\
!*** ./src/App.vue?vue&type=script&lang=js ***!
*********************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (/* reexport safe */
_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_App_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__["default"])/* harmony export */
});
/* harmony import */
var _node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_App_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./App.vue?vue&type=script&lang=js */
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=script&lang=js");
/***/
}
),
/***/
"./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true": /*!***************************************************************!*\
!*** ./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true ***!
***************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
render: () => (/* reexport safe */
_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_1_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_App_vue_vue_type_template_id_7ba5bd90_scoped_true__WEBPACK_IMPORTED_MODULE_0__.render)/* harmony export */
});
/* harmony import */
var _node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_1_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_App_vue_vue_type_template_id_7ba5bd90_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./App.vue?vue&type=template&id=7ba5bd90&scoped=true */
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true");
/***/
}
),
/***/
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true": /*!*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true ***!
*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
render: () => (/* binding */
render)/* harmony export */
});
/* harmony import */
var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */
"../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js");
const _withScopeId = n => ((0,
vue__WEBPACK_IMPORTED_MODULE_0__.pushScopeId)("data-v-7ba5bd90"),
n = n(),
(0,
vue__WEBPACK_IMPORTED_MODULE_0__.popScopeId)(),
n)
const _hoisted_1 = /*#__PURE__*/
_withScopeId( () => /*#__PURE__*/
(0,
vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "Main App", -1 /* HOISTED */
))
function render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_Content = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("Content")
const _component_Button = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("Button")
return ((0,
vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(),
(0,
vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", null, [_hoisted_1, (0,
vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Content), (0,
vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Button)]))
}
/***/
}
),
/***/
"./src/main.js": /*!*********************!*\
!*** ./src/main.js ***!
*********************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */
var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */
"../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js");
/* harmony import */
var _App_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./App.vue */
"./src/App.vue");
const app = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.createApp)(_App_vue__WEBPACK_IMPORTED_MODULE_1__["default"]);
app.mount('#app');
/***/
}
)
}]);
//# sourceMappingURL=src_main_js.js.map
3.1.3.4 button.js组件文件
3.1.3.4.1 源码
import { render, h } from 'vue';
const button = {
name: 'btn-component',
render() {
return h(
'button',
{
id: 'btn-primary',
},
'Hello World',
);
},
};
export default button;
3.1.3.4.2 构建后代码
"use strict";
(self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || []).push([["src_components_Button_js"],{
/***/ "./src/components/Button.js":
/*!**********************************!*\
!*** ./src/components/Button.js ***!
**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js");
const button = {
name: 'btn-component',
render() {
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.h)(
'button',
{
id: 'btn-primary',
},
'Hello World',
);
},
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (button);
/***/ })
}]);
//# sourceMappingURL=src_components_Button_js.js.map
3.1.3.5 Content.vue组件文件
3.1.3.5.1 源码
<template>
<div style="color: red">{{ title }}</div>
</template>
<script>
export default {
data() {
return {
title: 'Remote Component in Action..',
};
},
};
</script>
3.1.3.5.2 构建后代码
"use strict";
(self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || []).push([["src_components_Content_vue"], {
/***/
"./src/components/Content.vue": /*!************************************!*\
!*** ./src/components/Content.vue ***!
************************************/
/***/
( (module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */
});
/* harmony import */
var _Content_vue_vue_type_template_id_7eab81f9__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Content.vue?vue&type=template&id=7eab81f9 */
"./src/components/Content.vue?vue&type=template&id=7eab81f9");
/* harmony import */
var _Content_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Content.vue?vue&type=script&lang=js */
"./src/components/Content.vue?vue&type=script&lang=js");
/* harmony import */
var _Users_liqi_fe_module_federation_examples_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/exportHelper.js */
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/exportHelper.js");
;const __exports__ = /*#__PURE__*/
(0,
_Users_liqi_fe_module_federation_examples_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__["default"])(_Content_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__["default"], [['render', _Content_vue_vue_type_template_id_7eab81f9__WEBPACK_IMPORTED_MODULE_0__.render], ['__file', "src/components/Content.vue"]])
/* hot reload */
if (true) {
__exports__.__hmrId = "7eab81f9"
const api = __VUE_HMR_RUNTIME__
module.hot.accept()
if (!api.createRecord('7eab81f9', __exports__)) {
console.log('reload')
api.reload('7eab81f9', __exports__)
}
module.hot.accept(/*! ./Content.vue?vue&type=template&id=7eab81f9 */
"./src/components/Content.vue?vue&type=template&id=7eab81f9", __WEBPACK_OUTDATED_DEPENDENCIES__ => {
/* harmony import */
_Content_vue_vue_type_template_id_7eab81f9__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Content.vue?vue&type=template&id=7eab81f9 */
"./src/components/Content.vue?vue&type=template&id=7eab81f9");
( () => {
console.log('re-render')
api.rerender('7eab81f9', _Content_vue_vue_type_template_id_7eab81f9__WEBPACK_IMPORTED_MODULE_0__.render)
}
)(__WEBPACK_OUTDATED_DEPENDENCIES__);
}
)
}
/* harmony default export */
const __WEBPACK_DEFAULT_EXPORT__ = (__exports__);
/***/
}
),
/***/
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/components/Content.vue?vue&type=script&lang=js": /*!********************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/components/Content.vue?vue&type=script&lang=js ***!
********************************************************************************************************************************************************************************************************************************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */
});
/* harmony default export */
const __WEBPACK_DEFAULT_EXPORT__ = ({
data() {
return {
title: 'Remote Component in Action..',
};
},
});
/***/
}
),
/***/
"./src/components/Content.vue?vue&type=script&lang=js": /*!************************************************************!*\
!*** ./src/components/Content.vue?vue&type=script&lang=js ***!
************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (/* reexport safe */
_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_Content_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__["default"])/* harmony export */
});
/* harmony import */
var _node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_Content_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./Content.vue?vue&type=script&lang=js */
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/components/Content.vue?vue&type=script&lang=js");
/***/
}
),
/***/
"./src/components/Content.vue?vue&type=template&id=7eab81f9": /*!******************************************************************!*\
!*** ./src/components/Content.vue?vue&type=template&id=7eab81f9 ***!
******************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
render: () => (/* reexport safe */
_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_1_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_Content_vue_vue_type_template_id_7eab81f9__WEBPACK_IMPORTED_MODULE_0__.render)/* harmony export */
});
/* harmony import */
var _node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_1_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_index_js_ruleSet_1_rules_4_use_0_Content_vue_vue_type_template_id_7eab81f9__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./Content.vue?vue&type=template&id=7eab81f9 */
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/components/Content.vue?vue&type=template&id=7eab81f9");
/***/
}
),
/***/
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/components/Content.vue?vue&type=template&id=7eab81f9": /*!************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/index.js??ruleSet[1].rules[4].use[0]!./src/components/Content.vue?vue&type=template&id=7eab81f9 ***!
************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
render: () => (/* binding */
render)/* harmony export */
});
/* harmony import */
var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */
"../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js");
const _hoisted_1 = {
style: {
"color": "red"
}
}
function render(_ctx, _cache, $props, $setup, $data, $options) {
return ((0,
vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(),
(0,
vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, (0,
vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.title), 1 /* TEXT */
))
}
/***/
}
)
}]);
//# sourceMappingURL=src_components_Content_vue.js.map
3.1.4 过程解析
3.1.4.1 webpack\_require("./src/index.js")
import('./main.js');
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
**********************/
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_pnpm_mini-css-extract-plugin_2_9_2_webpack_5_96_1__swc_core_1_9_2_webpac-fe6f3f"), __webpack_require__.e("src_main_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./main.js */ "./src/main.js"));
/***/ })
})
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId,
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };
/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); });
/******/ module = execOptions.module;
/******/ execOptions.factory.call(module.exports, module, module.exports, execOptions.require);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = __webpack_module_cache__;
/******/
/******/ // expose the module execution interceptor
/******/ __webpack_require__.i = [];
/******/
/************************************************************************/
/******/ // module cache are used so entry inlining is disabled
/******/ // startup
/******/ // Load entry module and return exports
/******/ __webpack_require__("../../node_modules/.pnpm/webpack-dev-server@5.0.4_webpack-cli@5.1.4_webpack@5.96.1/node_modules/webpack-dev-server/client/index.js?protocol=ws%3A&hostname=0.0.0.0&port=3002&pathname=%2Fws&logging=info&overlay=true&reconnect=10&hot=true&live-reload=true");
/******/ __webpack_require__("../../node_modules/.pnpm/webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4/node_modules/webpack/hot/dev-server.js");
/******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
/******/
/******/ })()
;
*/ var __webpack_exports__ = __webpack_require__("./src/index.js");
./src/index.js的模块,没有缓存,则创建一个新的模块数据结构,并放到\_\_webpack\_module\_cache\_\_变量里面, /******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // 先从__webpack_module_cache__缓存变量中获取moduleId为./src/index.js的模块
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // 没有缓存,则创建一个新的模块数据结构,并放到__webpack_module_cache__变量里面
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId,
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };
/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); });
/******/ module = execOptions.module;
/******/ execOptions.factory.call(module.exports, module, module.exports, execOptions.require);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
3.1.4.2 webpack\_modules
/******/ var __webpack_modules__ = ({
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
**********************/
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
Promise.all(/*! import() */
[
__webpack_require__.e("vendors-node_modules_pnpm_mini-css-extract-plugin_2_9_2_webpack_5_96_1__swc_core_1_9_2_webpac-fe6f3f"),
__webpack_require__.e("src_main_js")]
).then(
__webpack_require__.bind(__webpack_require__, /*! ./main.js */ "./src/main.js")
);
/***/ })
})
import('./main.js'); 异步加载main.js模块,转化成了 __webpack_require__.e("src_main_js") 。__webpack_require__.bind(__webpack_require__, /*! ./main.js */ "./src/main.js")"./src/index.js",都是用__webpack_require__函数。3.1.4.3 webpack\_require.e
__webpack_require__.e是如何实现,其实从前面的index.js加载过程,大致可以推测一下,它主要任务有两个__webpack_modules__变量中找到./src/main.js的具体实现。__webpack_modules__变量上面。就是最大的疑问。
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();__webpack_require__.f = {
miniCss: (chunkId, promises) => {
/******/ var cssChunks = {"90":1};
/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);
/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {
/******/ promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(() => {
/******/ installedCssChunks[chunkId] = 0;
/******/ }, (e) => {
/******/ delete installedCssChunks[chunkId];
/******/ throw e;
/******/ }));
/******/ }
/******/ };
/******/ j: (chunkId, promises) => {
/******/ // JSONP chunk loading for javascript
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ if(true) { // all chunks have JS
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ var loadingEnded = (event) => {
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
/******/ installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
/******/ if(installedChunkData) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ installedChunkData[1](error);
/******/ }
/******/ }
/******/ };
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
/******/ }
/******/ }
/******/ }
/******/ };
}
__webpack_require__.l,里面主要功能也是通过动态创建script标签,异步加载./src/main.js文件/******/ /* webpack/runtime/load script */
/******/ (() => {
/******/ var inProgress = {};
/******/ var dataWebpackPrefix = "vue3-demo_home:";
/******/ // loadScript function to load a script via script tag
/******/ __webpack_require__.l = (url, done, key, chunkId) => {
...
/******/ needAttach = true;
/******/ script = document.createElement('script');
/******/
/******/ script.charset = 'utf-8';
/******/ script.timeout = 120;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key);
/******/
/******/ script.src = url;
/******/
/******/ inProgress[url] = [done];
/******/ var onScriptComplete = (prev, event) => {
....
/******/ }
/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
/******/ script.onload = onScriptComplete.bind(null, script.onload);
/******/ };
/******/ })();
3.1.4.4 ./src/main.js
./src/main.js 文件加载并执行完成有什么效果。"use strict";
(self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || []).push([["src_main_js"], {
/***/
"./src/App.vue": /*!*********************!*\
!*** ./src/App.vue ***!
*********************/
/***/
( (module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */
});
/* harmony import */
var _App_vue_vue_type_template_id_7ba5bd90_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./App.vue?vue&type=template&id=7ba5bd90&scoped=true */
"./src/App.vue?vue&type=template&id=7ba5bd90&scoped=true");
/* harmony import */
var _App_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./App.vue?vue&type=script&lang=js */
"./src/App.vue?vue&type=script&lang=js");
/* harmony import */
var _App_vue_vue_type_style_index_0_id_7ba5bd90_scoped_true_lang_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css */
"./src/App.vue?vue&type=style&index=0&id=7ba5bd90&scoped=true&lang=css");
/* harmony import */
var _Users_liqi_fe_module_federation_examples_node_modules_pnpm_vue_loader_16_8_3_vue_compiler_sfc_3_4_31_vue_3_3_7_typescript_5_6_3_webpack_5_96_1_swc_core_1_9_2_webpack_cli_5_1_4_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/exportHelper.js */
"../../node_modules/.pnpm/vue-loader@16.8.3_@vue+compiler-sfc@3.4.31_vue@3.3.7_typescript@5.6.3__webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4_/node_modules/vue-loader/dist/exportHelper.js");
;
/* harmony default export */
const __WEBPACK_DEFAULT_EXPORT__ = (__exports__);
/***/
}
),
/***/
"./src/main.js": /*!*********************!*\
!*** ./src/main.js ***!
*********************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */
var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */
"../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js");
/* harmony import */
var _App_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./App.vue */
"./src/App.vue");
const app = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.createApp)(_App_vue__WEBPACK_IMPORTED_MODULE_1__["default"]);
app.mount('#app');
/***/
}
)
}]);
__webpack_modules__变量结构很类似,key对应moduleid, value对应具体代码实现。self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || []).push([["src_main_js"], {
{key}: {value}
}])
3.1.4.5 self["webpackChunkvue3\_demo\_home"].push = webpackJsonpCallback
// install a JSONP callback for chunk loading
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0;
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
/******/ for(moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) var result = runtime(__webpack_require__);
/******/ }
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ installedChunks[chunkId][0]();
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/
/******/ }
/******/
/******/ var chunkLoadingGlobal = self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || [];
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
/******/ })();
3.1.5 整体组件加载执行过程

3.2 Module Federation模块加载流程
module federation加载流程跟异步加载主流程保持不变,额外引入了remote、resumes处理方法,所以需要先看完webpack按需加载到流程
3.2.1 概述
src/index.jsvue3-demo/
├── layout(host)
│ ├── src
│ │ ├── Layout.vue -- 使用业务组件Content,
│ │ ├── index.js -- import('./main.js');
│ │ └── main.js -- const Content = defineAsyncComponent(() => import('home/Content'));
│ └── webpack.config.js -- remotes:{home: 'home@http://home.com/remoteEntry.js'}
└── package.json
3.2.2 初始化请求链路
3.2.3 源码与构建后代码对照
3.2.3.1 入口html文件
3.2.3.1.1 源码
<div id="app"></div>
3.2.3.1.2 构建后代码
<head><script defer src="main.js"></script></head><div id="app"></div>
3.2.3.2 入口index.js文件
3.2.3.2.1 源码
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
import('./main.js');
3.2.3.2.2 构建后代码
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
**********************/
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
// https://webpack.js.org/concepts/module-federation/#uncaught-error-shared-module-is-not-available-for-eager-consumption
__webpack_require__.e(/*! import() */ "src_main_js").then(__webpack_require__.bind(__webpack_require__, /*! ./main.js */ "./src/main.js"));
/***/ }),
/***/ "webpack/container/reference/home":
/*!************************************************************!*\
!*** external "home@http://localhost:3002/remoteEntry.js" ***!
************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
var __webpack_error__ = new Error();
module.exports = new Promise((resolve, reject) => {
if(typeof home !== "undefined") return resolve();
__webpack_require__.l("http://localhost:3002/remoteEntry.js", (event) => {
if(typeof home !== "undefined") return resolve();
var errorType = event && (event.type === 'load' ? 'missing' : event.type);
var realSrc = event && event.target && event.target.src;
__webpack_error__.message = 'Loading script failed.\n(' + errorType + ': ' + realSrc + ')';
__webpack_error__.name = 'ScriptExternalLoadError';
__webpack_error__.type = errorType;
__webpack_error__.request = realSrc;
reject(__webpack_error__);
}, "home");
}).then(() => (home));
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId,
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };
/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); });
/******/ module = execOptions.module;
/******/ execOptions.factory.call(module.exports, module, module.exports, execOptions.require);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = __webpack_module_cache__;
/******/
/******/ // expose the module execution interceptor
/******/ __webpack_require__.i = [];
/******/
/******/
/******/
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/
/******/
/******/ /* webpack/runtime/get mini-css chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.miniCssF = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "" + chunkId + ".css";
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/remotes loading */
/******/ (() => {
/******/ var chunkMapping = {
/******/ "webpack_container_remote_home_Content": [
/******/ "webpack/container/remote/home/Content"
/******/ ],
/******/ "webpack_container_remote_home_Button": [
/******/ "webpack/container/remote/home/Button"
/******/ ]
/******/ };
/******/ var idToExternalAndNameMapping = {
/******/ "webpack/container/remote/home/Content": [
/******/ "default",
/******/ "./Content",
/******/ "webpack/container/reference/home"
/******/ ],
/******/ "webpack/container/remote/home/Button": [
/******/ "default",
/******/ "./Button",
/******/ "webpack/container/reference/home"
/******/ ]
/******/ };
/******/ __webpack_require__.f.remotes = (chunkId, promises) => {
/******/ if(__webpack_require__.o(chunkMapping, chunkId)) {
/******/ chunkMapping[chunkId].forEach((id) => {
/******/ var getScope = __webpack_require__.R;
/******/ if(!getScope) getScope = [];
/******/ var data = idToExternalAndNameMapping[id];
/******/ if(getScope.indexOf(data) >= 0) return;
/******/ getScope.push(data);
/******/ if(data.p) return promises.push(data.p);
/******/ var onError = (error) => {
/******/ if(!error) error = new Error("Container missing");
/******/ if(typeof error.message === "string")
/******/ error.message += '\nwhile loading "' + data[1] + '" from ' + data[2];
/******/ __webpack_require__.m[id] = () => {
/******/ throw error;
/******/ }
/******/ data.p = 0;
/******/ };
/******/ var handleFunction = (fn, arg1, arg2, d, next, first) => {
/******/ try {
/******/ var promise = fn(arg1, arg2);
/******/ if(promise && promise.then) {
/******/ var p = promise.then((result) => (next(result, d)), onError);
/******/ if(first) promises.push(data.p = p); else return p;
/******/ } else {
/******/ return next(promise, d, first);
/******/ }
/******/ } catch(error) {
/******/ onError(error);
/******/ }
/******/ }
/******/ var onExternal = (external, _, first) => (external ? handleFunction(__webpack_require__.I, data[0], 0, external, onInitialized, first) : onError());
/******/ var onInitialized = (_, external, first) => (handleFunction(external.get, data[1], getScope, 0, onFactory, first));
/******/ var onFactory = (factory) => {
/******/ data.p = 1;
/******/ __webpack_require__.m[id] = (module) => {
/******/ module.exports = factory();
/******/ }
/******/ };
/******/ handleFunction(__webpack_require__, data[2], 0, 0, onExternal, 1);
/******/ });
/******/ }
/******/ }
/******/ })();
/******/
/******/ /* webpack/runtime/sharing */
/******/ (() => {
/******/ __webpack_require__.S = {};
/******/ var initPromises = {};
/******/ var initTokens = {};
/******/ __webpack_require__.I = (name, initScope) => {
/******/ if(!initScope) initScope = [];
/******/ // handling circular init calls
/******/ var initToken = initTokens[name];
/******/ if(!initToken) initToken = initTokens[name] = {};
/******/ if(initScope.indexOf(initToken) >= 0) return;
/******/ initScope.push(initToken);
/******/ // only runs once
/******/ if(initPromises[name]) return initPromises[name];
/******/ // creates a new share scope if needed
/******/ if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {};
/******/ // runs all init snippets from all modules reachable
/******/ var scope = __webpack_require__.S[name];
/******/ var warn = (msg) => {
/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg);
/******/ };
/******/ var uniqueName = "vue3-demo_layout";
/******/ var register = (name, version, factory, eager) => {
/******/ var versions = scope[name] = scope[name] || {};
/******/ var activeVersion = versions[version];
/******/ if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };
/******/ };
/******/ var initExternal = (id) => {
/******/ var handleError = (err) => (warn("Initialization of sharing external failed: " + err));
/******/ try {
/******/ var module = __webpack_require__(id);
/******/ if(!module) return;
/******/ var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope))
/******/ if(module.then) return promises.push(module.then(initFn, handleError));
/******/ var initResult = initFn(module);
/******/ if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));
/******/ } catch(err) { handleError(err); }
/******/ }
/******/ var promises = [];
/******/ switch(name) {
/******/ case "default": {
/******/ register("vue", "3.3.7", () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! ../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js"))))));
/******/ initExternal("webpack/container/reference/home");
/******/ }
/******/ break;
/******/ }
/******/ if(!promises.length) return initPromises[name] = 1;
/******/ return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/consumes */
/******/ (() => {
/******/ var parseVersion = (str) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ var p=p=>{return p.split(".").map((p=>{return+p==p?+p:p}))},n=/^([^-+]+)?(?:-([^+]+))?(?:+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r;
/******/ }
/******/ var versionLt = (a, b) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ a=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r<b.length&&"u"!=(typeof b[r])[0];var e=a[r],n=(typeof e)[0];if(r>=b.length)return"u"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return"o"==n&&"n"==f||("s"==f||"u"==n);if("o"!=n&&"u"!=n&&e!=t)return e<t;r++}
/******/ }
/******/ var rangeToString = (range) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ var r=range[0],n="";if(1===range.length)return"*";if(r+.5){n+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a<range.length;a++){e--,n+="u"==(typeof(t=range[a]))[0]?"-":(e>0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a<range.length;a++){var t=range[a];g.push(0===t?"not("+o()+")":1===t?"("+o()+" || "+o()+")":2===t?g.pop()+" "+g.pop():rangeToString(t))}return o();function o(){return g.pop().replace(/^((.+))$/,"$1")}
/******/ }
/******/ var satisfy = (range, version) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ if(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i<range.length?(typeof range[i])[0]:"";if(n>=version.length||"o"==(s=(typeof(f=version[n]))[0]))return!a||("u"==g?i>e&&!r:""==g!=r);if("u"==s){if(!a||"u"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f<range[i])return!1;f!=range[i]&&(a=!1)}else if("s"!=g&&"n"!=g){if(r||i<=e)return!1;a=!1,i--}else{if(i<=e||s<g!=r)return!1;a=!1}else"s"!=g&&"n"!=g&&(a=!1,i--)}}var t=[],o=t.pop.bind(t);for(n=1;n<range.length;n++){var u=range[n];t.push(1==u?o()|o():2==u?o()&o():u?satisfy(u,version):!o())}return!!o();
/******/ }
/******/ var exists = (scope, key) => {
/******/ return scope && __webpack_require__.o(scope, key);
/******/ }
/******/ var get = (entry) => {
/******/ entry.loaded = 1;
/******/ return entry.get()
/******/ };
/******/ var eagerOnly = (versions) => {
/******/ return Object.keys(versions).reduce((filtered, version) => {
/******/ if (versions[version].eager) {
/******/ filtered[version] = versions[version];
/******/ }
/******/ return filtered;
/******/ }, {});
/******/ };
/******/ var findLatestVersion = (scope, key, eager) => {
/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key];
/******/ var key = Object.keys(versions).reduce((a, b) => {
/******/ return !a || versionLt(a, b) ? b : a;
/******/ }, 0);
/******/ return key && versions[key];
/******/ };
/******/ var findSatisfyingVersion = (scope, key, requiredVersion, eager) => {
/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key];
/******/ var key = Object.keys(versions).reduce((a, b) => {
/******/ if (!satisfy(requiredVersion, b)) return a;
/******/ return !a || versionLt(a, b) ? b : a;
/******/ }, 0);
/******/ return key && versions[key]
/******/ };
/******/ var findSingletonVersionKey = (scope, key, eager) => {
/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key];
/******/ return Object.keys(versions).reduce((a, b) => {
/******/ return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;
/******/ }, 0);
/******/ };
/******/ var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => {
/******/ return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"
/******/ };
/******/ var getInvalidVersionMessage = (scope, scopeName, key, requiredVersion, eager) => {
/******/ var versions = scope[key];
/******/ return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\n" +
/******/ "Available versions: " + Object.keys(versions).map((key) => {
/******/ return key + " from " + versions[key].from;
/******/ }).join(", ");
/******/ };
/******/ var fail = (msg) => {
/******/ throw new Error(msg);
/******/ }
/******/ var failAsNotExist = (scopeName, key) => {
/******/ return fail("Shared module " + key + " doesn't exist in shared scope " + scopeName);
/******/ }
/******/ var warn = /*#__PURE__*/ (msg) => {
/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg);
/******/ };
/******/ var init = (fn) => (function(scopeName, key, eager, c, d) {
/******/ var promise = __webpack_require__.I(scopeName);
/******/ if (promise && promise.then && !eager) {
/******/ return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], key, false, c, d));
/******/ }
/******/ return fn(scopeName, __webpack_require__.S[scopeName], key, eager, c, d);
/******/ });
/******/
/******/ var useFallback = (scopeName, key, fallback) => {
/******/ return fallback ? fallback() : failAsNotExist(scopeName, key);
/******/ }
/******/ var load = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ return get(findLatestVersion(scope, key, eager));
/******/ });
/******/ var loadVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);
/******/ if (satisfyingVersion) return get(satisfyingVersion);
/******/ warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))
/******/ return get(findLatestVersion(scope, key, eager));
/******/ });
/******/ var loadStrictVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);
/******/ if (satisfyingVersion) return get(satisfyingVersion);
/******/ if (fallback) return fallback();
/******/ fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));
/******/ });
/******/ var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var version = findSingletonVersionKey(scope, key, eager);
/******/ return get(scope[key][version]);
/******/ });
/******/ var loadSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var version = findSingletonVersionKey(scope, key, eager);
/******/ if (!satisfy(requiredVersion, version)) {
/******/ warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));
/******/ }
/******/ return get(scope[key][version]);
/******/ });
/******/ var loadStrictSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var version = findSingletonVersionKey(scope, key, eager);
/******/ if (!satisfy(requiredVersion, version)) {
/******/ fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));
/******/ }
/******/ return get(scope[key][version]);
/******/ });
/******/ var installedModules = {};
/******/ var moduleToHandlerMapping = {
/******/ "webpack/sharing/consume/default/vue/vue": () => (loadSingletonVersion("default", "vue", false, [1,3,0,11], () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! vue */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js")))))))
/******/ };
/******/ // no consumes in initial chunks
/******/ var chunkMapping = {
/******/ "src_main_js": [
/******/ "webpack/sharing/consume/default/vue/vue"
/******/ ]
/******/ };
/******/ var startedInstallModules = {};
/******/ __webpack_require__.f.consumes = (chunkId, promises) => {
/******/ if(__webpack_require__.o(chunkMapping, chunkId)) {
/******/ chunkMapping[chunkId].forEach((id) => {
/******/ if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);
/******/ if(!startedInstallModules[id]) {
/******/ var onFactory = (factory) => {
/******/ installedModules[id] = 0;
/******/ __webpack_require__.m[id] = (module) => {
/******/ delete __webpack_require__.c[id];
/******/ module.exports = factory();
/******/ }
/******/ };
/******/ startedInstallModules[id] = true;
/******/ var onError = (error) => {
/******/ delete installedModules[id];
/******/ __webpack_require__.m[id] = (module) => {
/******/ delete __webpack_require__.c[id];
/******/ throw error;
/******/ }
/******/ };
/******/ try {
/******/ var promise = moduleToHandlerMapping[id]();
/******/ if(promise.then) {
/******/ promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));
/******/ } else onFactory(promise);
/******/ } catch(e) { onError(e); }
/******/ }
/******/ });
/******/ }
/******/ }
/******/ })();
/******/
/******/ /* webpack/runtime/css loading */
/******/ (() => {
/******/ if (typeof document === "undefined") return;
/******/ var createStylesheet = (chunkId, fullhref, oldTag, resolve, reject) => {
/******/ var linkTag = document.createElement("link");
/******/
/******/ linkTag.rel = "stylesheet";
/******/ linkTag.type = "text/css";
/******/ if (__webpack_require__.nc) {
/******/ linkTag.nonce = __webpack_require__.nc;
/******/ }
/******/ var onLinkComplete = (event) => {
/******/ // avoid mem leaks.
/******/ linkTag.onerror = linkTag.onload = null;
/******/ if (event.type === 'load') {
/******/ resolve();
/******/ } else {
/******/ var errorType = event && event.type;
/******/ var realHref = event && event.target && event.target.href || fullhref;
/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + errorType + ": " + realHref + ")");
/******/ err.name = "ChunkLoadError";
/******/ err.code = "CSS_CHUNK_LOAD_FAILED";
/******/ err.type = errorType;
/******/ err.request = realHref;
/******/ if (linkTag.parentNode) linkTag.parentNode.removeChild(linkTag)
/******/ reject(err);
/******/ }
/******/ }
/******/ linkTag.onerror = linkTag.onload = onLinkComplete;
/******/ linkTag.href = fullhref;
/******/
/******/
/******/ if (oldTag) {
/******/ oldTag.parentNode.insertBefore(linkTag, oldTag.nextSibling);
/******/ } else {
/******/ document.head.appendChild(linkTag);
/******/ }
/******/ return linkTag;
/******/ };
/******/ var findStylesheet = (href, fullhref) => {
/******/ var existingLinkTags = document.getElementsByTagName("link");
/******/ for(var i = 0; i < existingLinkTags.length; i++) {
/******/ var tag = existingLinkTags[i];
/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");
/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return tag;
/******/ }
/******/ var existingStyleTags = document.getElementsByTagName("style");
/******/ for(var i = 0; i < existingStyleTags.length; i++) {
/******/ var tag = existingStyleTags[i];
/******/ var dataHref = tag.getAttribute("data-href");
/******/ if(dataHref === href || dataHref === fullhref) return tag;
/******/ }
/******/ };
/******/ var loadStylesheet = (chunkId) => {
/******/ return new Promise((resolve, reject) => {
/******/ var href = __webpack_require__.miniCssF(chunkId);
/******/ var fullhref = __webpack_require__.p + href;
/******/ if(findStylesheet(href, fullhref)) return resolve();
/******/ createStylesheet(chunkId, fullhref, null, resolve, reject);
/******/ });
/******/ }
/******/ // object to store loaded CSS chunks
/******/ var installedCssChunks = {
/******/ "main": 0
/******/ };
/******/
/******/ __webpack_require__.f.miniCss = (chunkId, promises) => {
/******/ var cssChunks = {"src_main_js":1};
/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);
/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {
/******/ promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(() => {
/******/ installedCssChunks[chunkId] = 0;
/******/ }, (e) => {
/******/ delete installedCssChunks[chunkId];
/******/ throw e;
/******/ }));
/******/ }
/******/ };
/******/
/******/ var oldTags = [];
/******/ var newTags = [];
/******/ var applyHandler = (options) => {
/******/ return { dispose: () => {
/******/ for(var i = 0; i < oldTags.length; i++) {
/******/ var oldTag = oldTags[i];
/******/ if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);
/******/ }
/******/ oldTags.length = 0;
/******/ }, apply: () => {
/******/ for(var i = 0; i < newTags.length; i++) newTags[i].rel = "stylesheet";
/******/ newTags.length = 0;
/******/ } };
/******/ }
/******/ __webpack_require__.hmrC.miniCss = (chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList) => {
/******/ applyHandlers.push(applyHandler);
/******/ chunkIds.forEach((chunkId) => {
/******/ var href = __webpack_require__.miniCssF(chunkId);
/******/ var fullhref = __webpack_require__.p + href;
/******/ var oldTag = findStylesheet(href, fullhref);
/******/ if(!oldTag) return;
/******/ promises.push(new Promise((resolve, reject) => {
/******/ var tag = createStylesheet(chunkId, fullhref, oldTag, () => {
/******/ tag.as = "style";
/******/ tag.rel = "preload";
/******/ resolve();
/******/ }, reject);
/******/ oldTags.push(oldTag);
/******/ newTags.push(tag);
/******/ }));
/******/ });
/******/ }
/******/
/******/ // no prefetching
/******/
/******/ // no preloaded
/******/ })();
/******/
/******/ /* webpack/runtime/jsonp chunk loading */
/******/ (() => {
/******/ // no baseURI
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
/******/ var installedChunks = __webpack_require__.hmrS_jsonp = __webpack_require__.hmrS_jsonp || {
/******/ "main": 0
/******/ };
/******/
/******/ __webpack_require__.f.j = (chunkId, promises) => {
/******/ // JSONP chunk loading for javascript
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ if(!/^webpack_container_remote_home_(Button|Content)$/.test(chunkId)) {
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ var loadingEnded = (event) => {
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
/******/ installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
/******/ if(installedChunkData) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ installedChunkData[1](error);
/******/ }
/******/ }
/******/ };
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
/******/ } else installedChunks[chunkId] = 0;
/******/ }
/******/ }
/******/ };
/******/
/******/ // no prefetching
/******/
/******/ // no preloaded
/******/
/******/
/******/ self["webpackHotUpdatevue3_demo_layout"] = (chunkId, moreModules, runtime) => {
/******/ for(var moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ currentUpdate[moduleId] = moreModules[moduleId];
/******/ if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);
/******/ }
/******/ }
/******/ if(runtime) currentUpdateRuntime.push(runtime);
/******/ if(waitingUpdateResolves[chunkId]) {
/******/ waitingUpdateResolves[chunkId]();
/******/ waitingUpdateResolves[chunkId] = undefined;
/******/ }
/******/ };
/******/
/******/
/******/ // no on chunks loaded
/******/
/******/ // install a JSONP callback for chunk loading
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0;
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
/******/ for(moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) var result = runtime(__webpack_require__);
/******/ }
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ installedChunks[chunkId][0]();
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/
/******/ }
/******/
/******/ var chunkLoadingGlobal = self["webpackChunkvue3_demo_layout"] = self["webpackChunkvue3_demo_layout"] || [];
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
/******/ })();
/******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
/******/
/******/ })()
;
3.2.3.3 remoteEntry.js文件
var home;
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "webpack/container/entry/home":
/*!***********************!*\
!*** container entry ***!
***********************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var moduleMap = {
"./Content": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Content_vue-_cddc0")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Content */ "./src/components/Content.vue")))));
},
"./Button": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Button_js")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Button */ "./src/components/Button.js")))));
}
};
var get = (module, getScope) => {
__webpack_require__.R = getScope;
getScope = (
__webpack_require__.o(moduleMap, module)
? moduleMap[module]()
: Promise.resolve().then(() => {
throw new Error('Module "' + module + '" does not exist in container.');
})
);
__webpack_require__.R = undefined;
return getScope;
};
var init = (shareScope, initScope) => {
if (!__webpack_require__.S) return;
var name = "default"
var oldScope = __webpack_require__.S[name];
if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");
__webpack_require__.S[name] = shareScope;
return __webpack_require__.I(name, initScope);
};
// This exports getters to disallow modifications
__webpack_require__.d(exports, {
get: () => (get),
init: () => (init)
});
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };
/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); });
/******/ module = execOptions.module;
/******/ execOptions.factory.call(module.exports, module, module.exports, execOptions.require);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = __webpack_modules__;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = __webpack_module_cache__;
/******/
/******/ // expose the module execution interceptor
/******/ __webpack_require__.i = [];
/******/
/******/
/******/ /* webpack/runtime/ensure chunk */
/******/ (() => {
/******/ __webpack_require__.f = {};
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = (chunkId) => {
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ __webpack_require__.f[key](chunkId, promises);
/******/ return promises;
/******/ }, []));
/******/ };
/******/ })();
/******/
/******/
/******/
/******/ /* webpack/runtime/get mini-css chunk filename */
/******/ (() => {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.miniCssF = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return undefined;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/load script */
/******/ (() => {
/******/ var inProgress = {};
/******/ var dataWebpackPrefix = "vue3-demo_home:";
/******/ // loadScript function to load a script via script tag
/******/ __webpack_require__.l = (url, done, key, chunkId) => {
/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
/******/ var script, needAttach;
/******/ if(key !== undefined) {
/******/ var scripts = document.getElementsByTagName("script");
/******/ for(var i = 0; i < scripts.length; i++) {
/******/ var s = scripts[i];
/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }
/******/ }
/******/ }
/******/ if(!script) {
/******/ needAttach = true;
/******/ script = document.createElement('script');
/******/
/******/ script.charset = 'utf-8';
/******/ script.timeout = 120;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key);
/******/
/******/ script.src = url;
/******/ }
/******/ inProgress[url] = [done];
/******/ var onScriptComplete = (prev, event) => {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
/******/ clearTimeout(timeout);
/******/ var doneFns = inProgress[url];
/******/ delete inProgress[url];
/******/ script.parentNode && script.parentNode.removeChild(script);
/******/ doneFns && doneFns.forEach((fn) => (fn(event)));
/******/ if(prev) return prev(event);
/******/ }
/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
/******/ script.onload = onScriptComplete.bind(null, script.onload);
/******/ needAttach && document.head.appendChild(script);
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/remotes loading */
/******/ (() => {
/******/ var chunkMapping = {};
/******/ var idToExternalAndNameMapping = {};
/******/ __webpack_require__.f.remotes = (chunkId, promises) => {
/******/ if(__webpack_require__.o(chunkMapping, chunkId)) {
/******/ chunkMapping[chunkId].forEach((id) => {
/******/ var getScope = __webpack_require__.R;
/******/ if(!getScope) getScope = [];
/******/ var data = idToExternalAndNameMapping[id];
/******/ if(getScope.indexOf(data) >= 0) return;
/******/ getScope.push(data);
/******/ if(data.p) return promises.push(data.p);
/******/ var onError = (error) => {
/******/ if(!error) error = new Error("Container missing");
/******/ if(typeof error.message === "string")
/******/ error.message += '\nwhile loading "' + data[1] + '" from ' + data[2];
/******/ __webpack_require__.m[id] = () => {
/******/ throw error;
/******/ }
/******/ data.p = 0;
/******/ };
/******/ var handleFunction = (fn, arg1, arg2, d, next, first) => {
/******/ try {
/******/ var promise = fn(arg1, arg2);
/******/ if(promise && promise.then) {
/******/ var p = promise.then((result) => (next(result, d)), onError);
/******/ if(first) promises.push(data.p = p); else return p;
/******/ } else {
/******/ return next(promise, d, first);
/******/ }
/******/ } catch(error) {
/******/ onError(error);
/******/ }
/******/ }
/******/ var onExternal = (external, _, first) => (external ? handleFunction(__webpack_require__.I, data[0], 0, external, onInitialized, first) : onError());
/******/ var onInitialized = (_, external, first) => (handleFunction(external.get, data[1], getScope, 0, onFactory, first));
/******/ var onFactory = (factory) => {
/******/ data.p = 1;
/******/ __webpack_require__.m[id] = (module) => {
/******/ module.exports = factory();
/******/ }
/******/ };
/******/ handleFunction(__webpack_require__, data[2], 0, 0, onExternal, 1);
/******/ });
/******/ }
/******/ }
/******/ })();
/******/
/******/ /* webpack/runtime/sharing */
/******/ (() => {
/******/ __webpack_require__.S = {};
/******/ var initPromises = {};
/******/ var initTokens = {};
/******/ __webpack_require__.I = (name, initScope) => {
/******/ if(!initScope) initScope = [];
/******/ // handling circular init calls
/******/ var initToken = initTokens[name];
/******/ if(!initToken) initToken = initTokens[name] = {};
/******/ if(initScope.indexOf(initToken) >= 0) return;
/******/ initScope.push(initToken);
/******/ // only runs once
/******/ if(initPromises[name]) return initPromises[name];
/******/ // creates a new share scope if needed
/******/ if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {};
/******/ // runs all init snippets from all modules reachable
/******/ var scope = __webpack_require__.S[name];
/******/ var warn = (msg) => {
/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg);
/******/ };
/******/ var uniqueName = "vue3-demo_home";
/******/ var register = (name, version, factory, eager) => {
/******/ var versions = scope[name] = scope[name] || {};
/******/ var activeVersion = versions[version];
/******/ if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };
/******/ };
/******/ var initExternal = (id) => {
/******/ var handleError = (err) => (warn("Initialization of sharing external failed: " + err));
/******/ try {
/******/ var module = __webpack_require__(id);
/******/ if(!module) return;
/******/ var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope))
/******/ if(module.then) return promises.push(module.then(initFn, handleError));
/******/ var initResult = initFn(module);
/******/ if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));
/******/ } catch(err) { handleError(err); }
/******/ }
/******/ var promises = [];
/******/ switch(name) {
/******/ case "default": {
/******/ register("vue", "3.3.7", () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! ../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js"))))));
/******/ }
/******/ break;
/******/ }
/******/ if(!promises.length) return initPromises[name] = 1;
/******/ return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1));
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/consumes */
/******/ (() => {
/******/ var parseVersion = (str) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ var p=p=>{return p.split(".").map((p=>{return+p==p?+p:p}))},n=/^([^-+]+)?(?:-([^+]+))?(?:+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r;
/******/ }
/******/ var versionLt = (a, b) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ a=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r<b.length&&"u"!=(typeof b[r])[0];var e=a[r],n=(typeof e)[0];if(r>=b.length)return"u"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return"o"==n&&"n"==f||("s"==f||"u"==n);if("o"!=n&&"u"!=n&&e!=t)return e<t;r++}
/******/ }
/******/ var rangeToString = (range) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ var r=range[0],n="";if(1===range.length)return"*";if(r+.5){n+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a<range.length;a++){e--,n+="u"==(typeof(t=range[a]))[0]?"-":(e>0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a<range.length;a++){var t=range[a];g.push(0===t?"not("+o()+")":1===t?"("+o()+" || "+o()+")":2===t?g.pop()+" "+g.pop():rangeToString(t))}return o();function o(){return g.pop().replace(/^((.+))$/,"$1")}
/******/ }
/******/ var satisfy = (range, version) => {
/******/ // see webpack/lib/util/semver.js for original code
/******/ if(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i<range.length?(typeof range[i])[0]:"";if(n>=version.length||"o"==(s=(typeof(f=version[n]))[0]))return!a||("u"==g?i>e&&!r:""==g!=r);if("u"==s){if(!a||"u"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f<range[i])return!1;f!=range[i]&&(a=!1)}else if("s"!=g&&"n"!=g){if(r||i<=e)return!1;a=!1,i--}else{if(i<=e||s<g!=r)return!1;a=!1}else"s"!=g&&"n"!=g&&(a=!1,i--)}}var t=[],o=t.pop.bind(t);for(n=1;n<range.length;n++){var u=range[n];t.push(1==u?o()|o():2==u?o()&o():u?satisfy(u,version):!o())}return!!o();
/******/ }
/******/ var exists = (scope, key) => {
/******/ return scope && __webpack_require__.o(scope, key);
/******/ }
/******/ var get = (entry) => {
/******/ entry.loaded = 1;
/******/ return entry.get()
/******/ };
/******/ var eagerOnly = (versions) => {
/******/ return Object.keys(versions).reduce((filtered, version) => {
/******/ if (versions[version].eager) {
/******/ filtered[version] = versions[version];
/******/ }
/******/ return filtered;
/******/ }, {});
/******/ };
/******/ var findLatestVersion = (scope, key, eager) => {
/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key];
/******/ var key = Object.keys(versions).reduce((a, b) => {
/******/ return !a || versionLt(a, b) ? b : a;
/******/ }, 0);
/******/ return key && versions[key];
/******/ };
/******/ var findSatisfyingVersion = (scope, key, requiredVersion, eager) => {
/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key];
/******/ var key = Object.keys(versions).reduce((a, b) => {
/******/ if (!satisfy(requiredVersion, b)) return a;
/******/ return !a || versionLt(a, b) ? b : a;
/******/ }, 0);
/******/ return key && versions[key]
/******/ };
/******/ var findSingletonVersionKey = (scope, key, eager) => {
/******/ var versions = eager ? eagerOnly(scope[key]) : scope[key];
/******/ return Object.keys(versions).reduce((a, b) => {
/******/ return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;
/******/ }, 0);
/******/ };
/******/ var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => {
/******/ return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"
/******/ };
/******/ var getInvalidVersionMessage = (scope, scopeName, key, requiredVersion, eager) => {
/******/ var versions = scope[key];
/******/ return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\n" +
/******/ "Available versions: " + Object.keys(versions).map((key) => {
/******/ return key + " from " + versions[key].from;
/******/ }).join(", ");
/******/ };
/******/ var fail = (msg) => {
/******/ throw new Error(msg);
/******/ }
/******/ var failAsNotExist = (scopeName, key) => {
/******/ return fail("Shared module " + key + " doesn't exist in shared scope " + scopeName);
/******/ }
/******/ var warn = /*#__PURE__*/ (msg) => {
/******/ if (typeof console !== "undefined" && console.warn) console.warn(msg);
/******/ };
/******/ var init = (fn) => (function(scopeName, key, eager, c, d) {
/******/ var promise = __webpack_require__.I(scopeName);
/******/ if (promise && promise.then && !eager) {
/******/ return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], key, false, c, d));
/******/ }
/******/ return fn(scopeName, __webpack_require__.S[scopeName], key, eager, c, d);
/******/ });
/******/
/******/ var useFallback = (scopeName, key, fallback) => {
/******/ return fallback ? fallback() : failAsNotExist(scopeName, key);
/******/ }
/******/ var load = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ return get(findLatestVersion(scope, key, eager));
/******/ });
/******/ var loadVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);
/******/ if (satisfyingVersion) return get(satisfyingVersion);
/******/ warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))
/******/ return get(findLatestVersion(scope, key, eager));
/******/ });
/******/ var loadStrictVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);
/******/ if (satisfyingVersion) return get(satisfyingVersion);
/******/ if (fallback) return fallback();
/******/ fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));
/******/ });
/******/ var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var version = findSingletonVersionKey(scope, key, eager);
/******/ return get(scope[key][version]);
/******/ });
/******/ var loadSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var version = findSingletonVersionKey(scope, key, eager);
/******/ if (!satisfy(requiredVersion, version)) {
/******/ warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));
/******/ }
/******/ return get(scope[key][version]);
/******/ });
/******/ var loadStrictSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
/******/ if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
/******/ var version = findSingletonVersionKey(scope, key, eager);
/******/ if (!satisfy(requiredVersion, version)) {
/******/ fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));
/******/ }
/******/ return get(scope[key][version]);
/******/ });
/******/ var installedModules = {};
/******/ var moduleToHandlerMapping = {
/******/ "webpack/sharing/consume/default/vue/vue": () => (loadSingletonVersion("default", "vue", false, [1,3,0,11], () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! vue */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js")))))))
/******/ };
/******/ // no consumes in initial chunks
/******/ var chunkMapping = {
/******/ "webpack_sharing_consume_default_vue_vue": [
/******/ "webpack/sharing/consume/default/vue/vue"
/******/ ]
/******/ };
/******/ var startedInstallModules = {};
/******/ __webpack_require__.f.consumes = (chunkId, promises) => {
/******/ if(__webpack_require__.o(chunkMapping, chunkId)) {
/******/ chunkMapping[chunkId].forEach((id) => {
/******/ if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);
/******/ if(!startedInstallModules[id]) {
/******/ var onFactory = (factory) => {
/******/ installedModules[id] = 0;
/******/ __webpack_require__.m[id] = (module) => {
/******/ delete __webpack_require__.c[id];
/******/ module.exports = factory();
/******/ }
/******/ };
/******/ startedInstallModules[id] = true;
/******/ var onError = (error) => {
/******/ delete installedModules[id];
/******/ __webpack_require__.m[id] = (module) => {
/******/ delete __webpack_require__.c[id];
/******/ throw error;
/******/ }
/******/ };
/******/ try {
/******/ var promise = moduleToHandlerMapping[id]();
/******/ if(promise.then) {
/******/ promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));
/******/ } else onFactory(promise);
/******/ } catch(e) { onError(e); }
/******/ }
/******/ });
/******/ }
/******/ }
/******/ })();
/******/
/******/
/******/ /* webpack/runtime/jsonp chunk loading */
/******/ (() => {
/******/ // no baseURI
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
/******/ var installedChunks = __webpack_require__.hmrS_jsonp = __webpack_require__.hmrS_jsonp || {
/******/ "home": 0
/******/ };
/******/
/******/ __webpack_require__.f.j = (chunkId, promises) => {
/******/ // JSONP chunk loading for javascript
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ if("webpack_sharing_consume_default_vue_vue" != chunkId) {
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ var loadingEnded = (event) => {
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
/******/ installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
/******/ if(installedChunkData) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ installedChunkData[1](error);
/******/ }
/******/ }
/******/ };
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
/******/ } else installedChunks[chunkId] = 0;
/******/ }
/******/ }
/******/ };
/******/
/******/ // no prefetching
/******/
/******/ // no preloaded
/******/
/******/ var currentUpdatedModulesList;
/******/ var waitingUpdateResolves = {};
/******/ function loadUpdateChunk(chunkId, updatedModulesList) {
/******/ currentUpdatedModulesList = updatedModulesList;
/******/ return new Promise((resolve, reject) => {
/******/ waitingUpdateResolves[chunkId] = resolve;
/******/ // start update chunk loading
/******/ var url = __webpack_require__.p + __webpack_require__.hu(chunkId);
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ var loadingEnded = (event) => {
/******/ if(waitingUpdateResolves[chunkId]) {
/******/ waitingUpdateResolves[chunkId] = undefined
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading hot update chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ reject(error);
/******/ }
/******/ };
/******/ __webpack_require__.l(url, loadingEnded);
/******/ });
/******/ }
/******/
/******/ self["webpackHotUpdatevue3_demo_home"] = (chunkId, moreModules, runtime) => {
/******/ for(var moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ currentUpdate[moduleId] = moreModules[moduleId];
/******/ if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);
/******/ }
/******/ }
/******/ if(runtime) currentUpdateRuntime.push(runtime);
/******/ if(waitingUpdateResolves[chunkId]) {
/******/ waitingUpdateResolves[chunkId]();
/******/ waitingUpdateResolves[chunkId] = undefined;
/******/ }
/******/ };
/******/ };
/******/
/******/
/******/ // no on chunks loaded
/******/
/******/ // install a JSONP callback for chunk loading
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
/******/ var [chunkIds, moreModules, runtime] = data;
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0;
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
/******/ for(moduleId in moreModules) {
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(runtime) var result = runtime(__webpack_require__);
/******/ }
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ installedChunks[chunkId][0]();
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/
/******/ }
/******/
/******/ var chunkLoadingGlobal = self["webpackChunkvue3_demo_home"] = self["webpackChunkvue3_demo_home"] || [];
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // module cache are used so entry inlining is disabled
/******/ // startup
/******/ // Load entry module and return exports
/******/ __webpack_require__("../../node_modules/.pnpm/webpack-dev-server@5.0.4_webpack-cli@5.1.4_webpack@5.96.1/node_modules/webpack-dev-server/client/index.js?protocol=ws%3A&hostname=0.0.0.0&port=3002&pathname=%2Fws&logging=info&overlay=true&reconnect=10&hot=true&live-reload=true");
/******/ __webpack_require__("../../node_modules/.pnpm/webpack@5.96.1_@swc+core@1.9.2_webpack-cli@5.1.4/node_modules/webpack/hot/dev-server.js");
/******/ var __webpack_exports__ = __webpack_require__("webpack/container/entry/home");
/******/ home = __webpack_exports__;
/******/
/******/ })()
;
3.2.3.4 main.js文件
3.2.3.4.1 源码
import { createApp, defineAsyncComponent } from 'vue';
import Layout from './Layout.vue';
const Content = defineAsyncComponent(() => import('home/Content'));
const Button = defineAsyncComponent(() => import('home/Button'));
const app = createApp(Layout);
app.component('content-element', Content);
app.component('button-element', Button);
app.mount('#app');
3.2.3.4.2 构建后代码
"use strict";
(self["webpackChunkvue3_demo_layout"] = self["webpackChunkvue3_demo_layout"] || []).push([["src_main_js"],{
/***/ "./src/main.js":
/*!*********************!*\
!*** ./src/main.js ***!
*********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "webpack/sharing/consume/default/vue/vue");
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _Layout_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Layout.vue */ "./src/Layout.vue");
const Content = (0,vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)(() => __webpack_require__.e(/*! import() */ "webpack_container_remote_home_Content").then(__webpack_require__.t.bind(__webpack_require__, /*! home/Content */ "webpack/container/remote/home/Content", 23)));
const Button = (0,vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)(() => __webpack_require__.e(/*! import() */ "webpack_container_remote_home_Button").then(__webpack_require__.t.bind(__webpack_require__, /*! home/Button */ "webpack/container/remote/home/Button", 23)));
const app = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createApp)(_Layout_vue__WEBPACK_IMPORTED_MODULE_1__["default"]);
app.component('content-element', Content);
app.component('button-element', Button);
app.mount('#app');
/***/ })
}]);
3.2.4 过程解析
3.2.4.1 webpack异步模块的加载流程前置
__webpack_require__.e函数,__webpack_require__.f.resumes
__webpack_require__.f.remotes
__webpack_require__.f.MiniCss
__webpack_require__.f.l
3.2.4.2 webpack\_require.f.consumes
var parseVersion = (str) => {
// see webpack/lib/util/semver.js for original code
var p=p=>{return p.split(".").map((p=>{return+p==p?+p:p}))},n=/^([^-+]+)?(?:-([^+]+))?(?:+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r;
}
var versionLt = (a, b) => {
// see webpack/lib/util/semver.js for original code
a=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r<b.length&&"u"!=(typeof b[r])[0];var e=a[r],n=(typeof e)[0];if(r>=b.length)return"u"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return"o"==n&&"n"==f||("s"==f||"u"==n);if("o"!=n&&"u"!=n&&e!=t)return e<t;r++}
}
var rangeToString = (range) => {
// see webpack/lib/util/semver.js for original code
var r=range[0],n="";if(1===range.length)return"*";if(r+.5){n+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a<range.length;a++){e--,n+="u"==(typeof(t=range[a]))[0]?"-":(e>0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a<range.length;a++){var t=range[a];g.push(0===t?"not("+o()+")":1===t?"("+o()+" || "+o()+")":2===t?g.pop()+" "+g.pop():rangeToString(t))}return o();function o(){return g.pop().replace(/^((.+))$/,"$1")}
}
var satisfy = (range, version) => {
// see webpack/lib/util/semver.js for original code
if(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i<range.length?(typeof range[i])[0]:"";if(n>=version.length||"o"==(s=(typeof(f=version[n]))[0]))return!a||("u"==g?i>e&&!r:""==g!=r);if("u"==s){if(!a||"u"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f<range[i])return!1;f!=range[i]&&(a=!1)}else if("s"!=g&&"n"!=g){if(r||i<=e)return!1;a=!1,i--}else{if(i<=e||s<g!=r)return!1;a=!1}else"s"!=g&&"n"!=g&&(a=!1,i--)}}var t=[],o=t.pop.bind(t);for(n=1;n<range.length;n++){var u=range[n];t.push(1==u?o()|o():2==u?o()&o():u?satisfy(u,version):!o())}return!!o();
}
var exists = (scope, key) => {
return scope && __webpack_require__.o(scope, key);
}
var get = (entry) => {
entry.loaded = 1;
return entry.get()
};
var eagerOnly = (versions) => {
return Object.keys(versions).reduce((filtered, version) => {
if (versions[version].eager) {
filtered[version] = versions[version];
}
return filtered;
}, {});
};
var findLatestVersion = (scope, key, eager) => {
var versions = eager ? eagerOnly(scope[key]) : scope[key];
var key = Object.keys(versions).reduce((a, b) => {
return !a || versionLt(a, b) ? b : a;
}, 0);
return key && versions[key];
};
var findSatisfyingVersion = (scope, key, requiredVersion, eager) => {
var versions = eager ? eagerOnly(scope[key]) : scope[key];
var key = Object.keys(versions).reduce((a, b) => {
if (!satisfy(requiredVersion, b)) return a;
return !a || versionLt(a, b) ? b : a;
}, 0);
return key && versions[key]
};
var findSingletonVersionKey = (scope, key, eager) => {
var versions = eager ? eagerOnly(scope[key]) : scope[key];
return Object.keys(versions).reduce((a, b) => {
return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;
}, 0);
};
var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => {
return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"
};
var getInvalidVersionMessage = (scope, scopeName, key, requiredVersion, eager) => {
var versions = scope[key];
return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\n" +
"Available versions: " + Object.keys(versions).map((key) => {
return key + " from " + versions[key].from;
}).join(", ");
};
var fail = (msg) => {
throw new Error(msg);
}
var failAsNotExist = (scopeName, key) => {
return fail("Shared module " + key + " doesn't exist in shared scope " + scopeName);
}
var warn = /*#__PURE__*/ (msg) => {
if (typeof console !== "undefined" && console.warn) console.warn(msg);
};
var init = (fn) => (function(scopeName, key, eager, c, d) {
var promise = __webpack_require__.I(scopeName);
if (promise && promise.then && !eager) {
return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], key, false, c, d));
}
return fn(scopeName, __webpack_require__.S[scopeName], key, eager, c, d);
});
var useFallback = (scopeName, key, fallback) => {
return fallback ? fallback() : failAsNotExist(scopeName, key);
}
var load = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => {
if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
return get(findLatestVersion(scope, key, eager));
});
var loadVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);
if (satisfyingVersion) return get(satisfyingVersion);
warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))
return get(findLatestVersion(scope, key, eager));
});
var loadStrictVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);
if (satisfyingVersion) return get(satisfyingVersion);
if (fallback) return fallback();
fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));
});
var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key, eager, fallback) => {
if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
var version = findSingletonVersionKey(scope, key, eager);
return get(scope[key][version]);
});
var loadSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
var version = findSingletonVersionKey(scope, key, eager);
if (!satisfy(requiredVersion, version)) {
warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));
}
return get(scope[key][version]);
});
var loadStrictSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
var version = findSingletonVersionKey(scope, key, eager);
if (!satisfy(requiredVersion, version)) {
fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));
}
return get(scope[key][version]);
});
var installedModules = {};
var moduleToHandlerMapping = {
"webpack/sharing/consume/default/vue/vue": () => (loadSingletonVersion("default", "vue", false, [1,3,0,11], () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! vue */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js")))))))
};
// no consumes in initial chunks
// 模块依赖的共享依赖
var chunkMapping = {
"src_main_js": [
"webpack/sharing/consume/default/vue/vue"
]
};
var startedInstallModules = {};
__webpack_require__.f.consumes = (chunkId, promises) => {
if(__webpack_require__.o(chunkMapping, chunkId)) {
chunkMapping[chunkId].forEach((id) => {
if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);
if(!startedInstallModules[id]) {
var onFactory = (factory) => {
installedModules[id] = 0;
__webpack_require__.m[id] = (module) => {
delete __webpack_require__.c[id];
module.exports = factory();
}
};
startedInstallModules[id] = true;
var onError = (error) => {
delete installedModules[id];
__webpack_require__.m[id] = (module) => {
delete __webpack_require__.c[id];
throw error;
}
};
try {
var promise = moduleToHandlerMapping[id]();
if(promise.then) {
promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));
} else onFactory(promise);
} catch(e) { onError(e); }
}
});
}
}
shared 共享依赖,所以在执行到__webpack_require__.f.consumes开始检查模块是否有对应的共享依赖,这里可以发现就是webpack/sharing/consume/default/vue/vueloadSingletonVersion 函数进行加载,主要我们在配置中设置了singleton: truevar moduleToHandlerMapping = {
"webpack/sharing/consume/default/vue/vue":
() => (loadSingletonVersion("default", "vue", false, [1,3,0,11], () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! vue */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js")))))))
};
var loadSingletonVersion = /*#__PURE__*/ init((scopeName, scope, key, eager, requiredVersion, fallback) => {
if (!exists(scope, key)) return useFallback(scopeName, key, fallback);
var version = findSingletonVersionKey(scope, key, eager);
if (!satisfy(requiredVersion, version)) {
warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));
}
return get(scope[key][version]);
});
loadSingletonVersion之前,首先要执行了 init方法,var init = (fn) => (function(scopeName, key, eager, c, d) {
var promise = __webpack_require__.I(scopeName);
if (promise && promise.then && !eager) {
return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], key, false, c, d));
}
return fn(scopeName, __webpack_require__.S[scopeName], key, eager, c, d);
});
__webpack_require__.I,接着看I函数,它是一个独立的模块,在runtime/share3.2.4.3 webpack\_require.I
__webpack_require__.S = {};
var initPromises = {};
var initTokens = {};
__webpack_require__.I = (name, initScope) => {
if(!initScope) initScope = [];
// handling circular init calls
var initToken = initTokens[name];
if(!initToken) initToken = initTokens[name] = {};
if(initScope.indexOf(initToken) >= 0) return;
initScope.push(initToken);
// only runs once
if(initPromises[name]) return initPromises[name];
// creates a new share scope if needed
if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {};
// runs all init snippets from all modules reachable
var scope = __webpack_require__.S[name];
var warn = (msg) => {
if (typeof console !== "undefined" && console.warn) console.warn(msg);
};
var uniqueName = "vue3-demo_layout";
var register = (name, version, factory, eager) => {
var versions = scope[name] = scope[name] || {};
var activeVersion = versions[version];
if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };
};
var initExternal = (id) => {
var handleError = (err) => (warn("Initialization of sharing external failed: " + err));
try {
var module = __webpack_require__(id);
if(!module) return;
var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope))
if(module.then) return promises.push(module.then(initFn, handleError));
var initResult = initFn(module);
if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));
} catch(err) { handleError(err); }
}
var promises = [];
switch(name) {
case "default": {
register("vue", "3.3.7", () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! ../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js"))))));
initExternal("webpack/container/reference/home");
}
break;
}
if(!promises.length) return initPromises[name] = 1;
return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1));
};
__webpack_require__.S上面,数据结构就是__webpack_require__.S[version] = { get: factory, from: uniqueName, eager: !!eager }() => (__webpack_require__.e("vendors-{
"default": {
"vue": {
"3.3.7": {
"from": "vue3-demo_layout",
"eager": false
// get 包括了具体vue如何请求到
get: () => (__webpack_require__.e("vendors-node_modules_pnpm_vue_3_3_7_typescript_5_6_3_node_modules_vue_dist_vue_runtime_esm-bu-3fdf17").then(() => (() => (__webpack_require__(/*! ../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js */ "../../node_modules/.pnpm/vue@3.3.7_typescript@5.6.3/node_modules/vue/dist/vue.runtime.esm-bundler.js")))))
}
}
}
}
__webpack_require__ .S
__webpack_require__(webpack/container/reference/home),这个模块在前面已经注册过了{
/***/ "webpack/container/reference/home":
/*!************************************************************!*\
!*** external "home@http://localhost:3002/remoteEntry.js" ***!
************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
var __webpack_error__ = new Error();
module.exports = new Promise((resolve, reject) => {
if(typeof home !== "undefined") return resolve();
__webpack_require__.l("http://localhost:3002/remoteEntry.js", (event) => {
if(typeof home !== "undefined") return resolve();
var errorType = event && (event.type === 'load' ? 'missing' : event.type);
var realSrc = event && event.target && event.target.src;
__webpack_error__.message = 'Loading script failed.\n(' + errorType + ': ' + realSrc + ')';
__webpack_error__.name = 'ScriptExternalLoadError';
__webpack_error__.type = errorType;
__webpack_error__.request = realSrc;
reject(__webpack_error__);
}, "home");
}).then(() => (home));
/***/ }
__webpack_require__.l 函数,加载远程模块入口文件http://localhost:3002/remoteEntry.jsvar moduleMap = {
"./Content": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Content_vue-_cddc0")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Content */ "./src/components/Content.vue")))));
},
"./Button": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Button_js")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Button */ "./src/components/Button.js")))));
}
};
var init = (shareScope, initScope) => {
if (!__webpack_require__.S) return;
var name = "default"
var oldScope = __webpack_require__.S[name];
if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");
__webpack_require__.S[name] = shareScope;
return __webpack_require__.I(name, initScope);
};
var get = (module, getScope) => {
__webpack_require__.R = getScope;
getScope = (
__webpack_require__.o(moduleMap, module)
? moduleMap[module]()
: Promise.resolve().then(() => {
throw new Error('Module "' + module + '" does not exist in container.');
})
);
__webpack_require__.R = undefined;
return getScope;
};
// This exports getters to disallow modifications
__webpack_require__.d(exports, {
get: () => (get),
init: () => (init)
});
__webpack_require__.S和initScope作为参数var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope))__webpack_require__.S[name] = shareScope;
__webpack_require__.S[name]作为参数传入的,本质上是src/main.js(host)文件和remoteEntry.js(remote)文件之间,通过全局变量,传递各自上下文中的内部变量(__webpack_require__.S)上的共享依赖。remote___webpack_require__.S[name] = host___webpack_require__.S[name]
3.2.4.4 webpack\_require.f.j
{
/***/ "./src/main.js":
/*!*********************!*\
!*** ./src/main.js ***!
*********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "webpack/sharing/consume/default/vue/vue");
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _Layout_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Layout.vue */ "./src/Layout.vue");
const Content = (0,vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)(() => __webpack_require__.e(/*! import() */ "webpack_container_remote_home_Content").then(__webpack_require__.t.bind(__webpack_require__, /*! home/Content */ "webpack/container/remote/home/Content", 23)));
const Button = (0,vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)(() => __webpack_require__.e(/*! import() */ "webpack_container_remote_home_Button").then(__webpack_require__.t.bind(__webpack_require__, /*! home/Button */ "webpack/container/remote/home/Button", 23)));
const app = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createApp)(_Layout_vue__WEBPACK_IMPORTED_MODULE_1__["default"]);
app.component('content-element', Content);
app.component('button-element', Button);
app.mount('#app');
/***/ })
}
__webpack_require__.e(/*! import() */ "webpack_container_remote_home_Content")函数,跟[前面的src\_main\_js加载类似],开始遍历执行\_\_webpack\_require\_\_.f上的挂载方法,执行到\_\_webpack\_require\_\_.f.consumes时,没有映射到共享依赖跳过,继续执行到__webpack_require__.f.remotes3.2.4.5 webpack\_require.f.remotes
var chunkMapping = {
"webpack_container_remote_home_Content": [
"webpack/container/remote/home/Content"
],
"webpack_container_remote_home_Button": [
"webpack/container/remote/home/Button"
]
};
var idToExternalAndNameMapping = {
"webpack/container/remote/home/Content": [
"default",
"./Content",
"webpack/container/reference/home"
],
"webpack/container/remote/home/Button": [
"default",
"./Button",
"webpack/container/reference/home"
]
};
__webpack_require__.f.remotes = (chunkId, promises) => {
if(__webpack_require__.o(chunkMapping, chunkId)) {
chunkMapping[chunkId].forEach((id) => {
var getScope = __webpack_require__.R;
if(!getScope) getScope = [];
var data = idToExternalAndNameMapping[id];
if(getScope.indexOf(data) >= 0) return;
getScope.push(data);
if(data.p) return promises.push(data.p);
var onError = (error) => {
if(!error) error = new Error("Container missing");
if(typeof error.message === "string")
error.message += '\nwhile loading "' + data[1] + '" from ' + data[2];
__webpack_require__.m[id] = () => {
throw error;
}
data.p = 0;
};
var handleFunction = (fn, arg1, arg2, d, next, first) => {
try {
var promise = fn(arg1, arg2);
if(promise && promise.then) {
var p = promise.then((result) => (next(result, d)), onError);
if(first) promises.push(data.p = p); else return p;
} else {
return next(promise, d, first);
}
} catch(error) {
onError(error);
}
}
var onExternal = (external, _, first) => (external ? handleFunction(__webpack_require__.I, data[0], 0, external, onInitialized, first) : onError());
var onInitialized = (_, external, first) => (handleFunction(external.get, data[1], getScope, 0, onFactory, first));
var onFactory = (factory) => {
data.p = 1;
__webpack_require__.m[id] = (module) => {
module.exports = factory();
}
};
handleFunction(__webpack_require__, data[2], 0, 0, onExternal, 1);
});
}
}
webpack_container_remote_home_Content在chunkMapping里面已经声明了,chunkMapping保存依赖的远程应用具体模块id,idToExternalAndNameMapping则保存远程模块的具体信息,看最后的执行入口函数handleFunction(__webpack_require__, data[2], 0, 0, onExternal, 1); var handleFunction = (fn, arg1, arg2, d, next, first) => {
try {
var promise = fn(arg1, arg2);
if(promise && promise.then) {
var p = promise.then((result) => (next(result, d)), onError);
if(first) promises.push(data.p = p); else return p;
} else {
return next(promise, d, first);
}
} catch(error) {
onError(error);
}
}
"webpack/container/reference/home",直接执行var promise = fn(arg1, arg2);
=>
__webpack_require__("webpack/container/reference/home", 0)
__webpack_module_cache__里面获取执行结果,也就是export上抛出的get和init方法。onExternal var onExternal = (external, _, first) => (external ? handleFunction(__webpack_require__.I, data[0], 0, external, onInitialized, first) : onError());
handleFunction(__webpack_require__.I, 'default', 0, external, onInitialized, first)
var promise = fn(arg1, arg2);
=>
__webpack_require__.I('default', 0),
就是前面在consumes方法里面,寻找并注册共享依赖,执行完成后继续执行next方法,也就是第5个参数onInitialized
var onInitialized = (_, external, first) => (handleFunction(external.get, data[1], getScope, 0, onFactory, first));
handleFunction(external.get, './Content', getScope, 0, onFactory, first )
var moduleMap = {
"./Content": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Content_vue-_cddc0")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Content */ "./src/components/Content.vue")))));
},
"./Button": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Button_js")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Button */ "./src/components/Button.js")))));
}
};
var get = (module, getScope) => {
__webpack_require__.R = getScope;
getScope = (
__webpack_require__.o(moduleMap, module)
? moduleMap[module]()
: Promise.resolve().then(() => {
throw new Error('Module "' + module + '" does not exist in container.');
})
);
__webpack_require__.R = undefined;
return getScope;
};
moduleMap['./Content'](),这里同样有__webpack_require__.e,但在是在远程应用的执行上下文里面,跟当前主应用的执行环境不同,这里是远程应用根据自己的webpack配置生成的webpack\_require相关函数,也是真正打包构建‘./Content’共享组件的地方。 var onFactory = (factory) => {
data.p = 1;
__webpack_require__.m[id] = (module) => {
module.exports = factory();
}
};
__webpack_require__.m = __webpack_modules__;
3.2.5 整体组件加载执行过程

3.3 Module Federation Runtime API 加载流程
3.3.1 概述
3.3.2 初始化请求链路
//const { ModuleFederationPlugin } = require('webpack').container;
...
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
// new ModuleFederationPlugin({
// name: 'layout',
// filename: 'remoteEntry.js',
// remotes: {
// home: 'home@http://localhost:3002/remoteEntry.js',
// },
// exposes: {},
// shared: {
// vue: {
// singleton: true,
// },
// },
// }),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './index.html'),
chunks: ['main'],
}),
new VueLoaderPlugin(),
],
import { createApp, defineAsyncComponent } from 'vue';
import Layout from './Layout.vue';
import { init, loadRemote } from '@module-federation/runtime';
init({
name: 'layout',
remotes: [
{
name: 'home',
entry: 'http://localhost:3002/remoteEntry.js',
},
],
shared: {
vue: {
singleton: true,
},
},
});
const Content = defineAsyncComponent(async () => await loadRemote('home/Content'));
const Button = defineAsyncComponent(async () => await loadRemote('home/Button'));
const app = createApp(Layout);
app.component('content-element', Content);
app.component('button-element', Button);
app.mount('#app');
3.3.3 源码与构建后代码对照
3.3.3.1 依赖库
"use strict";
(self["webpackChunkvue3_demo_layout"] = self["webpackChunkvue3_demo_layout"] || []).push([["vendors-node_modules_pnpm_mini-css-extract-plugin_2_9_2_webpack_5_96_1__swc_core_1_9_2__swc_h-8958a1"],{
"../../node_modules/.pnpm/@module-federation+runtime@0.20.0/node_modules/@module-federation/runtime/dist/index.esm.js":
/*!****************************************************************************************************************************!*\
!*** ../../node_modules/.pnpm/@module-federation+runtime@0.20.0/node_modules/@module-federation/runtime/dist/index.esm.js ***!
****************************************************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Module: () => (/* reexport safe */ _module_federation_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Module),
/* harmony export */ ModuleFederation: () => (/* reexport safe */ _module_federation_runtime_core__WEBPACK_IMPORTED_MODULE_0__.ModuleFederation),
/* harmony export */ createInstance: () => (/* binding */ createInstance),
/* harmony export */ getInstance: () => (/* binding */ getInstance),
/* harmony export */ getRemoteEntry: () => (/* reexport safe */ _module_federation_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getRemoteEntry),
/* harmony export */ getRemoteInfo: () => (/* reexport safe */ _module_federation_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getRemoteInfo),
/* harmony export */ init: () => (/* binding */ init),
/* harmony export */ loadRemote: () => (/* binding */ loadRemote),
/* harmony export */ loadScript: () => (/* reexport safe */ _module_federation_runtime_core__WEBPACK_IMPORTED_MODULE_0__.loadScript),
/* harmony export */ loadScriptNode: () => (/* reexport safe */ _module_federation_runtime_core__WEBPACK_IMPORTED_MODULE_0__.loadScriptNode),
/* harmony export */ loadShare: () => (/* binding */ loadShare),
/* harmony export */ loadShareSync: () => (/* binding */ loadShareSync),
/* harmony export */ preloadRemote: () => (/* binding */ preloadRemote),
...
})3.3.3.2 main.js文件
3.3.3.2.1 源码
import { createApp, defineAsyncComponent } from 'vue';
import Layout from './Layout.vue';
import { init, loadRemote } from '@module-federation/runtime';
init({
name: 'layout',
remotes: [
{
name: 'home',
entry: 'http://localhost:3002/remoteEntry.js',
},
],
shared: {
vue: {
singleton: true,
},
},
});
const Content = defineAsyncComponent(async () => await loadRemote('home/Content'));
const Button = defineAsyncComponent(async () => await loadRemote('home/Button'));
const app = createApp(Layout);
app.component('content-element', Content);
app.component('button-element', Button);
app.mount('#app');
3.3.3.2.2 构建后代码
"use strict";
(self["webpackChunkvue3_demo_layout"] = self["webpackChunkvue3_demo_layout"] || []).push([["src_main_js"], {
/***/
"./src/main.js": /*!*********************!*\
!*** ./src/main.js ***!
*********************/
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */
/* harmony import */
var _Layout_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Layout.vue */
"./src/Layout.vue");
/* harmony import */
var _module_federation_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @module-federation/runtime */
"../../node_modules/.pnpm/@module-federation+runtime@0.20.0/node_modules/@module-federation/runtime/dist/index.esm.js");
(0,
_module_federation_runtime__WEBPACK_IMPORTED_MODULE_2__.init)({
name: 'layout',
remotes: [{
name: 'home',
entry: 'http://localhost:3002/remoteEntry.js',
}, ],
shared: {
vue: {
singleton: true,
},
},
});
const Content = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)(async () => await (0,
_module_federation_runtime__WEBPACK_IMPORTED_MODULE_2__.loadRemote)('home/Content'));
const Button = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)(async () => await (0,
_module_federation_runtime__WEBPACK_IMPORTED_MODULE_2__.loadRemote)('home/Button'));
const app = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.createApp)(_Layout_vue__WEBPACK_IMPORTED_MODULE_1__["default"]);
app.component('content-element', Content);
app.component('button-element', Button);
app.mount('#app');
/***/
}
)
}]);
3.3.4 过程分析
@module-federation/runtime里面的代码"./src/main.js": /*!*********************!*\
/***/
( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */
/* harmony import */
var _module_federation_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @module-federation/runtime */
"../../node_modules/.pnpm/@module-federation+runtime@0.20.0/node_modules/@module-federation/runtime/dist/index.esm.js");
(0,
_module_federation_runtime__WEBPACK_IMPORTED_MODULE_2__.init)({
name: 'layout',
remotes: [{
name: 'home',
entry: 'http://localhost:3002/remoteEntry.js',
}, ],
shared: {
vue: {
singleton: true,
},
},
});
const Content = (0,
vue__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent)(async () => await (0,
_module_federation_runtime__WEBPACK_IMPORTED_MODULE_2__.loadRemote)('home/Content'));
/***/
}
)
3.3.4.1 init方法
3.3.4.1.1 传入参数
export function createInstance(options: UserOptions) {
// Retrieve debug constructor
const ModuleFederationConstructor =
getGlobalFederationConstructor() || ModuleFederation;
const instance = new ModuleFederationConstructor(options);
setGlobalFederationInstance(instance);
return instance;
}
let FederationInstance: ModuleFederation | null = null;
/**
* @deprecated Use createInstance or getInstance instead
*/
export function init(options: UserOptions): ModuleFederation {
// Retrieve the same instance with the same name
const instance = getGlobalFederationInstance(options.name, options.version);
if (!instance) {
FederationInstance = createInstance(options);
return FederationInstance;
} else {
// Merge options
instance.initOptions(options);
if (!FederationInstance) {
FederationInstance = instance;
}
return instance;
}
}
3.3.4.1.2 runtime-core中执行构造函数
@module-federation/runtime-core 实现, constructor(userOptions: UserOptions) {
const plugins = USE_SNAPSHOT
? [snapshotPlugin(), generatePreloadAssetsPlugin()]
: [];
// TODO: Validate the details of the options
// Initialize options with default values
// 合并用户选项和默认选项
const defaultOptions: Options = {
id: getBuilderId(),
name: userOptions.name,
plugins,
remotes: [],
shared: {},
inBrowser: isBrowserEnv(),
};
this.name = userOptions.name;
this.options = defaultOptions;
// 2. 初始化各个处理器
this.snapshotHandler = new SnapshotHandler(this);
this.sharedHandler = new SharedHandler(this);
this.remoteHandler = new RemoteHandler(this);
this.shareScopeMap = this.sharedHandler.shareScopeMap;
// 3. 注册传入的插件
this.registerPlugins([
...defaultOptions.plugins,
...(userOptions.plugins || []),
]);
this.options = this.formatOptions(defaultOptions, userOptions);
}
setGlobalFederationInstance(instance); 存储到全局变量,方便后面的loadRemote使用export function setGlobalFederationInstance(
FederationInstance: ModuleFederation,
): void {
CurrentGlobal.__FEDERATION__.__INSTANCES__.push(FederationInstance);
}
3.3.4.2 loadRemote方法
3.3.4.2.1 外层调用查看
export function loadRemote<T>(
...args: Parameters<ModuleFederation['loadRemote']>
): Promise<T | null> {
assert(FederationInstance, getShortErrorMsg(RUNTIME_009, runtimeDescMap));
const loadRemote: typeof FederationInstance.loadRemote<T> =
FederationInstance.loadRemote;
// eslint-disable-next-line prefer-spread
return loadRemote.apply(FederationInstance, args);
}
async loadRemote<T>(
id: string,
options?: { loadFactory?: boolean; from: CallFrom },
): Promise<T | null> {
return this.remoteHandler.loadRemote(id, options);
}
this.remoteHandler 已经在前面实例化时,执行了初始化,再转到remote文件里面async loadRemote<T>(
id: string,
options?: { loadFactory?: boolean; from: CallFrom },
): Promise<T | null> {
const { host } = this;
try {
const { loadFactory = true } = options || {
loadFactory: true,
};
// 1. 获取 Module 实例和相关配置信息
const { module, moduleOptions, remoteMatchInfo } =
await this.getRemoteModuleAndOptions({
id,
});
..
// 2. 执行module.get
const moduleOrFactory = (await module.get(
idRes,
expose,
options,
remoteSnapshot,
)) as T;
// 3. 调用对应的生命周期钩子
const moduleWrapper = await this.hooks.lifecycle.onLoad.emit({
id: idRes,
pkgNameOrAlias,
expose,
exposeModule: loadFactory ? moduleOrFactory : undefined,
exposeModuleFactory: loadFactory ? undefined : moduleOrFactory,
remote,
options: moduleOptions,
moduleInstance: module,
origin: host,
});
this.setIdToRemoteMap(id, remoteMatchInfo);
// 4. 返回远程组件的具体实现
return moduleOrFactory;
} catch (error) {
return failOver as T;
}
}
3.3.4.2.2 New Module
getRemoteModuleAndOptions获取Module实例和相关配置信息,getRemoteModuleAndOptions里面除了初始化Module实例 new Module(moduleOptions);前面还有各种钩子函数的执行。3.3.4.2.3 Module.get
async get(
id: string,
expose: string,
options?: { loadFactory?: boolean },
remoteSnapshot?: ModuleInfo,
) {
const { loadFactory = true } = options || { loadFactory: true };
// 获取remoteEntry.js
const remoteEntryExports = await this.getEntry();
....
await remoteEntryExports.init(
initContainerOptions.shareScope,
initContainerOptions.initScope,
initContainerOptions.remoteEntryInitOptions,
);
await this.host.hooks.lifecycle.initContainer.emit({
...initContainerOptions,
id,
remoteSnapshot,
remoteEntryExports,
});
}
this.lib = remoteEntryExports;
this.inited = true;
let moduleFactory;
moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({
remoteEntryExports,
expose,
moduleInfo: this.remoteInfo,
});
// get exposeGetter
if (!moduleFactory) {
moduleFactory = await remoteEntryExports.get(expose);
}
assert(
moduleFactory,
`${getFMId(this.remoteInfo)} remote don't export ${expose}.`,
);
// keep symbol for module name always one format
const symbolName = processModuleAlias(this.remoteInfo.name, expose);
const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);
if (!loadFactory) {
return wrapModuleFactory;
}
const exposeContent = await wrapModuleFactory();
return exposeContent;
}
3.3.4.2.3.1 通过getEntry,异步加载remoteEntry.js
async getEntry(): Promise<RemoteEntryExports> {
...
remoteEntryExports = await getRemoteEntry({
origin: this.host,
remoteInfo: this.remoteInfo,
remoteEntryExports: this.remoteEntryExports,
});
...
this.remoteEntryExports = remoteEntryExports as RemoteEntryExports;
return this.remoteEntryExports;
}
export async function getRemoteEntry(params: {
origin: ModuleFederation;
remoteInfo: RemoteInfo;
remoteEntryExports?: RemoteEntryExports | undefined;
getEntryUrl?: (url: string) => string;
_inErrorHandling?: boolean; // Add flag to prevent recursion
}): Promise<RemoteEntryExports | false | void> {
const uniqueKey = getRemoteEntryUniqueKey(remoteInfo);
if (!globalLoading[uniqueKey]) {
const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;
const loaderHook = origin.loaderHook;
globalLoading[uniqueKey] = loadEntryHook
.emit({
loaderHook,
remoteInfo,
remoteEntryExports,
})
.then((res) => {
if (res) {
return res;
}
// Use ENV_TARGET if defined, otherwise fallback to isBrowserEnv, must keep this
const isWebEnvironment =
typeof ENV_TARGET !== 'undefined'
? ENV_TARGET === 'web'
: isBrowserEnv();
return isWebEnvironment
? loadEntryDom({
remoteInfo,
remoteEntryExports,
loaderHook,
getEntryUrl,
})
: loadEntryNode({ remoteInfo, loaderHook });
})
.catch(async (err) => {
throw err;
});
}
return globalLoading[uniqueKey];
}
async function loadEntryDom({
remoteInfo,
remoteEntryExports,
loaderHook,
getEntryUrl,
}: {
remoteInfo: RemoteInfo;
remoteEntryExports?: RemoteEntryExports;
loaderHook: ModuleFederation['loaderHook'];
getEntryUrl?: (url: string) => string;
}) {
const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
switch (type) {
case 'esm':
case 'module':
return loadEsmEntry({ entry, remoteEntryExports });
case 'system':
return loadSystemJsEntry({ entry, remoteEntryExports });
default:
return loadEntryScript({
entry,
globalName,
name,
loaderHook,
getEntryUrl,
});
}
}
async function loadEntryScript({
name,
globalName,
entry,
loaderHook,
getEntryUrl,
}: {
name: string;
globalName: string;
entry: string;
loaderHook: ModuleFederation['loaderHook'];
getEntryUrl?: (url: string) => string;
}): Promise<RemoteEntryExports> {
// if getEntryUrl is passed, use the getEntryUrl to get the entry url
const url = getEntryUrl ? getEntryUrl(entry) : entry;
return loadScript(url, {
attrs: {},
createScriptHook: (url, attrs) => {
const res = loaderHook.lifecycle.createScript.emit({ url, attrs });
},
})
.then(() => {
return handleRemoteEntryLoaded(name, globalName, entry);
})
}
3.3.4.2.3.2 执行remoteEntryExports.init,进行共享依赖传递融合
await remoteEntryExports.init(
initContainerOptions.shareScope,
initContainerOptions.initScope,
initContainerOptions.remoteEntryInitOptions,
);
var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope))
var moduleMap = {
"./Content": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Content_vue-_94460")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Content */ "./src/components/Content.vue")))));
},
"./Button": () => {
return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_vue_vue"), __webpack_require__.e("src_components_Button_js")]).then(() => (() => ((__webpack_require__(/*! ./src/components/Button */ "./src/components/Button.js")))));
}
};
var get = (module, getScope) => {
__webpack_require__.R = getScope;
getScope = (
__webpack_require__.o(moduleMap, module)
? moduleMap[module]()
: Promise.resolve().then(() => {
throw new Error('Module "' + module + '" does not exist in container.');
})
);
__webpack_require__.R = undefined;
return getScope;
};
var init = (shareScope, initScope) => {
if (!__webpack_require__.S) return;
var name = "default"
var oldScope = __webpack_require__.S[name];
if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");
__webpack_require__.S[name] = shareScope;
return __webpack_require__.I(name, initScope);
};
__webpack_require__.S是 Webpack 运行时内部用来存储所有共享作用域 (Share Scopes) 的地方,表示当前运行环境不支持共享功能,var oldScope = __webpack_require__.S[name];表示远程应用上进行共享配置项目,并进行缓存处理,这里进行oldScope && oldScope !== shareScope判断,主要兼容remoteEntry.js被加载多次的场景,比如远程应用在当前页面被多个宿主(host)引入并初始化,host-a 和host-b在一个页面被加载,他们都依赖同一个remote,远程应用的运行时只能有统一的远程应用的share scope。__webpack_require__.S[name] = shareScope,这里通常是vue、react这些共享库。3.3.4.2.3.3 执行远程应用remoteEntryExports暴露出来的get方法,加载共享组件Content,并返回给宿主应用
moduleFactory = await remoteEntryExports.get(expose);
remoteEntryExports.get('home/Content')moduleMap['./Content'](),找到content远程组件真实的地址,并通过__webpack_require__.e进行异步获取src_components_Content_vue-_944603.3.4.2.4 Return moduleFactory
3.3.5 整体组件加载执行过程

4. 项目实操
4.1 如何动态引入远程应用的remoteEntry.js如何进行控制?
4.2 远程应用加载失败如何处理?
4.3 js/css作用域控制?
4.4 其他一些类似的模块组件级加载方案
const app = await Garfish.loadApp('vue-app', {
cache: true,
basename,
domGetter: '#container',
// 子应用的入口资源地址,支持 HTML 和 JS
entry: 'http://localhost:8092',
});
setApp(app);
this.microApp = loadMicroApp({
name: 'app1',
entry: '//localhost:1234',
container: this.containerRef.current,
props: { brand: 'qiankun' },
});