help wanted: strings not interpolated (displaying {var}) in "production" builds
See original GitHub issueDescribe the bug I am experiencing an issue in my TypeScript application (bootstrapped by Create-React-App) where translation strings aren’t properly interpolated when built for “production” (minified, etc.).
For example:
- if I run the app in “development” mode with
npm start
results:Displaying 1 of 5
(expected) - if I run the app in “production” mode" with
npm run build
andserve -s build
, results:Displaying {item} of {total}
(not expected) (see screenshots below)
I also see this same interpolation behavior in the following cases:
- In the use of plurals, results:
{thing, plural, one {# thing} other {# things}}
, expected:1 thing
or2 things
- In both lingui versions 2.9.2 and 3.0.0-13
- After running a message catalog extract/compile and importing message catalogs in app before
npm run build
I haven’t seen a duplicate bug to this in existing issues (open or closed).
To Reproduce
- Bootstrap a React app via create-react-app with Redux+Typescript:
npx create-react-app linguiv2 --template redux-typescript
- Add lingui components to project:
npm install @lingui/react @lingui/cli @lingui/macro
- Modify project
tsconfig.json
, change:"target": "es2016"
"jsx": "preserve"
- (these are from docs here: https://lingui.js.org/guides/typescript.html)
- Add minimal lingui to the project:
- In
index.tsx
, addimport { I18nProvider } from '@lingui/react'
and wrap<Provider store={store}>
with<Provider store={store}>
inReactDOM.render(
- In App.tsx, add
import { Trans } from "@lingui/macro";
and inApp
functional component, add some variables to be interpolated and a translation element, such as:
- In
function App() {
const item = 1;
const total = 5;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<Counter />
<p>
<Trans>Displaying {item} of {total}</Trans>
</p>
- View in “developer mode”
npm build
and viewing page displays:Displaying 1 of 5
(expected behavior)
- Build+view in “production mode”
npm run build
andserve -s build
and viewing page displays:Displaying {item} of {total}
(not expected behavior)
Expected behavior Expected that variables would be interpolated in messages in production builds.
Additional context
Please note that I followed the guidance for configuration of my tsconfig.json
file here:
https://lingui.js.org/guides/typescript.html
But I am unsure how to complete the additional steps to configure babel and webpack as I am using a project bootstrapped by create-react-app that I have not ejected (and I would prefer not to eject unless it’s necessary to make this work).
As such, I do not have separate .babelrc
or webpack.config.js
files and when I create these for the project they do not appear to do anything (because this config is “owned” by cra). Note that I did also try ejecting my app and following this documentation, but it seems like it may be out-of-date at this point because it appears babel-preset-env
and babel-preset-react
have been replaced by @babel/preset-env
and @babel/preset-react
for a while now and the preferred way way use TS and Babel is to run TS through Babel (via @babel/preset-typescript
), so there is no more ts-loader
in webpack.
I also tried following these 2.x to 3.x migration directions:
https://github.com/lingui/js-lingui/blob/81937f9c05368459d201c6b5069ed06307b988f0/docs/releases/migration-3.rst#pluginspresets
by installing babel-plugin-macros
and adding the following macro to my package.json
file, but this also yielded the same results:
"babel": {
"plugins": [
"macros"
]
}
I’m sure there’s a step I’m missing here for how (or in what order) the code is getting transpiled + minified, but I can’t figure out how to fix this.
Dev screenshot (see highlighted text)
Production screenshot (see highlighted text)
Versions
- jsLingui version: seeing this behavior in both
2.9.2
and3.0.0-13
- Babel version:
7.9.0
- Your Babel config (e.g.
.babelrc
) or framework you use (Create React App, Meteor, etc.) I don’t have a.babelrc
, I am using create-react-app, react-scripts version3.4.3
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (3 by maintainers)
Fixed. The issue was my import of the message catalogs, specifically this line:
i18n.load(locale, require("locale/en/messages"));
I was loading the messages, but not loading the actual exported
messages
object, so I adjusted to an es6 import:and this resolved it. Or I supposed if I wanted to continue to use CJS require in order to conditionally load catalogs based on supported language(s), I could use:
The main thing is that I missed importing the actual
.messages
object. Thank you very much for your help, please feel free to close/resolve this issue. Best regards,Thank you very much for the quick response and sample! I am adjusting my project now to see if I can resolve the issue. I probably should have noted that I first saw this in an application I am creating using TypeScript and Lingui v3.0.0-13 and in this app I am importing the message catalog. I just didn’t import the message catalogs in the create-react-app sample app I created to reproduce the issue.
In my app I am bootstrapping my message catalog as:
I haven’t tried adjusting this yet, but perhaps it has something to do with me using CJS vs ES6 imports here. I also note that our .linguirc files differ. The notable differences seem to be:
compileNamespace: "cjs"
, while mine is using"es"
"runtimeConfigModule": ["@lingui/core", "i18n"]
, I do not have this line at allWill update once I adjust my project and test, I just wanted to make note of these updates.