Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReferenceError: Cannot access '__vite_ssr_import_0__' before initialization when using mocks #1084

Closed
6 tasks done
gdorsi opened this issue Apr 3, 2022 · 16 comments · Fixed by #1098
Closed
6 tasks done

Comments

@gdorsi
Copy link
Contributor

gdorsi commented Apr 3, 2022

Describe the bug

I get the ReferenceError: Cannot access '__vite_ssr_import_0__' before initialization when i try to use the API vi.mock.

Reproduction

This is a failing workflow: https://github.com/gdorsi/vite-mock-error-repro/runs/5804962645?check_suite_focus=true

This is the test file: https://github.com/gdorsi/vite-mock-error-repro/blob/redaxios/frontend/src/components/LoginForm/LoginForm.test.jsx

This is the repro: https://github.com/gdorsi/vite-mock-error-repro

System Info

System:
    OS: macOS 11.6
    CPU: (8) arm64 Apple M1
    Memory: 186.25 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.13.1 - ~/.volta/tools/image/node/16.13.1/bin/node
    Yarn: 3.1.1 - ~/.volta/tools/image/yarn/1.22.17/bin/yarn
    npm: 8.1.2 - ~/.volta/tools/image/node/16.13.1/bin/npm
  Browsers:
    Chrome: 100.0.4896.60
    Firefox: 98.0.2
    Safari: 14.1.2
  npmPackages:
    @vitejs/plugin-react: ^1.3.0 => 1.3.0 
    vite: ^2.9.1 => 2.9.1 
    vitest: ^0.8.2 => 0.8.2

Used Package Manager

yarn

Validations

@sheremet-va
Copy link
Member

sheremet-va commented Apr 3, 2022

Vitest is hoisting vi.mock to top of the file, so it doesn't have access to imported variables. We usually bypass it by also hoisting imports from vitest, but you moved it to another file.

So there are several workarounds to this:

  • import vi from vitest
  • enable globals options
  • use vi.doMock (it doesn't get hoisted), but you would need to move it before mocked import:
import { render, screen, expect, describe, it, vi, userEvent, waitFor } from '../../test-utils'
vi.doMock('redaxios')
import LoginForm from './LoginForm' // LoginForm also uses `axios`
import axios from 'redaxios'

@gdorsi
Copy link
Contributor Author

gdorsi commented Apr 4, 2022

Thanks for the answer!

I've fixed the issue by importing directly vi from vitest.

I'd like to try to work on a PR to fix this issue.

Should we try to hoist the related import declaration, instead limiting the hoist to vitest?
Or it's better to simply work on a better error message?

@sheremet-va
Copy link
Member

sheremet-va commented Apr 4, 2022

No, I don't think it's safe to hoist other "potential" imports. I think the current solution works as expected.

Maybe better error message would be preferable

@dudintv
Copy link

dudintv commented Mar 1, 2023

I still have the issue. Vitest v0.29.2:

ReferenceError: Cannot access '__vite_ssr_import_2__' before initialization
 ❯ components/content/media/MediaImage.spec.ts:3:27
      1| import { expect } from 'vitest';
      2| import { mount } from '@vue/test-utils';
      3| import { mockRoutePath } from './testUtils';
                                   ^

there is highlighted "from" on line #3

I've just created a common utility function with route mocking:

// testUtils.ts
import { vi } from 'vitest';

export function mockRoutePath(path: string) {
  return () => ({
    useRoute: vi.fn().mockImplementation(() => ({
      path,
    })),
  });
}

@gdorsi
Copy link
Contributor Author

gdorsi commented Mar 2, 2023

@dudintv

This error is related to the usage of vi.mock, where are you using it?

@dudintv
Copy link

dudintv commented Mar 2, 2023

@dudintv

This error is related to the usage of vi.mock, where are you using it?

@gdorsi
You're right. I didn't know that vi.mock is hoisted by Vitest (like Jest does). The error message is confusing.

Btw, is there any working way to make a "common" function using vi.mock?

@gdorsi
Copy link
Contributor Author

gdorsi commented Mar 2, 2023

There is a bug actually, the fix I did should provide a user friendly error but it isn't catching your case.

Could you share more code about how you are using vi.mock?

The general advice to fix this issue is either:

  • switch to the vitest globals
  • when using vi.mock import vi directly from vitest

@grundmanise
Copy link

grundmanise commented Mar 6, 2023

Just wanted to share the behaviour I've observed that is related to the same error:

vi.mock("react-router-dom", async (importOriginal) => {
  const actual = await importOriginal()
  return {
    ...actual,
    useHistory: () => ({/*...*/}),
  }
})

When the mock factory returns a promise (async is used) - Vitest errors with the message ReferenceError: Cannot access '__vite_ssr_import_0__' before initialization. Globals are used, and vitest@0.29.2. There might be some misconfiguration somewhere which I can not figure out yet. But just wanted to highlight that fix is not always "globals" or "direct imports" - it can be something else.

It works completely fine when vi.doMock is used instead.

@dudintv
Copy link

dudintv commented Mar 6, 2023

@gdorsi
actually, I posted all involved code :)
The rest doesn't matter, I think. I can post the whole files:

// testUtils.ts
import { vi } from 'vitest';

export function mockRoutePath(path: string) {
  return () => ({
    useRoute: vi.fn().mockImplementation(() => ({
      path,
    })),
  });
}
// mediaImage.spec.ts
import { expect } from 'vitest';
import { mount } from '@vue/test-utils';
import { mockRoutePath } from './testUtils';

import MediaFile from './MediaImage.vue';

const path = '/path';
const name = 'image.png';
const imagesPublicFolder = 'images';

vi.mock('vue-router', mockRoutePath(path) );

describe('MediaFile', async () => {
  const wrapper = mount(MediaFile, {
    props: {
      name,
    },
  });

  it('has correct image url', () => {
    const imageSrc = wrapper.find('img').element.src;
    const expectImageSrc = `http://${window.location.host}/${imagesPublicFolder}${path}/${name}`;
    expect(imageSrc).toEqual(expectImageSrc);
  });

@gdorsi
Copy link
Contributor Author

gdorsi commented Mar 6, 2023

@dudintv Looking at the posted files seems that you are not importing vi in mediaImage.spec.ts

@dudintv
Copy link

dudintv commented Mar 6, 2023

@dudintv Looking at the posted files seems that you are not importing vi in mediaImage.spec.ts

Correct, I use global "vi" in spec files

@yagiz-noonlight
Copy link

Any updates on this? I'm having the same exact issue.

@gdorsi
Copy link
Contributor Author

gdorsi commented Apr 4, 2023

@dudintv @yagiz-noonlight

If you give me a repro of the issue I can find the time to work on this one.

@dudintv
Copy link

dudintv commented Apr 6, 2023

@gdorsi
Copy link
Contributor Author

gdorsi commented Apr 8, 2023

Created a dedicated issue with a minimal repro --> #3152

@joshmedeski
Copy link

I was having this issue in my GitHub action and upgrading to vitest@0.31.0 fixed it 😄

@github-actions github-actions bot locked and limited conversation to collaborators Jun 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
6 participants