Search code examples
vue.jscypressvuetify.jsvite

Vite + Cypress : how to prevent reloading (due to optimized dependencies) causing the test to fail?


When I'm running Cypress component test, sometimes i'm facing this :

17:34:59 [vite] ✨ new dependencies optimized: vuetify/components, vuetify/lib/components/VAppBar/index.mjs, vuetify/lib/components/VDivider/index.mjs, vuetify/lib/components/VToolbar/index.mjs, @vueuse/core
17:34:59 [vite] ✨ optimized dependencies changed. reloading

1) An uncaught error was detected outside of a test

And the test fails... If I relaunch tests a second time, everything is ok : all tests pass. Anything I can do to prevent this ?

My cypress.config.ts is quite simple :

export default defineConfig({
  video: false,
  env: {
    codeCoverage: {
      exclude: ['cypress/**/*.*', 'src/**/*.cy.ts'],
    },
  },
  component: {
    devServer: {
      framework: 'vue',
      bundler: 'vite',
    },
    setupNodeEvents(on, config) {
      registerCodeCoverageTasks(on, config)

      return config
    },
  },
})

So do my vite.config.ts :

export default defineConfig({
  plugins: [
    vue(), // SFC
    vuetify({
      autoImport: true,
    }),
    istanbul({
      cypress: true,
      requireEnv: false,
    }),
  ],
 resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
    },
    extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'],
  },
 }
})

Solution

  • I faced a similar problem where my Cypress tests were failing on Firefox only with "TypeError: error loading dynamically imported module".

    Looking at your vite.config.ts I see you're using vite-plugin-vuetify.

    From the Vite docs:

    A typical use case for optimizeDeps.include or optimizeDeps.exclude is when you have an import that is not directly discoverable in the source code. For example, maybe the import is created as a result of a plugin transform. This means Vite won't be able to discover the import on the initial scan - it can only discover it after the file is requested by the browser and transformed. This will cause the server to immediately re-bundle after server start.

    Both include and exclude can be used to deal with this. If the dependency is large (with many internal modules) or is CommonJS, then you should include it; If the dependency is small and is already valid ESM, you can exclude it and let the browser load it directly.

    So the solution is

    // vite.config.ts
    export default defineConfig({
      ...,
      optimizeDeps: {
        exclude: ['vuetify'],
        // or include: ['vuetify'], ?
      },
    

    It sounds like it would make more sense to include rather than exclude as Vuetify is probably considered large, but I found that only exclude works for me.

    You may also need to do the same for @vueuse/core.


    P.S. You might also want to look at including .vue files in optimizeDeps.entries so Vite knows it needs to crawl them to find dependencies, if you are using single file components. Something like

      optimizeDeps: {
        entries: ['./src/**/*.{vue,js,jsx,ts,tsx}'],