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

Vue-I18n not loaded #566

Closed
Floppy012 opened this issue Apr 12, 2023 · 18 comments
Closed

Vue-I18n not loaded #566

Floppy012 opened this issue Apr 12, 2023 · 18 comments

Comments

@Floppy012
Copy link

Floppy012 commented Apr 12, 2023

I'm currently trying to implement component tests for a component that uses vue-i18n and I'm getting this error:

SyntaxError: Need to install with `app.use` function
 - /var/www/html/node_modules/@intlify/core-base/node_modules/@intlify/message-compiler/dist/message-compiler.cjs.js:58:19
 - /var/www/html/node_modules/vue-i18n/dist/vue-i18n.runtime.esm-bundler.js:105:34
 - /var/www/html/node_modules/vue-i18n/dist/vue-i18n.runtime.esm-bundler.js:2224:15
 - /components/metronic/form/Input.vue:326:1
 - /var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:171:22
 - /var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7194:29
 - /var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7149:11
 - /var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:13
 - /var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5455:17
 - /var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5059:21

I have @intlify/nuxt3 configured in my nuxt.config.ts:

export default defineNuxtConfig({
    modules: ["@pinia/nuxt", "@nuxtjs/tailwindcss", "@intlify/nuxt3", "@nuxtjs/google-fonts", "@vueuse/nuxt", "nuxt-vitest"],
    intlify: {
        localeDir: "locales",
        vueI18n: {
            locale: "de",
        },
    },
// ...

I'm working around this problem by manually using createI18n in my setup file and adding it to the global plugins of vue test-utils:

import { config } from '@vue/test-utils';
import { createI18n } from 'vue-i18n';

config.global.plugins.push(
    createI18n({
        locale: 'de',
        legacy: false,
    })
);

Then, since I'm also testing using @testing-library/vue which has another bug, I also have to use the workaround described there to also get the plugin working for testing-library.

I know there is nobody to blame but component tests are DX-wise very bad. I have to invest more time into getting the tests to actually work, than writing them :/

@Floppy012 Floppy012 changed the title Plugins not loaded Plugins/Modules not loaded Apr 12, 2023
@Floppy012 Floppy012 changed the title Plugins/Modules not loaded Vue-I18n not loaded Apr 13, 2023
@QozbroQqn
Copy link

I know your pain because I feel it too. I am trying to put together a test environment for nearly 4 days now. And I thought Codeception with Selenium in a docker was hard.

Here is a SO link someone might find interesting: Mock i18n

Unfortunately none of the answers in that SO question helps me. I try to mock the i18n. I see no sense in checking for "the right translation" but this is ofcourse opinionated. The strange thing is, that mocking actually sometimes work. But if I hit rerun on the test, it doesn't anymore and I get:

TypeError: $setup.t is not a function

If others want to try, here is my setup which "SOMETIMES" work:

// ./tests/nuxt/yourTestFile.spec.ts 
// ./tests/nuxt/yourTestFile.nuxt.spec.ts (nuxt environment)

vi.mock('vue-i18n');

useI18n.mockReturnValue({
  t: (tKey: string) => tKey,
});

describe('Test description', () => {
  // ...
}
// ./tests/setupFiles/i18n.ts
import { config } from '@vue/test-utils';
import { createI18n } from 'vue-i18n';

config.global.plugins.push(createI18n({
  legacy: false,
}));

config.global.mocks.$t = (key: string) => key;
config.global.mocks.t  = (key: string) => key;
// vitest.config.ts
import { defineVitestConfig } from 'nuxt-vitest/config';

export default defineVitestConfig({
  test: {
    globals   : true,
    setupFiles: [ './tests/setupFiles/i18n.ts' ],
  },
});

As I said it sometimes work and sometimes not. It could help if you comment out legacy: false and rerun the test. If it not work, trying to comment in legacy: false and rerun. It seems to be an async load behaviour or race condition.

@Floppy012
Copy link
Author

Without legacy: false it threw an error in my case.

One thing I would try before changing everything would be to actually initialize i18n like I do now and try to mock the functions of the i18n instance:

vi.spyOn(i18n.global, 't').mockImplementation((tKey) => String(tKey));

@QozbroQqn
Copy link

Good luck with that. I am sick and tired of trying. And if you ever get a working real world testing environment, I beg you to share it. Maybe here #137.

I also use @testing-library/vue but vitest fails to load the vuetify components. So all I can currently do is using $fetch and stick with unit testing composables.

@Floppy012
Copy link
Author

@QozbroQqn I made a minimal stackblitz project with the way I'm working with it. Maybe it helps: https://stackblitz.com/edit/nuxt-starter-bjyxnr

@QozbroQqn
Copy link

Thank you. If you have the time and could test vuetify, that would be awesome. Maybe you see something I don't.

And is there a reason why you use intlify instead of nuxt i18n module V8?

@Floppy012
Copy link
Author

If you have the time and could test vuetify, that would be awesome. Maybe you see something I don't.

I tried some things and they didn't work. I guess there is another (component related) problem in addition to the normal problem, that plugins don't load. Sorry :/

And is there a reason why you use intlify instead of nuxt i18n module V8?

Not really. It was the one that worked at the time I set it up for my project.

@QozbroQqn
Copy link

Thank you for your trying. Guess I just have to wait.

@danielroe
Copy link
Member

Would you see if 0.6.12 resolved the issue for you? If not, would you provide a reproduction?

@QozbroQqn
Copy link

Thank you for your hard work @danielroe.

@Floppy012 made a minimal example:https://stackblitz.com/edit/nuxt-starter-bjyxnr

You just need to remove the setup file from vitest config and get the following error:

TypeError: _ctx.$t is not a function
 ❯ Proxy._sfc_render components/TestTranslation.vue:2:12
      1| <template>
      2|   <span>{{ $t(translationKey) }}</span>
       |            ^
      3| </template>
      4| 

same in my project. Only difference is I am using the nuxt i18n module instead of intlify. Hope that helps.

@Floppy012
Copy link
Author

Would you see if 0.6.12 resolved the issue for you? If not, would you provide a reproduction?

@danielroe https://stackblitz.com/edit/nuxt-starter-c57a8p?file=package.json

Still does not work. I've made a repro with both cases (useI18n and $t): https://stackblitz.com/edit/nuxt-starter-c57a8p?file=package.json

@TECH7Fox
Copy link

I'm also having this issue. I succesfully mocked the $t, but then I still get a SyntaxError: Need to install with app.use function when calling useI18n(). Is there any workaround for this?

@ExEr7um
Copy link
Contributor

ExEr7um commented May 27, 2023

@QozbroQqn I made a minimal stackblitz project with the way I'm working with it. Maybe it helps: https://stackblitz.com/edit/nuxt-starter-bjyxnr

I tried it with nuxt-i18n and it works great. Thank you!

@unshame
Copy link

unshame commented Jun 13, 2023

Got this working without creating a new instance of i18n.

https://stackblitz.com/edit/nuxt-starter-px8r35?file=test%2Fsetup.ts,app.vue,nuxt.config.ts

import { config } from '@vue/test-utils';

try {
  // For .nuxt.test files reuse the nuxt's i18n instance
  const nuxtApp = useNuxtApp();

  config.global.plugins.push({
    async install(app, ...options) {
      const i18n = nuxtApp.vueApp.__VUE_I18N__;

      await i18n.install(app, ...options);
    },
  });
} catch {
  // For .test files we don't make i18n available
}

It seems weird to me that there's a whole another vue app being created by nuxt that is different than the one created by @vue/test-utils. All vue plugins installed via nuxt modules have to be manually re-installed on the test vue instance. I would've assumed that that part of nuxt's initialization would be stubbed by this module and all plugins would be forwarded to the test app.

Copy link
Member

danielroe commented Jun 14, 2023

I would welcome ideas or PRs for closer (ideally automatic) integration with @vue/test-utils. At the moment, using @vue/test-utils is completely separate from nuxt-vitest and nothing 'carries over'. Which is why we have utilities like mountSuspended that handle passing injections/provide across.

@unshame
Copy link

unshame commented Jun 15, 2023

I'm honestly not sure what mountSuspended is supposed to do, since it's not documented. From the name I assumed it was simply wrapping the component in Suspense to make await work in setup. But I'm guessing it does way more than that. Maybe it can be renamed to mountWithNuxt?

I've actually been using vue-test-utils' mount and stubbed app.vue for my unit tests completely, and it's working okay. But that's probably because I don't use nuxt's global instance much. For me it would be enough to forward the vue plugins installed in nuxt plugins/modules to vue-test-utils' config.global.plugins.

@danielroe
Copy link
Member

Here's an example of integrating with @nuxtjs/i18n: https://github.com/nuxt/test-utils/tree/main/examples/i18n.

@danielroe danielroe closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2023
@trandaison
Copy link

@danielroe The example above is not working if change the global function $t by a composition function.

+ <script setup>
+ const { t: $t } = useI18n();
+ </script>
+ 
  <template>
    <div>
      Hi from @nuxtjs/i18n: {{ $t('hello') }}
    </div>
  </template>

I already open an issue here #743, please have a look when you have time.

@indiehjaerta
Copy link

Like mentioned above updating the code using use18n() and t in template the example repo test fails with
SyntaxError: Need to install with app.use function would be great with an update or workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants