Skip to content

Commit 3a0e5ab

Browse files
authored
fix: improve custom extender (#1494)
1 parent 69748e3 commit 3a0e5ab

File tree

14 files changed

+267
-141
lines changed

14 files changed

+267
-141
lines changed

packages/petite-vue-i18n/src/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ export {
7979
VueI18nDateTimeFormatting,
8080
VueI18nNumberFormatting,
8181
VueI18nResolveLocaleMessageTranslation,
82-
ComponentInstanceCreatedListener
82+
ComponentInstanceCreatedListener,
83+
VueI18nExtender
8384
} from '../../vue-i18n-core/src/legacy'
8485
export {
8586
createI18n,
@@ -92,10 +93,12 @@ export {
9293
I18nScope,
9394
ComposerAdditionalOptions,
9495
UseI18nOptions,
95-
ExportedGlobalComposer
96+
ExportedGlobalComposer,
97+
ComposerExtender
9698
} from '../../vue-i18n-core/src/i18n'
9799
export { I18nPluginOptions } from '../../vue-i18n-core/src/plugin'
98100
export { VERSION } from './../../vue-i18n-core/src/misc'
101+
export { Disposer } from './../../vue-i18n-core/src/types'
99102

100103
export type {
101104
IsNever,

packages/petite-vue-i18n/src/runtime.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ export {
7676
VueI18nDateTimeFormatting,
7777
VueI18nNumberFormatting,
7878
VueI18nResolveLocaleMessageTranslation,
79-
ComponentInstanceCreatedListener
79+
ComponentInstanceCreatedListener,
80+
VueI18nExtender
8081
} from '../../vue-i18n-core/src/legacy'
8182
export {
8283
createI18n,
@@ -89,10 +90,12 @@ export {
8990
I18nScope,
9091
ComposerAdditionalOptions,
9192
UseI18nOptions,
92-
ExportedGlobalComposer
93+
ExportedGlobalComposer,
94+
ComposerExtender
9395
} from '../../vue-i18n-core/src/i18n'
9496
export { I18nPluginOptions } from '../../vue-i18n-core/src/plugin'
9597
export { VERSION } from './../../vue-i18n-core/src/misc'
98+
export { Disposer } from './../../vue-i18n-core/src/types'
9699

97100
export type {
98101
IsNever,

packages/vue-i18n-bridge/src/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ export {
8989
VueI18nDateTimeFormatting,
9090
VueI18nNumberFormatting,
9191
VueI18nResolveLocaleMessageTranslation,
92-
ComponentInstanceCreatedListener
92+
ComponentInstanceCreatedListener,
93+
VueI18nExtender
9394
} from '../../vue-i18n-core/src/legacy'
9495
export {
9596
createI18n,
@@ -103,7 +104,8 @@ export {
103104
I18nScope,
104105
ComposerAdditionalOptions,
105106
UseI18nOptions,
106-
ExportedGlobalComposer
107+
ExportedGlobalComposer,
108+
ComposerExtender
107109
} from '../../vue-i18n-core/src/i18n'
108110
export {
109111
Translation,
@@ -119,6 +121,7 @@ export {
119121
} from '../../vue-i18n-core/src/components'
120122
export { I18nPluginOptions } from '../../vue-i18n-core/src/plugin'
121123
export { VERSION } from './../../vue-i18n-core/src/misc'
124+
export { Disposer } from './../../vue-i18n-core/src/types'
122125

123126
export type {
124127
IsNever,

packages/vue-i18n-bridge/src/runtime.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ export {
8686
VueI18nDateTimeFormatting,
8787
VueI18nNumberFormatting,
8888
VueI18nResolveLocaleMessageTranslation,
89-
ComponentInstanceCreatedListener
89+
ComponentInstanceCreatedListener,
90+
VueI18nExtender
9091
} from '../../vue-i18n-core/src/legacy'
9192
export {
9293
createI18n,
@@ -100,7 +101,8 @@ export {
100101
I18nScope,
101102
ComposerAdditionalOptions,
102103
UseI18nOptions,
103-
ExportedGlobalComposer
104+
ExportedGlobalComposer,
105+
ComposerExtender
104106
} from '../../vue-i18n-core/src/i18n'
105107
export {
106108
Translation,
@@ -116,6 +118,7 @@ export {
116118
} from '../../vue-i18n-core/src/components'
117119
export { I18nPluginOptions } from '../../vue-i18n-core/src/plugin'
118120
export { VERSION } from './../../vue-i18n-core/src/misc'
121+
export { Disposer } from './../../vue-i18n-core/src/types'
119122

120123
export type {
121124
IsNever,

packages/vue-i18n-core/src/composer.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import {
4545
EnableEmitter,
4646
DisableEmitter,
4747
SetPluralRulesSymbol,
48-
InejctWithOption,
48+
InejctWithOptionSymbol,
4949
LegacyInstanceSymbol,
5050
__VUE_I18N_BRIDGE__
5151
} from './symbols'
@@ -1782,7 +1782,7 @@ export function createComposer<
17821782
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
17831783
export function createComposer(options: any = {}, VueI18nLegacy?: any): any {
17841784
type Message = VueMessageType
1785-
const { __root } = options as ComposerInternalOptions<
1785+
const { __root, __injectWithOption } = options as ComposerInternalOptions<
17861786
LocaleMessages<LocaleMessage<Message>>,
17871787
DateTimeFormatsType,
17881788
NumberFormatsType
@@ -2526,7 +2526,7 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any {
25262526
;(composer as any).getNumberFormat = getNumberFormat
25272527
;(composer as any).setNumberFormat = setNumberFormat
25282528
;(composer as any).mergeNumberFormat = mergeNumberFormat
2529-
;(composer as any)[InejctWithOption] = options.__injectWithOption
2529+
;(composer as any)[InejctWithOptionSymbol] = __injectWithOption
25302530
;(composer as any)[TranslateVNodeSymbol] = translateVNode
25312531
;(composer as any)[DatetimePartsSymbol] = datetimeParts
25322532
;(composer as any)[NumberPartsSymbol] = numberParts
@@ -2537,11 +2537,9 @@ export function createComposer(options: any = {}, VueI18nLegacy?: any): any {
25372537

25382538
// for vue-devtools timeline event
25392539
if (!__BRIDGE__ && __DEV__) {
2540-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
25412540
;(composer as any)[EnableEmitter] = (emitter: VueDevToolsEmitter): void => {
25422541
;(_context as unknown as CoreInternalContext).__v_emitter = emitter
25432542
}
2544-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
25452543
;(composer as any)[DisableEmitter] = (): void => {
25462544
;(_context as unknown as CoreInternalContext).__v_emitter = undefined
25472545
}

packages/vue-i18n-core/src/i18n.ts

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import { I18nErrorCodes, createI18nError } from './errors'
3232
import {
3333
EnableEmitter,
3434
DisableEmitter,
35-
InejctWithOption,
35+
DisposeSymbol,
36+
InejctWithOptionSymbol,
3637
LegacyInstanceSymbol,
3738
__VUE_I18N_BRIDGE__
3839
} from './symbols'
@@ -81,7 +82,13 @@ import type {
8182
ComposerOptions,
8283
ComposerInternalOptions
8384
} from './composer'
84-
import type { VueI18n, VueI18nOptions, VueI18nInternal } from './legacy'
85+
import type {
86+
VueI18n,
87+
VueI18nOptions,
88+
VueI18nInternal,
89+
VueI18nExtender
90+
} from './legacy'
91+
import type { Disposer } from './types'
8592

8693
declare module 'vue' {
8794
// eslint-disable-next-line
@@ -251,12 +258,17 @@ export interface I18n<
251258
dispose(): void
252259
}
253260

261+
export type ComposerExtender = (composer: Composer) => Disposer | undefined
262+
254263
/**
264+
* The hooks that give to extend Composer (Composition API) and VueI18n instance (Options API).
265+
* This hook is mainly for vue-i18n-routing and nuxt i18n.
266+
*
255267
* @internal
256268
*/
257269
type ExtendHooks = {
258-
__composerExtend?: (composer: Composer) => void
259-
__vueI18nExtend?: (vueI18n: VueI18n) => void
270+
__composerExtend?: ComposerExtender
271+
__vueI18nExtend?: VueI18nExtender
260272
}
261273

262274
/**
@@ -291,8 +303,8 @@ export interface I18nInternal<
291303
instance: Instance
292304
): void
293305
__deleteInstance(component: ComponentInternalInstance): void
294-
__composerExtend?: Required<ExtendHooks>['__composerExtend']
295-
__vueI18nExtend?: Required<ExtendHooks>['__vueI18nExtend']
306+
__composerExtend?: ComposerExtender
307+
__vueI18nExtend?: VueI18nExtender
296308
}
297309

298310
/**
@@ -584,6 +596,8 @@ export function createI18n(options: any = {}, VueI18nLegacy?: any): any {
584596
// set composer & vuei18n extend hook options from plugin options
585597
if (isPlainObject(options[0])) {
586598
const opts = options[0] as ExtendHooks
599+
// Plugin options cannot be passed directly to the function that creates Composer & VueI18n,
600+
// so we keep it temporary
587601
;(i18n as unknown as I18nInternal).__composerExtend =
588602
opts.__composerExtend
589603
;(i18n as unknown as I18nInternal).__vueI18nExtend =
@@ -897,7 +911,9 @@ export function useI18n<
897911

898912
composer = createComposer(composerOptions, _legacyVueI18n) as Composer
899913
if (i18nInternal.__composerExtend) {
900-
i18nInternal.__composerExtend(composer)
914+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
915+
;(composer as any)[DisposeSymbol] =
916+
i18nInternal.__composerExtend(composer)
901917
}
902918
setupLifeCycle(i18nInternal, instance, composer)
903919

@@ -1044,7 +1060,7 @@ function getComposer(
10441060
if (
10451061
useComponent &&
10461062
composer &&
1047-
!(composer as any)[InejctWithOption] // eslint-disable-line @typescript-eslint/no-explicit-any
1063+
!(composer as any)[InejctWithOptionSymbol] // eslint-disable-line @typescript-eslint/no-explicit-any
10481064
) {
10491065
composer = null
10501066
}
@@ -1151,6 +1167,9 @@ function setupLifeCycle(
11511167
}, target)
11521168

11531169
onUnmounted(() => {
1170+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1171+
const _composer = composer as any
1172+
11541173
// remove composer instance from DOM for intlify-devtools
11551174
if (
11561175
(__DEV__ || __FEATURE_PROD_VUE_DEVTOOLS__) &&
@@ -1159,12 +1178,17 @@ function setupLifeCycle(
11591178
target.vnode.el.__VUE_I18N__
11601179
) {
11611180
emitter && emitter.off('*', addTimelineEvent)
1162-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1163-
const _composer = composer as any
11641181
_composer[DisableEmitter] && _composer[DisableEmitter]()
11651182
delete target.vnode.el.__VUE_I18N__
11661183
}
11671184
i18n.__deleteInstance(target)
1185+
1186+
// dispose extended resources
1187+
const dispose = _composer[DisposeSymbol]
1188+
if (dispose) {
1189+
dispose()
1190+
delete _composer[DisposeSymbol]
1191+
}
11681192
}, target)
11691193
}
11701194
}
@@ -1656,12 +1680,7 @@ const globalExportMethods = !__LITE__
16561680
? ['t', 'rt', 'd', 'n', 'tm', 'te']
16571681
: ['t']
16581682

1659-
type GlobalInjectionReleaseHandler = () => void
1660-
1661-
function injectGlobalFields(
1662-
app: App,
1663-
composer: Composer
1664-
): GlobalInjectionReleaseHandler {
1683+
function injectGlobalFields(app: App, composer: Composer): Disposer {
16651684
const i18n = Object.create(null)
16661685
globalExportProps.forEach(prop => {
16671686
const desc = Object.getOwnPropertyDescriptor(composer, prop)
@@ -1695,7 +1714,7 @@ function injectGlobalFields(
16951714
Object.defineProperty(app.config.globalProperties, `$${method}`, desc)
16961715
})
16971716

1698-
const release = () => {
1717+
const dispose = () => {
16991718
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17001719
delete (app as any).config.globalProperties.$i18n
17011720
globalExportMethods.forEach(method => {
@@ -1704,7 +1723,7 @@ function injectGlobalFields(
17041723
})
17051724
}
17061725

1707-
return release
1726+
return dispose
17081727
}
17091728

17101729
function injectGlobalFieldsForBridge(

packages/vue-i18n-core/src/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ export {
6666
VueI18nDateTimeFormatting,
6767
VueI18nNumberFormatting,
6868
VueI18nResolveLocaleMessageTranslation,
69-
ComponentInstanceCreatedListener
69+
ComponentInstanceCreatedListener,
70+
VueI18nExtender
7071
} from './legacy'
7172
export {
7273
createI18n,
@@ -80,7 +81,8 @@ export {
8081
I18nScope,
8182
ComposerAdditionalOptions,
8283
UseI18nOptions,
83-
ExportedGlobalComposer
84+
ExportedGlobalComposer,
85+
ComposerExtender
8486
} from './i18n'
8587
export {
8688
Translation,
@@ -99,6 +101,7 @@ export {
99101
export { vTDirective, TranslationDirective } from './directive'
100102
export { I18nPluginOptions } from './plugin'
101103
export { VERSION } from './misc'
104+
export { Disposer } from './types'
102105

103106
export type {
104107
IsNever,

0 commit comments

Comments
 (0)