HMR does not work when importing shared components
Version
3.2.33
Reproduction link
Steps to reproduce
$ git clone git@github.com:martinszeltins/vue-shared-components-hmr.git
important to use yarn because of package linking
$ cd shared && yarn
$ cd ../my-vue-app && yarn && yarn dev
Now open
http://localhost:3000/
Now open
my-vue-app/src/App.vue
and change the text inside<div>
or themsg
prop text to something else.Now save
App.vue
file and you will see that HMR did not update the UI (!)Now refresh the page and you will see the updates.
But if you open
my-vue-app/src/main.js
and remove theimport Shared from 'shared/src/main'
and.use(Shared)
then HMR will work.
What is expected?
It is expected that when you change a component the HMR will update the UI without having to do a full page refresh.
What is actually happening?
HMR is not updating the UI after changes.
So the problem seems to be that I am trying to use a shared component. If you do not try to use a shared component then it works.
Maybe fixed with this Pull requests.
I am running into exact same issue while trying to use a remote micro app (based on vuejs) inside another vuejs app which is a full fledged vuejs application. Strange thing is that this setup is working fine with Vue CLI (but for a vuejs 2 application).
Another issue which I have observed is that it will skip main vuejs application's entry file in production mode if there is any other entry file ( belonging to a micro app) in index.html file but same thing is working fine in development mode. This is how my index.html file looks like -
<script type="module" src="/src/main.ts"></script>
<script type="module" src="/micro-apps/app1/src/app1.ts"></script>
<script type="module">
window.appContext.app.mount('#app')
</script>
Actually vite build will not even work unless I add following in vite.config.ts file -
build: {
rollupOptions: {
external: [
"/micro-apps/app1/src/app1.ts"
]
}
}
So it seems Vite is behaving differently between development and production modes.
The reason is that your app is actually loading two different copies of Vue.
- Both your
my-vue-app
andshared
directory listsvue
as dependency, and they are installed separately node_modules
resolution resolves dependency closest to the file being processed. This is necessary because technically you can specify different versions ofvue
in your two directories. This resolution algorithm is followed by all mainstream bundlers.- For the same
import { * } from 'vue'
statement, files inmy-vue-app
will be importing from its copy of Vue, while files inshared
will be importing from a different copy. This can cause all kinds of issues not limited to HMR, and should be avoided.
You should (1) use a monorepo solution to avoid node_modules
duplication, and if that does not help, (2) configure an alias in your app's vite.config.js
to ensure vue
always resolve to the same copy.