Subscribe on changes!

HMR does not work when importing shared components

avatar
May 10th 2022

Version

3.2.33

Reproduction link

github.com

Steps to reproduce

  1. $ git clone git@github.com:martinszeltins/vue-shared-components-hmr.git

important to use yarn because of package linking

  1. $ cd shared && yarn

  2. $ cd ../my-vue-app && yarn && yarn dev

  3. Now open http://localhost:3000/

  4. Now open my-vue-app/src/App.vue and change the text inside <div> or the msg prop text to something else.

  5. Now save App.vue file and you will see that HMR did not update the UI (!)

  6. Now refresh the page and you will see the updates.

  7. But if you open my-vue-app/src/main.js and remove the import 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.

avatar
May 14th 2022

Maybe fixed with this Pull requests.

avatar
May 31st 2022

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.

avatar
Nov 10th 2022

The reason is that your app is actually loading two different copies of Vue.

  1. Both your my-vue-app and shared directory lists vue as dependency, and they are installed separately
  2. node_modules resolution resolves dependency closest to the file being processed. This is necessary because technically you can specify different versions of vue in your two directories. This resolution algorithm is followed by all mainstream bundlers.
  3. For the same import { * } from 'vue' statement, files in my-vue-app will be importing from its copy of Vue, while files in shared 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.