ReactJS 和 Webpack 模块联合应用程序在部署到云端时包含未定义的 url

Posted

技术标签:

【中文标题】ReactJS 和 Webpack 模块联合应用程序在部署到云端时包含未定义的 url【英文标题】:ReactJS and Webpack Module Federation Application contains urls with undefined when deployed to cloudfront 【发布时间】:2021-05-24 05:18:40 【问题描述】:

我有一个微前端应用程序,它由一个容器应用程序和几个远程应用程序组成。它使用带有 Webpack 5 模块联合的 ReactJS,并且在我的本地环境中运行良好。但是,当我将它部署到 AWS CloudFront 时,它并没有按预期工作。

似乎容器应用程序加载到了正确的路径上,但“未定义”被添加到遥控器的 remoteEntry.js 文件的 url 中。

请看下面的截图:

容器项目webpack生产配置如下:

const prodConfig = 
  mode: "production",
  output: 
    filename: "[name].[contenthash].js",
    publicPath: "/container/latest/",
  ,
  plugins: [
    new ModuleFederationPlugin(
      name: "container",
      remotes: 
        auth: `auth@$domain/auth/latest/remoteEntry.js`,
        marketing: `marketing@$domain/marketing/latest/remoteEntry.js`,
        dashboard: `dashboard@$domain/dashboard/latest/remoteEntry.js`,
      ,
      shared: packageJson.dependencies,
    ),
  ],
;

远程项目webpack生产配置如下:

const prodConfig = 
  mode: "production",
  output: 
    filename: "[name].[contenthash].js",
    publicPath: "/marketing/latest/",
  ,
  plugins: [
    new ModuleFederationPlugin(
      name: "marketing",
      filename: "remoteEntry.js",
      exposes: 
        "./MarketingApp": "./src/bootstrap",
      ,
      shared: packageJson.dependencies,
    ),
  ],
;

容器项目App.js如下:

import React,  lazy, Suspense, useState, useEffect  from "react";
import  Router, Route, Switch, Redirect  from "react-router-dom";
import 
  StylesProvider,
  createGenerateClassName,
 from "@material-ui/core/styles";
import  createBrowserHistory  from "history";

import Progress from "./components/Progress";
import Header from "./components/Header";

const MarketingLazy = lazy(() => import("./components/MarketingApp"));
const AuthLazy = lazy(() => import("./components/AuthApp"));
const DashboardLazy = lazy(() => import("./components/DashboardApp"));

const generateClassName = createGenerateClassName(
  productionPrefix: "co",
);

const history = createBrowserHistory();

export default () => 
  const [isSignedIn, setIsSignedIn] = useState(false);

  useEffect(() => 
    if (isSignedIn) 
      history.push("/dashboard");
    
  , [isSignedIn]);

  return (
    <Router history=history>
      <StylesProvider generateClassName=generateClassName>
        <div>
          <Header
            onSignOut=() => setIsSignedIn(false)
            isSignedIn=isSignedIn
          />
          <Suspense fallback=<Progress />>
            <Switch>
              <Route path="/auth">
                <AuthLazy onSignIn=() => setIsSignedIn(true) />
              </Route>
              <Route path="/dashboard">
                !isSignedIn && <Redirect to="/" />
                <DashboardLazy />
              </Route>
              <Route path="/" component=MarketingLazy />
            </Switch>
          </Suspense>
        </div>
      </StylesProvider>
    </Router>
  );
;

我正在努力找出错误所在。我不确定它是否有错误:

反应 反应路由器 Webpack 模块联合 AWS CloudFront

任何帮助将不胜感激

【问题讨论】:

我觉得至少部分问题可能与错误中该 URL 的路由有关。请注意它指向的 URL 中的 undefined。这可能会导致潜在的误报,即由于无法达到其标记而读取 404 页或 500 页。并将该页面中的 html 错误地解释为 JS,从而引发了意外的 嘿!它可能与您的 webpack 配置文件中的 publicPath 属性有关。 publicPath 必须是 remoteEntry.js 文件可用的路径。在您的示例中,您已将其设置为/marketing/latest/,而在您的主配置中,它应该存在marketing@$domain/marketing/latest/。在我的配置中,我指定了这样的 URL:http://myapp.com/remote,然后应用程序可以从 http://myapp.com/remote/remoteEntry.js 加载它 【参考方案1】:

如果您仔细查看浏览器日志。

您的网址中有一个undefined/marketing/latest/remoteEntry.js,用于加载模块联合远程网址。

您可能需要将 domain 变量设置为云端端点。

【讨论】:

以上是关于ReactJS 和 Webpack 模块联合应用程序在部署到云端时包含未定义的 url的主要内容,如果未能解决你的问题,请参考以下文章

Angular mat-select 和 webpack 模块联合事件问题

Webpack 模块联合不适用于急切的共享库

ReactJS webpack实现JS模块化使用的坑

Angular MFE - WebPack5 - 模块联合 - 图像路径问题

我尝试在 webpack 5 中填充模块但不工作(Reactjs)

样式组件和 Webpack 5 联合模块之间的冲突(无效的钩子调用)