intlify / vue-i18n

Vue I18n for Vue 3
https://vue-i18n.intlify.dev/
MIT License
2.2k stars 336 forks source link

Inconsistent Vue plugin `install` function interface between ts typing and the actual code ❗ #1630

Open k-paxian opened 1 year ago

k-paxian commented 1 year ago

Reporting a bug?

The first concerning issue 1️⃣

The I18n ts interface declares install function here as

install(app: App, ...options: unknown[]): void

which is totally fine and aligned with the VueJs3 unit test here and aligned with the plugin installation contract - the install function expected to be synchronous ❗

But, the actual implementation function here is async

      // install plugin
      async install(app: App, ...options: unknown[]): Promise<void> {

The second concerning issue 2️⃣

When we assume the first issue is totally fine, since no one is concerned about it so far, because VueJs is actually calling that install method synchronously.

When we try to call the async installation method it returns Promise which is never ending, always "pending"

import { createI18n } from 'vue-i18n'

const pluginInstance = createI18n({})
// this hangs the script execution, since Promise never will be resolved, it just waits indefinitely  🤷 
const installationPromiseResult =  await pluginInstance.install(app, {}) 

Expected behavior

If you insists that the install method should be "async" for some reason, please do the right thing and return something / auto-resolve the returned Promise at least 😄

Reproduction

import { createI18n } from 'vue-i18n'

const pluginInstance = createI18n({})
// this hangs the script execution, since Promise never will be resolved, it just waits indefinitely 🤷 
const installationPromiseResult =  await pluginInstance.install(app, {}) 

System Info

doesn't matter

Screenshot

No response

Additional context

No response

Validations

kazupon commented 8 months ago

Hmm, Maximum call stack size exceeded in unit test...

RangeError: Maximum call stack size exceeded
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
    683|     }
    684|     // make the install function synchronous to be aligned with the Vue Plugin interface
    685|     i18n.install = (...args) => i18n.install(...args)
       |                                      ^
    686|     return i18n
    687|   } else {
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38
 ❯ Object.i18n.install packages/vue-i18n-core/src/i18n.ts:685:38

I'll revert this PR.