Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module federation shared #13451

Closed
Tarrowren opened this issue May 27, 2021 · 7 comments
Closed

module federation shared #13451

Tarrowren opened this issue May 27, 2021 · 7 comments

Comments

@Tarrowren
Copy link

Bug report

What is the current behavior?

Vue does not use the same source.

[Vue warn]: $attrs is readonly.
[Vue warn]: $listeners is readonly.

If the current behavior is a bug, please provide the steps to reproduce.

package.json

"dependencies": {
  "core-js": "^3.13.0",
  "vue": "^2.6.12"
},
"devDependencies": {
  "@vue/cli-plugin-babel": "^5.0.0-beta.1",
  "@vue/cli-plugin-typescript": "^5.0.0-beta.1",
  "@vue/cli-service": "^5.0.0-beta.1",
  "typescript": "^4.3.2",
  "vue-template-compiler": "^2.6.12",
  "webpack": "^5.37.1"
}

chunk/Hello.vue

<template>
  <div>remote: {{ msg }}</div>
</template>

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
  name: "Hello",
  props: {
    msg: String
  },
  mounted() {
    console.log("remote: " + (this as any).$hello);
  }
});
</script>

chunk/vue.config.js

const { ModuleFederationPlugin } = require("webpack").container;

module.exports = {
  publicPath: "http://localhost:3001/",
  configureWebpack: {
    plugins: [
      new ModuleFederationPlugin({
        name: "chunk",
        filename: "remoteEntry.js",
        exposes: { "./Hello.vue": "./src/components/Hello.vue" },
        shared: ["core-js", "vue"]
      })
    ]
  },
  devServer: {
    port: 3001,
    headers: { "Access-Control-Allow-Origin": "*" }
  }
};

core/App.vue

<template>
  <div>
    core
    <input type="text" v-model="msg" />
    <Hello :msg="msg" />
  </div>
</template>

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
  name: "App",
  components: {
    Hello: () => import("chunk/Hello.vue")
  },
  data() {
    return {
      msg: "sth.."
    };
  },
  mounted() {
    console.log("core: " + (this as any).$hello);
  }
});
</script>

core/main.ts

import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;
Vue.prototype.$hello = "hello";

new Vue({
  render: (h) => h(App)
}).$mount("#app");

core/vue.config.js

const { ModuleFederationPlugin } = require("webpack").container;

module.exports = {
  configureWebpack: {
    plugins: [
      new ModuleFederationPlugin({
        name: "core",
        remotes: { chunk: "chunk@http://localhost:3001/remoteEntry.js" }
      })
    ]
  },
  devServer: {
    port: 3000
  }
};

type the text

image

What is the expected behavior?

output:

core: hello
remote: hello

and no error.

Other relevant information:

webpack version: 5.37.1
Node.js version: 14.16.1
Operating System: windows10
Additional tools: vue2

@webpack-bot
Copy link
Contributor

For maintainers only:

  • webpack-4
  • webpack-5
  • bug
  • critical-bug
  • enhancement
  • documentation
  • performance
  • dependencies
  • question

@alexander-akait
Copy link
Member

Sorry, not related to webpack, this error from vue, better to ask vue community how better to implement this, here example for vu3 https://github.com/module-federation/module-federation-examples/tree/master/vue3-demo (maybe help)

@Tarrowren
Copy link
Author

give you another example:

core

import axios from "axios";

export default function () {
  console.log(axios.defaults.timeoutErrorMessage);
}

consumer

import axios from "axios";

axios.defaults.timeoutErrorMessage = "hello";

import("./local").then((v) => {
  v.default();
});
import("core/remote").then((v) => {
  v.default();
});

consumer/local

import axios from "axios";

export default function () {
  console.log(axios.defaults.timeoutErrorMessage);
}
{
  ...
  shared: ["axios"],
};

output:

hello
undefined

expect:

hello
hello

is my understanding of the "shared" field wrong? Or where else do I need to configure?

@alexander-akait
Copy link
Member

Modify axios.defaults.timeoutErrorMessage is not safe, because you have shared module

@Tarrowren
Copy link
Author

Vue3 has the same problem
vuejs/core#2884

@alexander-akait
Copy link
Member

@Tarrowren

That's a good indicator that the issue is fro having two distinct copies of vue included in the bundle (from the two node_modules folders.

it means you need search place where you use two copies vue, maybe you have it in global scope

@Tarrowren
Copy link
Author

End problem

first, "shared" field should be configured for all project.
second, asynchronous use of shared modules.

// bootstrap.ts;
import { createApp } from "vue";
import App from "./App";

createApp(App).mount("#app");
// main.ts
import("./bootstrap");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants