kazupon / vue-i18n

:globe_with_meridians: Internationalization plugin for Vue.js

Home Page:https://kazupon.github.io/vue-i18n/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypeError: _normalize is not a function

zkriszti opened this issue · comments

Reporting a bug?

I'm migrating a Vue2 project from Webpack to Vite. We have been using vue-i18n extensively. We have a special folder structure, so after importing all translation files as modules with Vite's globEager, I am creating a messages object that should be used throughout the app (and it is the same structure that we have successfully used w/ Webpack). However, the translation strings in my object come back as a function, such as:
title: (ctx) => {const { normalize: _normalize } = ctx;return _normalize(["My Translated Title"])}
When I'm trying to use i18n in a component, I get the below message:
TypeError: _normalize is not a function
(and my component won't render).

Expected behavior

The above error message should not happen, component with vue-i18n based translation should render seamlessly.

Reproduction

Here's a link to a minimal reproducible example in codesandbox:
https://codesandbox.io/s/mre-vue-i18n-normalize-is-not-a-function-duuxwt

i18n.js:

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import messages from '@intlify/vite-plugin-vue-i18n/messages'

//...

export default new VueI18n({
  locale: import.meta.VITE_I18N_LOCALE || locale,
  fallbackLocale: import.meta.VITE_I18N_FALLBACK_LOCALE || locale,
  messages: getLocaleMessages() // this returns custom messages object
})

vite.config.js

import { defineConfig } from 'vite'
import { createVuePlugin as vue } from "vite-plugin-vue2"
import vueI18n from '@intlify/vite-plugin-vue-i18n'
import path from "path";

export default defineConfig({
  define: {
    'process.env': {}
  },
  plugins: [
    vue(),
    vueI18n({
      compositionOnly: false, // set this to false to use Vue I18n Legacy API
      include: path.resolve(__dirname, './src/locales/**')
    })
  ],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src")
    }
  }
})

System Info

System:
    OS: Windows 10 10.0.19044
    CPU: (8) x64 Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz    
    Memory: 2.28 GB / 15.77 GB
  Binaries:
    Node: 12.14.1 - C:\Program Files\nodejs\node.EXE
    npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 100.0.4896.127
    Edge: Spartan (44.19041.1266.0), Chromium (100.0.1185.44)
    Internet Explorer: 11.0.19041.1566

Screenshot

image

Additional context

No response

Validations

EDIT: I added a link to a minimal reproducible example.

Hi, I have the exact same issue, any news?

You need to add vue-i18n-bridge package in your project.
see the details:
https://vue-i18n.intlify.dev/guide/migration/vue2.html#usage

If you do use it, note that there are some limitations.

vue-i18n-bridge has limitations:
https://vue-i18n.intlify.dev/guide/migration/vue2.html#limitations

I've been experiencing this exact issue today, and took the above sandbox and added vue-i18n-bridge following the instructions, and I still see the same error message...

Here's the updated sandbox:

https://codesandbox.io/s/mre-vue-i18n-normalize-is-not-a-function-forked-guqn1s

I've been experiencing this exact issue today, and took the above sandbox and added vue-i18n-bridge following the instructions, and I still see the same error message...

Here's the updated sandbox:

https://codesandbox.io/s/mre-vue-i18n-normalize-is-not-a-function-forked-guqn1s

Exactly, I've also tried using vue-i18n-bridge as per Kazupon's suggestion, but it unfortunately didn't solve the issue in my case either.

Ok, I managed to bypass this completely... my issue was that the our translations are on yaml files, so once I used a yaml transformer (even removed @intlify/vite-plugin-vue-i18n completely!), all issues were gone and everything started to work as expected!

Really important to say that adding that configuration of vue-i18n to vite.config.js doesn't solves this problem.

I'm also migrating a vue 2.7 app from webpack to vite.

I Have been stuck on this error for hours 😕. Any update? I followed the migration guide without success.

I'm still getting TypeError: _normalize is not a function

After we run npm run build, this is very problematic.

I'm not sure if I'm not importing my messages correctly, but why are all of them functions? If I have this structure:

{ 
   "en-EN": { 
      "test": "this is a test"
   }
}

the return of importedTest['en-EN'].test is not this is a test. It is actually e=>{const{normalize:n}=e;return n(["this is a test])}. Why this occurs? Am I doing something wrong?

Edit: here is an image of one of my imported JSON:

image

commented

Nuxt3 with some trick nice work...

<!-- <i18n src="./menu.json"></i18n> -->

<i18n lang="json">
  {
    "id": {
      "name": "Pertama",
      "sub": [
        {
          "one": "Satu"
        }
      ]
    },
    "en": {
      "name": "2nd",
      "sub": [
        {
          "one": "One"
        }
      ]
    }
  }
</i18n>

<script setup lang="ts">
const { locale, t, getLocaleMessage } = useI18n()
const menu = getLocaleMessage(unref(locale))

function normalize([v]: string[]) {
  return v
}
</script>

<template>
  <div>
    <div>
      {{ t('name') }}
    </div>
    <div v-for="(item, i) in menu.sub" :key="i">
      Sub: {{ item.one({ normalize }) }}
    </div>
  </div>
</template>

Nuxt3 with some trick nice work...

<!-- <i18n src="./menu.json"></i18n> -->

<i18n lang="json">
  {
    "id": {
      "name": "Pertama",
      "sub": [
        {
          "one": "Satu"
        }
      ]
    },
    "en": {
      "name": "2nd",
      "sub": [
        {
          "one": "One"
        }
      ]
    }
  }
</i18n>

<script setup lang="ts">
const { locale, t, getLocaleMessage } = useI18n()
const menu = getLocaleMessage(unref(locale))

function normalize([v]: string[]) {
  return v
}
</script>

<template>
  <div>
    <div>
      {{ t('name') }}
    </div>
    <div v-for="(item, i) in menu.sub" :key="i">
      Sub: {{ item.one({ normalize }) }}
    </div>
  </div>
</template>

Use .js file instead of json, then getLocaleMessage should works fine

Any update on this? Is there a solution to the problem?

I'm facing the same error (vue 2.7 migrating to vite)

None of the solutions here really solve my problem. Is this still being worked on?

@gazben @spectrachrome Please check this issue

I found a temporary hack to get around it, hoping for it to get solved one day

Facing same issue while migrating vite with Vue 2.7. :(