Migration guide from 1.x to 2.x¶
The biggest change in 2.x is a new build & release process which allowed simplify public API. Library is also taking advantage of latest React features while providing escape hatch to be used also in older React versions.
Backward incompatible changes¶
New scope of NPM packages¶
Packages are now released under @lingui
organization. Some package names
were renamed:
New package name |
Previous package name |
---|---|
@lingui/babel-preset-js |
babel-preset-lingui-js |
@lingui/babel-preset-react |
babel-preset-lingui-react |
@lingui/babel-plugin-transform-js |
babel-plugin-lingui-transform-js |
@lingui/babel-plugin-transform-react |
babel-plugin-lingui-transform-react |
@lingui/babel-plugin-extract-messages |
babel-plugin-lingui-extract-messages |
@lingui/react |
lingui-react |
@lingui/core |
lingui-i18n |
@lingui/cli |
lingui-cli |
@lingui/loader |
lingui-loader |
@lingui/conf |
lingui-conf |
Default message catalog format¶
LinguiJS used comprehensive lingui
format which contains additional info
like location of message in source and default translation (if any). Since most
3rd party tools work with simple JSON only, the default format will be
minimal
.
If you want to keep
lingui
format, add"format": "lingui"
to your lingui config in package.json.If you want to migrate
lingui
format tominimal
, removeformat
from configuration (if any) and runlingui extract --convert-from lingui
.If you used
minimal
format before, simply remove"format": "minimal"
from lingui configuration.
unpackCatalog
is deprecated¶
unpackCatalog
was a useless optimization, which probably saved less bytes
that was a size of unpackCatalog
function. lingui compile
now produce
unpacked file, which can be used directly in <I18nProvider>:
import { I18nProvider } from 'lingui-react'
import catalogEn from './locale/en/messages.js'
function App() {
return (
<I18nProvider language="en" catalogs={{ en: catalogEn }}>
<App />
</I18nProvider>
)
}
development
prop of I18nProvider
is deprecated¶
LinguiJS doesn’t include message parser in production bundle, because messages
are compiled to functions during build. However, in development it’s convenient
to see parsed and formatted messages right away without need to run
lingui extract
and lingui compile
everytime we add new text to an app.
Message parser is included in development package along with plural rules for
all languages. This package is now included automatically in development build
and the content is scoped under if (process.env.NODE_ENV === 'production')
so it’s removed using dead code elimination techniques. To remove it, simply
build your app with NODE_ENV=production
. This change is inspired by
React.
Default wrapping components removed¶
In React < 16.2, components had to return single children which had to be either
React Element or null. For this reason, <I18nProvider> wrapped
children in div
and <Trans> wrapped translations in span
.
React 16.2 allows multiple children and text children, so default wrapping components are removed.
If you’re using React < 16.2 or you want to keep the previous behavior:
Set
defaultRender
prop of <I18nProvider> tospan
.Wrap children of <I18nProvider> into
div
explicitly.
import * as React from 'react'
import { I18nProvider } from 'lingui-react'
function App() {
return (
<I18nProvider defaultRender="span">
<div>
// original children of I18nProvider
</div>
</I18nProvider>
)
}
Package lingui-formats
merged to lingui-i18n
¶
lingui-formats
package was used for date/number formatting and was a wrapper
around Intl module. It only exported two functions: date
and number
, so
it was merged to lingui-i18n
. It’s unlikely that you imported from it
directly but if you did, simply import date
and number
functions from
lingui-i18n
:
// Before
import { date, number } from 'lingui-formats'
// After
import { date, number } from 'lingui-i18n'
Signature of i18n._
changed¶
i18n._
is low-level API for message translation and formatting.
The function signature has changed from:
i18n._(messageId: string, { values: Object, defaults: string, formats: Object })
to:
i18n._(messageId: string, values: Object, { defaults: string, formats: Object })
This change makes usage easier, because values
are commonly used parameter.
Since this is a low-level API, you probably haven’t used it directly and it’s enough to upgrade your lingui babel plugin. Otherwise simple refactoring is required:
// before
i18n._('Hello {name}', { values: { name: "Fred" } })
// after
i18n._('Hello {name}', { name: "Fred" })
New features¶
Custom IDs for @lingui/core methods¶
Most i18n methods in core library (i18n.t
, i18n.select
, i18n.plural
)
accept custom message ID as the first argument. Generated message is used
as a default one:
i18n.t('id')`Default message`
i18n.plural('id', {
one: 'Book',
other: 'Books'
})
ID
is valid only for root calls of i18n methods:
// this doesn't work, `id` is set in nested i18n method
i18n.t`This is their ${i18n.selectOrdinal(`id`, { count: count, ... })}`