How to Call Vue component inside React Micro Frontend using WebPack 5

25 views Asked by At

I have started to learn micro frontend. First, I have create a react mf project Micro-Shell-App using npx create-mf-app. Second, I have created again vue mf project that is named SectionPart using same npx code. I want to share an any vue component with react shell app. How can I do it ? I am trying something but i did not find a solution. I am facing error like:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Do you have any advice to me? Thanks from now.

Here is folder structure:

enter image description here

MyComponent.vue:

<template>
  <div>
    <h2>Hello, {{ name }}!</h2>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'World'
    };
  }
};
</script>

SectionPart webpack.config.js:

// some imports
module.exports = (_, argv) => ({
  output: {
    publicPath: "http://localhost:3003/",
  },

  resolve: {
    extensions: [".tsx", ".ts", ".vue", ".jsx", ".js", ".json"],
  },

  devServer: {
    port: 3003,
    historyApiFallback: true,
  },

  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: "vue-loader",
      },
      {
        test: /\.tsx?$/,
        use: [
          "babel-loader",
          {
            loader: "ts-loader",
            options: {
              transpileOnly: true,
              appendTsSuffixTo: ["\\.vue$"],
              happyPackMode: true,
            },
          },
        ],
      },
      {
        test: /\.(css|s[ac]ss)$/i,
        use: ["style-loader", "css-loader", "postcss-loader"],
      },
    ],
  },

  plugins: [
    new VueLoaderPlugin(),
    new ModuleFederationPlugin({
      name: "SectionPart",
      filename: "remoteEntry.js",
      remotes: {
       
      },
      exposes: {
        "./MyComponent":"./src/components/MyComponent.vue",
      },
      shared: require("./package.json").dependencies,
    }),
    new HtmlWebPackPlugin({
      template: "./src/index.html",
    }),
    new Dotenv()
  ],
});

Micro Shell App webpack.config.js:

// some imports 

module.exports = (_, argv) => ({
  output: {
    publicPath: "http://localhost:3000/",
  },

  resolve: {
    extensions: [".tsx", ".ts", ".jsx", ".js", ".json"],
  },

  devServer: {
    port: 3000,
    historyApiFallback: true,
  },

  module: {
    rules: [
      {
        test: /\.m?js/,
        type: "javascript/auto",
        resolve: {
          fullySpecified: false,
        },
      },
      {
        test: /\.(css|s[ac]ss)$/i,
        use: ["style-loader", "css-loader", "postcss-loader"],
      },
      {
        test: /\.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.vue$/,
        loader: "vue-loader",
        exclude: /node_modules/
    }
    ],
  },

  plugins: [
    new ModuleFederationPlugin({
      name: "Micro_Shell_App",
      filename: "remoteEntry.js",
      remotes: {
        section:"SectionPart@http://localhost:3003/remoteEntry.js"
      },
      exposes: {},
      shared: {
        ...deps,
        react: {
          singleton: true,
          requiredVersion: deps.react,
        },
        "react-dom": {
          singleton: true,
          requiredVersion: deps["react-dom"],
        },
      },
    }),
    new HtmlWebPackPlugin({
      template: "./src/index.html",
    }),
    new VueLoaderPlugin(),
    new Dotenv()
  ],
});

App.jsx at Shell:

import React from "react";
import ReactDOM from "react-dom";
import MyComponent from "section/MyComponent"

const App = () => (
 
    <MyComponent />
  
);
ReactDOM.render(<App />, document.getElementById("app"));
0

There are 0 answers