Vite + Cypress:如何防止重新加载(由于优化的依赖关系)导致测试失败?

huangapple go评论66阅读模式
英文:

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

问题

运行 Cypress 组件测试时,有时会遇到以下问题:

    17:34:59 [vite] ✨ 新的依赖已优化: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] ✨ 优化的依赖已更改。重新加载

    1) 检测到一个未捕获的错误,位于测试之外

测试失败… 如果我第二次重新运行测试,一切都没问题:所有测试通过。
有什么方法可以预防这种情况发生吗?

我的 `cypress.config.ts` 非常简单:

    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
        },
      },
    })

我的 `vite.config.ts` 也是这样的:

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

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'],
  },
 }
})

答案1

得分: 7

我遇到了类似的问题,我的 Cypress 测试仅在 Firefox 上失败,显示 "TypeError: error loading dynamically imported module"。

从你的 vite.config.ts 文件中,我看到你正在使用 vite-plugin-vuetify

根据 Vite 文档

optimizeDeps.includeoptimizeDeps.exclude 的典型用例是当你有一个导入,它在源代码中不是直接可发现的。例如,也许这个导入是由插件变换的结果创建的。这意味着 Vite 在初始扫描时无法发现这个导入 - 它只能在浏览器请求文件并进行变换后才能发现它。这将导致服务器在启动后立即重新捆绑。

includeexclude 都可以用来处理这个问题。如果依赖项很大(具有许多内部模块)或是 CommonJS,那么你应该包含它;如果依赖项很小且已经是有效的 ESM,则可以排除它,让浏览器直接加载它。

所以解决方案是:

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

听起来包含而不是排除可能更合理,因为 Vuetify 可能被认为很大,但我发现只有排除对我有效。

你可能还需要对 @vueuse/core 做同样的操作。

另外,如果你使用单文件组件,你可能还需要考虑在 optimizeDeps.entries 中包含 .vue 文件,以便 Vite 知道需要遍历它们以查找依赖关系,就像下面这样:

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

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}'],

答案2

得分: 1

在我的情况下,导致依赖项被优化的库是antd

我尝试了几种不同的Vite的optimizeDeps选项,但都不适用于我。

相反,我所做的是找到所有antd的导入并将它们更改为从antd/es导入。

在你的情况下,我怀疑将你的vuetify导入更改为使用dist而不是lib子文件夹将解决问题。

所以,不是:

import { whatever } from 'vuetify/**lib**/whatever';

你可以尝试:

import { whatever } from 'vuetify/**dist**/whatever';
英文:

In my case the library that was causing the dependencies to be optimized was antd.

I tried several different optimizeDeps options for Vite but none of them worked for me.

What I did instead was to find all imports of antd and change them to import from antd/es instead.

In your case I suspect that changing your vuetify imports to use dist instead of lib subfolder will fix the issue.

So instead of:

import { whatever } from 'vuetify/**lib**/whatever'

You could try:

import { whatever } from 'vuetify/**dist**/whatever'

huangapple
  • 本文由 发表于 2023年2月16日 15:33:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75469067.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定