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:
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"));
