vol*_*olk 7 javascript reactjs webpack webpack-5 webpack-module-federation
我正在研究 Webpack 5 模块联合功能,但在理解为什么我的代码不起作用时遇到了一些麻烦。这个想法与标准模块联合示例的做法非常相似:
app1- 是主机应用程序
app2- 是一个远程暴露整个应用程序app1
(app1呈现标题和水平线,app2应在其下方呈现)
双方app1并app2声明react与react-dom他们的共享,单,在急切的依赖weback.config.js:
// app1 webpack.config.js
module.exports = {
entry: path.resolve(SRC_DIR, './index.js');,
...
plugins: [
new ModuleFederationPlugin({
name: "app1",
remotes: {
app2: `app2@//localhost:2002/remoteEntry.js`,
},
shared: { react: { singleton: true, eager: true }, "react-dom": { singleton: true, eager: true } },
}),
...
],
};
Run Code Online (Sandbox Code Playgroud)
// app2 webpack.config.js
module.exports = {
entry: path.resolve(SRC_DIR, './index.js');,
...
plugins: [
new ModuleFederationPlugin({
name: "app2",
library: { type: "var", name: "app2" },
filename: "remoteEntry.js",
exposes: {
"./App": "./src/App",
},
shared: { react: { singleton: true, eager: true }, "react-dom": { singleton: true, eager: true } },
}),
...
],
};
Run Code Online (Sandbox Code Playgroud)
在 App1 index.js 我有下一个代码:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)
App1App.js组件是下一个:
import React, { Suspense } from 'react';
const RemoteApp2 = React.lazy(() => import("app2/App"));
export default function App() {
return (
<div>
<h1>App 1</h1>
<p>Below will be some content</p>
<hr/>
<Suspense fallback={'Loading App 2'}>
<RemoteApp2 />
</Suspense>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
但是当我启动应用程序时,我收到下一个错误:
Uncaught Error: Shared module is not available for eager consumption: webpack/sharing/consume/default/react/react?1bb3
at Object.__webpack_modules__.<computed> (consumes:133)
at __webpack_require__ (bootstrap:21)
at fn (hot module replacement:61)
at Module../src/index.js (main.bundle.a8d89941f5dd9a37d429.js:239)
at __webpack_require__ (bootstrap:21)
at startup:4
at startup:6
Run Code Online (Sandbox Code Playgroud)
如果我从提取一切index.js以bootstrap.js和index.js会做
Uncaught Error: Shared module is not available for eager consumption: webpack/sharing/consume/default/react/react?1bb3
at Object.__webpack_modules__.<computed> (consumes:133)
at __webpack_require__ (bootstrap:21)
at fn (hot module replacement:61)
at Module../src/index.js (main.bundle.a8d89941f5dd9a37d429.js:239)
at __webpack_require__ (bootstrap:21)
at startup:4
at startup:6
Run Code Online (Sandbox Code Playgroud)
一切正常。
这让我感到困惑,因为创作者的官方文档和博客文章指出您可以采用任何一种bootstrap.js方式或将依赖声明为渴望的。
感谢您提供有关为什么它在没有bootstrap.js模式的情况下不起作用的任何帮助/见解。
这是我正在构建的完整 GitHub 沙箱的链接:https : //github.com/vovkvlad/webpack-module-federation-sandbox/tree/master/simple
为了使其工作,您需要更改加载远程条目的方式。
ModuleFederationPlugin将 app1 的配置更新webpack.config.js为:...
new ModuleFederationPlugin({
name: "app1",
remoteType: 'var',
remotes: {
app2: 'app2',
},
shared: {
...packageJsonDeps,
react: { singleton: true, eager: true, requiredVersion: packageJsonDeps.react },
"react-dom": { singleton: true, eager: true, requiredVersion: packageJsonDeps["react-dom"] }
},
}),
...
Run Code Online (Sandbox Code Playgroud)
script将标签添加到head您的index.htmlapp1 中:<script src="http://localhost:2002/remoteEntry.js"></script>
Run Code Online (Sandbox Code Playgroud)
进一步黑客攻击看起来不错!
更新:
只是为了它:我已经为您的沙箱存储库创建了一个 PR,并进行了上述修复: https ://github.com/vovkvlad/webpack-module-federation-sandbox/pull/2
只是为了让那些可能会错过对初始答案的评论的人清楚:
最初失败的主要原因似乎是该remoteEntry.js文件是在实际运行主机应用程序的代码之后加载的。
这两种bootstrap.js方法,并直接加入脚本<script src="http://localhost:2002/remoteEntry.js"></script>的<head></head>标签具有完全相同的结果-他们让remoteEntry.js被加载和分析之前的主要应用程序的代码。
在引导程序的情况下,顺序是下一个:
main_bundle 已加载bootstrap.js文件中时 -remoteEntry.js被加载bootstrap.js 已加载实际运行主应用程序Oleg Vodolazsky 提出的变体顺序是下一个:
remoteEntry.js首先加载,因为它被直接添加到html文件中,并且 webpackmain_bundle被附加到<head></head>remoteEntry 链接之后main_bundle 加载并运行应用程序如果只是尝试在没有引导程序的情况下运行应用程序并且在<head></head> main_bundle加载之前没有硬编码脚本remoteEntry.js并main_bundle尝试实际运行应用程序时,它会失败并显示错误:
| 归档时间: |
|
| 查看次数: |
8584 次 |
| 最近记录: |