webpack 使用Nx和Angular Architects将React mfe加载到Angular主机

r3i60tvu  于 2023-08-06  发布在  Webpack
关注(0)|答案(2)|浏览(107)

我已经用Nx创建了一个monorepo,具有一个Angular主机和一个Angular遥控器,这工作得很完美。我还有另一个带有React主机和React远程的monorepo,它们也可以工作。
This is the complete APP
当我试图将远程React微前端加载到Angular主机时,问题出现了。
我相信问题出在React微前端,因为如果我使用Angular Architects URL的演示URL,它工作得很好,但它不适用于我自己在Live Server上运行的URL。
我的 app.routes.ts

import { Route } from '@angular/router';
import { loadRemoteModule } from '@nx/angular/mf';
import {
  WebComponentWrapper,
  WebComponentWrapperOptions,
} from '@angular-architects/module-federation-tools';
import { NotFoundError } from 'rxjs';
import { HomeComponent } from './home/home.component';

export const appRoutes: Route[] = [
  {
    path: '',
    component: HomeComponent,
  },
  {
    path: 'microfront-angular',
    loadChildren: () =>
      loadRemoteModule('microfront-angular', './Module').then(
        (m) => m.RemoteEntryMfNg
      ),
  },
  {
    path: 'microfront-react',
    component: WebComponentWrapper,
    data: {
      // type: 'module',
      remoteEntry:
        'http://localhost:4301/remoteEntry.js',
      remoteName: 'microfront-react',
      elementName: 'microfront-react',
      exposedModule: './Module',
    } as WebComponentWrapperOptions,
  },
  {
    path: 'react',
    component: WebComponentWrapper,
    data: {
      remoteEntry:
        'https://witty-wave-0a695f710.azurestaticapps.net/remoteEntry.js',
      remoteName: 'react',
      elementName: 'react-element',
      exposedModule: './web-components',
    } as WebComponentWrapperOptions,
  },
  {
    path: 'vue',
    component: WebComponentWrapper,
    data: {
      remoteEntry:
        'https://mango-field-0d0778c10.azurestaticapps.net/remoteEntry.js',
      remoteName: 'vue',
      exposedModule: './web-components',
      elementName: 'vue-element',
    } as WebComponentWrapperOptions,
  },
  {
    path: '**',
    component: NotFoundError,
  },
];

字符串

  • microfront-react* dont'works but react works

当尝试访问 microfront-react 时会发生这种情况
x1c 0d1x的数据
但我仍然看到 * remoteEntry.js * 从我的构建网络...



创建我的React microfront的命令是:

nx g @nx/react:host host-react --remotes=microfront-react --style=scss


My apps/microfront-react/src/bootstrap.tsx

import { StrictMode } from 'react';
import * as ReactDOM from 'react-dom/client';

import App from './app/app';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

class MfeReact extends HTMLElement {
  connectedCallback() {
    console.log('web-component: bootstrap.tsx');

    root.render(
      <StrictMode>
        <App />
      </StrictMode>
    );
  }
}

customElements.define('microfront-react', MfeReact);


我想可能是我的 microfront-react 中的 * webpack.config.js * 和 * module-federation.config.js * 失败了

  • webpack.config.js*
const { composePlugins, withNx } = require('@nx/webpack');
const { withReact } = require('@nx/react');
const { withModuleFederation } = require('@nx/react/module-federation');

const baseConfig = require('./module-federation.config');

const config = {
  ...baseConfig,
};

// Nx plugins for webpack to build config object from Nx options and context.
module.exports = composePlugins(
  withNx(),
  withReact(),
  withModuleFederation(config)
);

  • module-federation.config.js*
module.exports = {
  name: 'microfront-react',
  filename: 'remoteEntry.js',
  exposes: {
    './web-components': './src/remote-entry.ts',
  }
};


有了这些行就足以正确地打包remoteEntry.js了吗?
希望这有助于理解我的问题,并感谢所有的人!!!
来源和THX:
Angular-architects Lerna
Nx

atmip9wb

atmip9wb1#

您正在Angular应用程序中添加WebComponentWrapper类型的远程入口。也许你的React微前端需要打包成一个Web组件?

yvgpqqbh

yvgpqqbh2#

我解决了!
需要在 bootstrap.tsx 上创建一个 customElements

import React from 'react';
import ReactDOM from 'react-dom';

import App from './app/app';

class Mfe4Element extends HTMLElement {
  connectedCallback() {
    console.log('http-mfe-react-element connectedCallback from DOM');

    window.React = React;
    ReactDOM.render(<App />, this);
  }

  disconnectedCallback() {
    console.log('http-mfe-react-element disconnectedCallback from DOM');
  }
}

customElements.define('http-mfe-react-element', Mfe4Element);

字符串
并在 * webpack.config.js * 上创建一个适当的配置

const { composePlugins, withNx } = require('@nx/webpack');
const { withReact } = require('@nx/react');

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

const path = require('path');

const webpackEntry = [
  path.resolve(__dirname, './src/index.html'),
  path.resolve(__dirname, './src/main.tsx'),
];

const webpackOutput = {
  publicPath: 'auto',
  path: path.resolve(__dirname, '../../dist/apps/http-mfe-react'),
};

const webpackModuleFederationPlugin = new ModuleFederationPlugin({
  name: 'http_mfe_react',
  library: { type: 'var', name: 'http_mfe_react' },
  filename: 'remoteEntry.js',
  exposes: {
    './web-components': path.resolve(__dirname, './src/bootstrap.tsx'),
  },
  shared: ['react', 'react-dom'],
});

const ruleForTsx = {
  test: /\.tsx$/,
  exclude: /node_modules/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        cacheDirectory: true,
        presets: ['@babel/react', '@babel/env'],
      },
    },
  ],
};
const ruleForMisc = {
  test: /\.(png|jpe?g|gif|woff|svg|eot|ttf)$/i,
  use: ['file-loader'],
};
const ruleForHtml = {
  test: /\.html$/,
  use: ['file-loader?name=[name].[ext]'],
};
const ruleForStyles = {
  test: /\.(s[ac]ss|\.css)$/,
  use: ['style-loader', 'css-loader', 'postcss-loader'],
};

const webpackRules = [ruleForTsx, ruleForMisc, ruleForHtml, ruleForStyles];

const webpackExtensions = ['.tsx', '.ts', '.js'];

// Nx plugins for webpack.
module.exports = composePlugins(withNx(), withReact(), (config) => {
  // Update the webpack config as needed here.
  // e.g. `config.plugins.push(new MyPlugin())`

  config.entry = webpackEntry;
  config.output = webpackOutput;
  config.plugins.push(webpackModuleFederationPlugin);
  config.optimization.runtimeChunk = false; // Only needed to bypass a temporary bug
  config.module.rules = webpackRules;
  config.resolve.extensions = webpackExtensions;

  return config;
});


希望它能帮助到某人。

相关问题