Skip to content

Commit c9f029c

Browse files
authored
feat: support for devtools interface (#97)
1 parent 47dd776 commit c9f029c

File tree

9 files changed

+134
-20
lines changed

9 files changed

+134
-20
lines changed

jest.config.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,13 @@ module.exports = {
6262
diagnostics: false
6363
},
6464
__DEV__: true,
65-
__VERSION__: require('./package.json').version
65+
__TEST__: true,
66+
__VERSION__: require('./package.json').version,
67+
__BROWSER__: false,
68+
__GLOBAL__: false,
69+
__ESM_BUNDLER__: true,
70+
__ESM_BROWSER__: false,
71+
__NODE_JS__: true
6672
},
6773

6874
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.

rollup.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ function createReplacePlugin(
168168
__ESM_BUNDLER__: isBundlerESMBuild,
169169
__ESM_BROWSER__: isBrowserESMBuild,
170170
__NODE_JS__: isNodeBuild,
171+
// feature flags
172+
__FEATURE_PROD_DEVTOOLS__: isBundlerESMBuild
173+
? `__INTLFY_PROD_DEVTOOLS__`
174+
: false,
171175
...(isProduction && isBrowserBuild
172176
? {
173177
'emitError(': `/*#__PURE__*/ emitError(`,

src/devtools.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { I18n } from './i18n'
2+
3+
interface I18nRecord {
4+
id: number
5+
version: string
6+
}
7+
8+
const enum DevtoolsHooks {
9+
REGISTER = 'intlify:register'
10+
}
11+
12+
interface DevtoolsHook {
13+
emit(event: string, ...payload: unknown[]): void
14+
on(event: string, handler: Function): void
15+
off(event: string, handler: Function): void
16+
i18nRecords: I18nRecord[]
17+
}
18+
19+
export let devtools: DevtoolsHook
20+
21+
export function setDevtoolsHook(hook: DevtoolsHook): void {
22+
devtools = hook
23+
}
24+
25+
export function devtoolsRegisterI18n(i18n: I18n, version: string): void {
26+
if (!devtools) {
27+
return
28+
}
29+
devtools.emit(DevtoolsHooks.REGISTER, i18n, version)
30+
}

src/global.d.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
// Global compile-time constants
2-
declare let __VERSION__: string
32
declare let __DEV__: boolean
3+
declare let __TEST__: boolean
4+
declare let __ESM_BUNDLER__: boolean
5+
declare let __BROWSER__: boolean
6+
declare let __VERSION__: string
7+
8+
// Feature flags
9+
declare let __FEATURE_PROD_DEVTOOLS__: boolean

src/i18n.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
22
inject,
3-
// onMounted,
4-
// onUnmounted,
3+
onMounted,
4+
onUnmounted,
55
InjectionKey,
66
getCurrentInstance,
77
ComponentInternalInstance,
@@ -28,6 +28,8 @@ import { I18nErrorCodes, createI18nError } from './errors'
2828
import { apply } from './plugin'
2929
import { defineMixin } from './mixin'
3030
import { isEmptyObject, warn } from './utils'
31+
import { devtoolsRegisterI18n } from './devtools'
32+
import { VERSION } from './misc'
3133

3234
/**
3335
* I18n Options for `createI18n`
@@ -288,6 +290,10 @@ export function createI18n<
288290
}
289291
}
290292

293+
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
294+
devtoolsRegisterI18n(i18n, VERSION)
295+
}
296+
291297
return i18n
292298
}
293299

@@ -430,13 +436,11 @@ export function useI18n<
430436
DateTimeFormats,
431437
NumberFormats
432438
>
433-
/* NOTE: DISABLE for intlify-devtools
434439
setupLifeCycle<Messages, DateTimeFormats, NumberFormats>(
435440
i18nInternal,
436441
instance,
437442
composer
438443
)
439-
*/
440444

441445
i18nInternal.__setInstance<
442446
Messages,
@@ -493,25 +497,23 @@ function getComposer<Messages, DateTimeFormats, NumberFormats>(
493497
return composer
494498
}
495499

496-
/*
497500
function setupLifeCycle<Messages, DateTimeFormats, NumberFormats>(
498501
i18n: I18nInternal,
499502
target: ComponentInternalInstance,
500503
composer: Composer<Messages, DateTimeFormats, NumberFormats>
501504
): void {
502505
onMounted(() => {
503506
// inject composer instance to DOM for intlify-devtools
504-
if (target.proxy) {
505-
target.proxy.$el.__intlify__ = composer
507+
if (target.vnode.el) {
508+
target.vnode.el.__intlify__ = composer
506509
}
507510
}, target)
508511

509512
onUnmounted(() => {
510513
// remove composer instance from DOM for intlify-devtools
511-
if (target.proxy && target.proxy.$el.__intlify__) {
512-
delete target.proxy.$el.__intlify__
514+
if (target.vnode.el && target.vnode.el.__INTLIFY__) {
515+
delete target.vnode.el.__intlify__
513516
}
514517
i18n.__deleteInstance(target)
515518
}, target)
516519
}
517-
*/

src/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { initDev, initFeatureFlags } from './misc'
2+
13
export { generateFormatCacheKey, friendlyJSONstringify } from './utils'
24
export { Path, PathValue } from './path'
35
export { createParser, Parser } from './message/parser'
@@ -56,8 +58,10 @@ export {
5658
ComponetI18nScope
5759
} from './components'
5860
export { I18nPluginOptions } from './plugin'
61+
export { VERSION } from './misc'
62+
63+
if (__ESM_BUNDLER__ && !__TEST__) {
64+
initFeatureFlags()
65+
}
5966

60-
/**
61-
* vue-i18n version
62-
*/
63-
export const VERSION = __VERSION__
67+
__DEV__ && initDev()

src/misc.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { getGlobalThis } from './utils'
2+
import { setDevtoolsHook } from './devtools'
3+
4+
export const VERSION = __VERSION__
5+
6+
/**
7+
* This is only called in esm-bundler builds.
8+
* istanbul-ignore-next
9+
*/
10+
export function initFeatureFlags(): void {
11+
let needWarn = false
12+
13+
if (typeof __FEATURE_PROD_DEVTOOLS__ !== 'boolean') {
14+
needWarn = true
15+
getGlobalThis().__INTLIFY_PROD_DEVTOOLS__ = false
16+
}
17+
18+
if (__DEV__ && needWarn) {
19+
console.warn(
20+
`You are running the esm-bundler build of vue-i18n. It is recommended to ` +
21+
`configure your bundler to explicitly replace feature flag globals ` +
22+
`with boolean literals to get proper tree-shaking in the final bundle.`
23+
)
24+
}
25+
}
26+
27+
/**
28+
* This is only called development env
29+
* istanbul-ignore-next
30+
*/
31+
export function initDev(): void {
32+
const target = getGlobalThis()
33+
34+
target.__INTLIFY__ = true
35+
setDevtoolsHook(target.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__)
36+
37+
if (__BROWSER__) {
38+
console.info(
39+
`You are running a development build of Vue.\n` +
40+
`Make sure to use the production build (*.prod.js) when deploying for production.`
41+
)
42+
}
43+
}

src/mixin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export function defineMixin<Messages, DateTimeFormats, NumberFormats>(
230230
},
231231

232232
mounted(): void {
233-
this.$el.__intlify__ = this.$i18n.__composer
233+
this.$el.__INTLIFY__ = this.$i18n.__composer
234234
},
235235

236236
beforeDestroy(): void {
@@ -240,7 +240,7 @@ export function defineMixin<Messages, DateTimeFormats, NumberFormats>(
240240
throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR)
241241
}
242242

243-
delete this.$el.__intlify__
243+
delete this.$el.__INTLIFY__
244244

245245
delete this.$t
246246
delete this.$tc

src/utils.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
const RE_ARGS = /\{([0-9a-zA-Z]+)\}/g
77

8-
// eslint-disable-next-line
8+
/* eslint-disable */
99
export function format(message: string, ...args: any): string {
1010
if (args.length === 1 && isObject(args[0])) {
1111
args = args[0]
@@ -20,7 +20,6 @@ export function format(message: string, ...args: any): string {
2020
}
2121
)
2222
}
23-
/* eslint-enable @typescript-eslint/no-explicit-any */
2423

2524
export const generateFormatCacheKey = (
2625
locale: string,
@@ -56,6 +55,26 @@ export function warn(msg: string, err?: Error): void {
5655
}
5756
}
5857

58+
let _globalThis: any
59+
export const getGlobalThis = (): any => {
60+
// prettier-ignore
61+
return (
62+
_globalThis ||
63+
(_globalThis =
64+
typeof globalThis !== 'undefined'
65+
? globalThis
66+
: typeof self !== 'undefined'
67+
? self
68+
: typeof window !== 'undefined'
69+
? window
70+
: typeof global !== 'undefined'
71+
? global
72+
: {})
73+
)
74+
}
75+
76+
/* eslint-enable */
77+
5978
/**
6079
* Useful Utilites By Evan you
6180
* Modified by kazuya kawaguchi

0 commit comments

Comments
 (0)