feat: 🎸 make getClientLocale tree-shakeable

BREAKING CHANGE: It's now needed to explicitly import the `getClientLocale` method to use
its heuristics when setting the initial locale. This makes the method
and its helpers to be tree-shakeable.

```js
import { init, getClientLocale } from 'svelte-i18n'

init({
  initialLocale: getClientLocale({ ... })
})
```
This commit is contained in:
Christian Kaisermann 2020-01-21 10:59:26 -03:00
parent f3b88f90ab
commit 4881acb7b3
6 changed files with 59 additions and 61 deletions

View File

@ -64,7 +64,7 @@ After populating your [`$dictionary`](/docs/Dictionary.md) with [`addMessages()`
```js
// src/i18n.js
import { register, init } from 'svelte-i18n'
import { register, init, getClientLocale } from 'svelte-i18n'
register('en', () => import('./en.json'))
register('en-US', () => import('./en-US.json'))
@ -73,9 +73,9 @@ register('pt', () => import('./pt.json'))
init({
fallbackLocale: 'en',
initialLocale: {
initialLocale: getClientLocale({
navigator: true, // i.e 'en-US'
},
}),
})
// starts loading 'en-US' and 'en'
```

View File

@ -10,46 +10,24 @@ Method responsible for configuring some of the library behaviours such as the gl
interface InitOptions {
// the global fallback locale
fallbackLocale: string
// set of heuristic configs to define the client's locale
initialLocale?: InitialLocaleOptions
// the app initial locale
initialLocale?: string
// custom time/date/number formats
formats?: Formats
// loading delay interval
loadingDelay?: number
}
interface InitialLocaleOptions {
// the fallback locale to use if no message is found in the current one
fallback?: string
// when 'true', check the 'window.navigator.language' to set the current locale
navigator?: boolean
// key to look for a locale on 'window.location.search'
// 'example.com?locale=en-US'
search?: string
// key to look for a locale on 'window.location.hash'
// 'example.com#locale=en-US'
hash?: string
// pattern to look in the window.location.pathname.
// It returns the first capturing group.
pathname?: RegExp
// pattern to look in the window.location.hostname.
// It returns the first capturing group.
hostname?: RegExp
}
```
**Example**:
```js
import { init } from 'svelte-i18n'
import { init, getClientLocale } from 'svelte-i18n'
init({
// fallback to en if current locale is not in the dictionary
fallbackLocale: 'en',
initialLocale: {
// based on the user's browser
navigator: true,
},
initialLocale: 'pt-br',
})
```
@ -90,6 +68,50 @@ init({
<!-- 123.456,79 € -->
```
#### getClientLocale
> `import { getClientLocale } from 'svelte-i18n'`
`getClientLocale(options: GetClientLocaleOptions): void`
Optional utility method to help getting the initial locale of a user. Use it together with the [`init()`](#init) method.
```ts
interface GetClientLocaleOptions {
// the fallback locale to use if no message is found in the current one
fallback?: string
// when 'true', check the 'window.navigator.language' to set the current locale
navigator?: boolean
// key to look for a locale on 'window.location.search'
// 'example.com?locale=en-US'
search?: string
// key to look for a locale on 'window.location.hash'
// 'example.com#locale=en-US'
hash?: string
// pattern to look in the window.location.pathname.
// It returns the first capturing group.
pathname?: RegExp
// pattern to look in the window.location.hostname.
// It returns the first capturing group.
hostname?: RegExp
}
```
**Example**:
```js
import { init, getClientLocale } from 'svelte-i18n'
init({
// fallback to en if current locale is not in the dictionary
fallbackLocale: 'en',
initialLocale: getClientLocale({
// based on the user's browser
navigator: true,
}),
})
```
#### addMessages
`import { addMessages } from 'svelte-i18n`

View File

@ -1,4 +1,3 @@
import { getClientLocale } from './includes/getClientLocale'
import { ConfigureOptions } from './types'
import { $locale } from './stores/locale'
@ -63,11 +62,7 @@ export function getOptions() {
export function init(opts: ConfigureOptions) {
const { formats, ...rest } = opts
const initialLocale = opts.initialLocale
? typeof opts.initialLocale === 'string'
? opts.initialLocale
: getClientLocale(opts.initialLocale) || opts.fallbackLocale
: opts.fallbackLocale
const initialLocale = opts.initialLocale || opts.fallbackLocale
Object.assign(options, rest, { initialLocale })

View File

@ -13,6 +13,7 @@ export function waitLocale(locale?: string) {
}
export { init } from './configs'
export { getClientLocale } from './includes/getClientLocale'
export { $locale as locale } from './stores/locale'

View File

@ -29,25 +29,6 @@ test('inits the initial locale by string', () => {
expect(get($locale)).toBe('en')
})
test('inits the initial locale by client heuristics', () => {
delete window.location
window.location = {
search: '?lang=en-US&foo',
pathname: '/',
hostname: 'example.com',
hash: '',
} as any
init({
fallbackLocale: 'pt',
initialLocale: {
search: 'lang',
},
})
expect(getOptions().initialLocale).toBe('en-US')
expect(get($locale)).toBe('en-US')
})
test('adds custom formats for time, date and number values', () => {
const customFormats = require('../fixtures/formats.json')

View File

@ -8,10 +8,11 @@ import {
getCurrentLocale,
$locale,
isRelatedLocale,
} from '../../../src/runtime/stores/locale'
import { getOptions, init } from '../../../src/runtime/configs'
import { register } from '../../../src/runtime'
import { hasLocaleQueue } from '../../../src/runtime/includes/loaderQueue'
} from '../../../src/client/stores/locale'
import { getOptions, init } from '../../../src/client/configs'
import { register } from '../../../src/client'
import { hasLocaleQueue } from '../../../src/client/includes/loaderQueue'
import { getClientLocale } from '../../../src/client/includes/getClientLocale'
beforeEach(() => {
init({ fallbackLocale: undefined })
@ -113,9 +114,7 @@ test('if no initial locale is set, set the locale to the fallback', () => {
test('if no initial locale was found, set to the fallback locale', () => {
init({
fallbackLocale: 'en',
initialLocale: {
hash: 'lang',
},
initialLocale: null,
})
expect(get($locale)).toBe('en')
expect(getOptions().fallbackLocale).toBe('en')