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

RangeError: Maximum call stack size exceeded on any version after 6.17.0 #1075

Closed
1 task done
nelsonlarocca opened this issue Feb 24, 2021 · 11 comments · Fixed by #1090, WalksCloud/OfficialWebsite#74 or hisan92/hisan.me#119
Labels

Comments

@nelsonlarocca
Copy link

Version

nuxt-i18n: any version after 6.17.0
nuxt: 2.14.2 and 2.15.2

  • universal
  • [] spa

Nuxt-i18n configuration

inside a component we have:

methods: {
async switLang(lang) {
await this.$i18n.setLocale(lang)
}
}

I'm just using this.$i18n.setLocale(language);
and it works 100% fine only IF "nuxt-i18n": "^6.17.0",
any other version after that drops the error. Maybe not the first time but randomly after repeating some times the lang switching

image

I use no_prefix strategy
any help?
Thanks

@rchl
Copy link
Collaborator

rchl commented Feb 25, 2021

Can you show the full source code of that component?

@nelsonlarocca
Copy link
Author

nelsonlarocca commented Feb 25, 2021

sure, here you have
thanks

<template>
  <div>
    <div>
      <v-select
        v-model="xxx"
        color="primary"
        solo
        :items="availableLocales"
        item-value="code"
        item-text="name"
        @change="changedValue"
      />
    </div>
  </div>
</template>

<script>
export default {
  props: {
    pLang: {
      type: String,
      default: '',
    },
  },

  data() {
    return {
      xLang: 'xxx',
    }
  },

  computed: {
    xxx: {
      get() {
        return this.$i18n.locale
      },
      set(v) {},
    },

    availableLocales() {
      return this.$i18n.locales // .filter((i) => i.code !== this.$i18n.locale)
    },
  },

  mounted() {
    this.xLang = this.pLang || this.$i18n.locale
  },

  methods: {
    async changedValue(lang) {
      if (lang !== this.$i18n.locale) {
        // asking to avoid looping if other selector on same page
        await this.$i18n.setLocale(lang)
        this.$bus.$emit('langSwitched', { location: 'FOOTER', lang })
      }
    },
  },
}
</script>

@rchl
Copy link
Collaborator

rchl commented Feb 25, 2021

Sorry but need more information.

klona is only used to clone the i18n.locales and i18n.vueI18n objects so there could be something in those objects that causes that.

If you could log the i18n.locales value before this error then it might reveal some issue with the circular property.

Ideally, you would create a repo that reproduces as that would save a lot of time in trying to figure this one out.

@PolarWooolf
Copy link

I have the same problem. It appears when observing i18n.locales object
изображение
Klona just starting infinitly cloning recursive object

@nelsonlarocca
Copy link
Author

@PolarWooolf, when is the error thrown?
I used to have a v-select to switch the current language, but I couldn't find the problem itself after debugging everything.
BUT if using i18n version 6.17.0, no issues appeared.

I changed the Vuetify v-select to a radio version, and everything is fine now.

@PolarWooolf
Copy link

Stack trace:
изображение
I'm not sure what's really creating this observer in my app, but before it dies it's trying to clone x.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.__ob__.value.... object, that initial klona's call here:
изображение

@rchl
Copy link
Collaborator

rchl commented Mar 6, 2021

Thanks for that information. Should be very helpful in reproducing and fixing.

It looks like you are also using i18n block in that component because that's when extend is called.

rchl added a commit that referenced this issue Mar 6, 2021
Ensure that we always clone the original "locales" when assigning to
"$i18n.locales" so that if the object is made reactive by the user, we
don't attempt to clone that.

Resolves #1075
@rchl
Copy link
Collaborator

rchl commented Mar 6, 2021

Created a fix in #1090

So it's enough to make the i18n.locales object reactive to trigger the issue. I had one place where I didn't use klona so fixed that now.

@rchl rchl closed this as completed in #1090 Mar 6, 2021
rchl added a commit that referenced this issue Mar 6, 2021
…1090)

Ensure that we always clone the original "locales" when assigning to
"$i18n.locales" so that if the object is made reactive by the user, we
don't attempt to clone that.

Resolves #1075
This was referenced Mar 16, 2021
@Tofandel
Copy link

This issue is still happening in v8.27.2

If you run twice

const msg = {'test': 'test'};
i18n.setLocaleMessage('en', msg);
i18n.setLocaleMessage('en', msg);

Then msg gets reactive after the first call, and the second call results in an error

@rchl
Copy link
Collaborator

rchl commented Jun 23, 2022

This is an API provided by https://github.com/kazupon/vue-i18n so you could report it there.
I suppose ideally it would copy the provided messages object instead of unintentionally mutating it.

But I do think that it should be possible to avoid doing that on your side as a workaround. Is there any good reason for assigning the same messages object twice?

FYI @kazupon

@Tofandel
Copy link

Tofandel commented Jun 23, 2022

Indeed, this is the wrong repo, sorry, I just came here from googling this issue and didn't check the url

It's weird because I've been trying to get it to reproduce on codesandbox but I just can't, it's happening on a large codebase and I'm thinking it's only happening with a weird combo of things

I was originally just switching locales multiple times and the loader wasn't checking if the locale had already been loaded (it's lazy loading the locale from a json file)

import axios from 'rewart-frontend-library/src/plugins/axios';
import Vue from 'vue';
import VueI18n from 'vue-i18n';

import vuetify from '@/plugins/vuetify';

Vue.use(VueI18n);

function loadLocaleMessages(locale) {
  return Promise.all([
    import(
      /* webpackChunkName: "app-locale-[request]" */
      /* webpackInclude: /(en|hu).json$/ */
      /* webpackMode: "lazy" */
      /* webpackPreload: true */
      `@/locales/${locale}.json`),
    import(
      /* webpackChunkName: "vuetify-locale-[request]" */
      /* webpackInclude: /(en|hu).js$/ */
      /* webpackMode: "lazy" */
      /* webpackPreload: true */
      `vuetify/lib/locale/${locale}.js`).then((v) => v.default),
  ]).then(([msg, vuetify]) => i18n.setLocaleMessage(locale, {...msg, $vuetify: vuetify})); // Error happening here
}

let fallbackLoaded = false;
let fallbackLoading = false;

const i18n = new VueI18n({
  locale: null,
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: {},
  silentFallbackWarn: true,
  missing(locale) {
    if (!fallbackLoaded && !fallbackLoading && locale !== i18n.fallbackLocale) {
      fallbackLoading = true;
      loadLocaleMessages(i18n.fallbackLocale).then(() => fallbackLoaded = true);
    }
  },
});

export const switchLocale = (locale = process.env.VUE_APP_I18N_LOCALE || 'en') => {
  const lang = locale.slice(0, 2);

  // If the same language
  if (i18n.locale === lang) {
    return Promise.resolve();
  }
  return loadLocaleMessages(lang).then(() => {
    axios.defaults.headers.common['Accept-Language'] = lang;
    document.querySelector('html').setAttribute('lang', lang);
    i18n.locale = lang;
    vuetify.framework.lang.current = locale;
  });
};

export default i18n;

And so once the same locale gets loaded again this error happens (maybe it has to do with webpack modules)

As a workaround I indeed just keep a variable of the loaded locales to avoid loading the same one multiple times

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