Error Report: cannot compile child components of asynchronous components
Version
3.2.20
Reproduction link
Steps to reproduce
cd vue3
npm install
npm start
cd vue2
npm install
npm start
What is expected?
Components are resolved recursively expected dom tree
<div>
<span>my outer component</span>
<div>hello world</div>
</div>
What is actually happening?
Only the outermost component is parsed, and the sub-components are not parsed correctly,which results in a dom node like this
<div>
<span>my outer component</span>
<hello-world></hello-world>
</div>
the same problem in https://github.com/vuejs/vue-next/issues/4799;
On first look, without running it, I'd say you forgot to exclude Vue from the federated bundle / declaring Vue as shared dependebcy in the federation, ending up with two copies of Vue in your final app.
It will end up being about something of that nature.
I just ran the Vue 3 example wih npm start
and this is what I see:
Looks like everything is working?
For the record though, like with react, you likely want your mofed config to declare Vue as a shared dependency:
const moduleFederationConfig = {
name: AssetMatrixModule.name,
filename: AssetMatrixModule.fileName,
exposes: {
"./Main": "./src/pages/main.vue",
},
remotes: {},
shared: {
vue: {
singleton: true,
eager: true,
},
},
};
I just ran the Vue 3 example wih
npm start
and this is what I see:Looks like everything is working?
For the record though, like with react, you likely want your mofed config to declare Vue as a shared dependency:
const moduleFederationConfig = { name: AssetMatrixModule.name, filename: AssetMatrixModule.fileName, exposes: { "./Main": "./src/pages/main.vue", }, remotes: {}, shared: { vue: { singleton: true, eager: true, }, }, };
Hi, thanks for your reply. The Vue3 demo works well, while when it is used in Vue2, it cannot compile the child component, that is the question i am trying to resolve. And i have tried the shared configuration, but it not works for me. Maybe vue2 cannot use vue3 components? Or is there some other ways for using vue3 components in vue2? Hope to get your advice.
I see, that wasn't really clear to me.
The underlying issue is likely the same though. In the console you see these warnings:
[Vue warn]: resolveComponent can only be used in render() or setup(). [Vue warn]: withDirectives can only be used inside render functions.
These indicate that the imported Vue 3 component uses another copy of the vue package than the consuming application. Vue 3 internally relies on some singleton values though (similar to react), so you need to have one shared copy in the consuming app.
The problem here is likely that in the consuming app, Vue 3 is aliased as "vue3"
, and "vue"
points to Vue 2, while the federated module uses "vue"
for the Vue 3 package.
There might be a way to solve this with some combination of sharing hint options, but that is outside of my expertise and outside of the scope of this repository to solve.
https://webpack.js.org/plugins/module-federation-plugin/#sharing-hints
I see, that wasn't really clear to me.
The underlying issue is likely the same though. In the console you see these warnings:
[Vue warn]: resolveComponent can only be used in render() or setup(). [Vue warn]: withDirectives can only be used inside render functions.
These indicate that the imported Vue 3 component uses another copy of the vue package than the consuming application. Vue 3 internally relies on some singleton values though (similar to react), so you need to have one shared copy in the consuming app.
The problem here is likely that in the consuming app, Vue 3 is aliased as
"vue3"
, and"vue"
points to Vue 2, while the federated module uses"vue"
for the Vue 3 package.There might be a way to solve this with some combination of sharing hint options, but that is outside of my expertise and outside of the scope of this repository to solve.
https://webpack.js.org/plugins/module-federation-plugin/#sharing-hints
Hi, thanks a lot for your reply. And i have resolved the problem by setting the module federation shared options, and changed the vue3 dependency of vue to vue3. The config files as follows, in vue2,
const moduleFederationConfig = {
name: FinderWebClientModule.name,
filename: FinderWebClientModule.fileName,
exposes: {},
remotes: {},
shared: {
vue3: {
singleton: true,
},
},
}
in vue3,
const moduleFederationConfig = {
name: AssetMatrixModule.name,
filename: AssetMatrixModule.fileName,
exposes: {
'./Main': './src/pages/main.vue',
},
remotes: {},
shared: {
vue3: {
singleton: true,
eager: true,
},
},
};
and the dependency in package.json of vue3
"vue": "^3.2.20", -> "vue3": "npm:vue@^3.2.20",
And thank you very much for the advice!