Jason Jason - 2 months ago 22
React JSX Question

Why does defineMessages from react-intl throw an error when passing in a object reference?

I am trying to get my head around

react-intl
from the Yahoo! i18n project and I am running into a weird issue. My goal is to store the base string (English) in some sort of JSON files outside the components so they can be edited by non-devs.

It seems logical than I can just
import
them and then use the parts I need in the component, but the
defineMessages
function causes an error when I do this.

Edit: The issue seems to be around the
babel-plugin-react-intl
plugin and "exporting" the default strings. The app runs fine, but when the
npm run build
command is run the error occurs.

.babelrc:

{
"presets": [
"es2015",
"react"
],
"plugins": [
["react-intl", {
"messagesDir": "./build/messages/"
}]
]
}


webpack-config:

module.exports = {
entry: './src/app.js', // The startingpoint of the app
output: {
filename: 'bundle.js', // Name of the "compiled" JavaScript.
path: './dist', // Which dir to put it on disk.
publicPath: '/', // Which relative path to fetch code from on the client.
},
module: {
loaders:[
{
test: /\.jsx?$/, // Convert ES2015/React-code into ES5.
exclude: /node_modules/,
loader: 'babel'
},
{
test: /\.json$/, // Load JSON-files into code base.
exclude: /node_modules/,
loader: 'json',
},
]
},
};


package.json:

{
"name": "intl3",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"dependencies": {
"babel-core": "^6.14.0",
"babel-loader": "^6.2.5",
"babel-plugin-react-intl": "^2.2.0",
"babel-preset-es2015": "^6.14.0",
"babel-preset-react": "^6.11.1",
"eslint": "^3.3.1",
"eslint-loader": "^1.5.0",
"eslint-plugin-babel": "^3.3.0",
"eslint-plugin-react": "^6.1.2",
"json-loader": "^0.5.4",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-intl": "^2.1.5",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.16.1"
},
"devDependencies": {
"babel-plugin-react-intl": "^2.2.0",
"babel-preset-react": "^6.16.0",
"json-loader": "^0.5.4"
},
"scripts": {
"start:dev": "webpack-dev-server --content-base ./ --config webpack.config.js",
"prebuild": "cp index.html ./dist/index.html",
"build": "webpack --config webpack.config.js",
"start": "http-server dist"
},
"keywords": [],
"author": "",
"license": "ISC"
}


Code that works:

import React from 'react';
import { FormattedMessage, defineMessages } from 'react-intl';

const strings = defineMessages({
"title": {
"id": "TITLE",
"description": "Title of the app.",
"defaultMessage": "Intl Company, Inc."
},
"menu": {
"id": "MENU",
"description": "Word for 'menu'.",
"defaultMessage": "Menu"
}
});

const Header = (props) => {
return (
<header>
<div>
<FormattedMessage {...strings.title} values={ { name: 'World' } } />
</div>
</header>
);
};

export default Header;


Code that fails:

const headerStrings = {
"title": {
"id": "TITLE",
"description": "Title of the app.",
"defaultMessage": "Intl Company, Inc."
},
"menu": {
"id": "MENU",
"description": "Word for 'menu'.",
"defaultMessage": "Menu"
}
};

const strings = defineMessages(headerStrings);


Error message I get when trying to pass a reference instead of object directly:

./src/components/Header.js
Module build failed: SyntaxError: [React Intl] `defineMessages()` must be called with an object expression with values that are React Intl Message Descriptors, also defined as object expressions.

17 | };
18 |
> 19 | const strings = defineMessages(headerStrings);
| ^
20 |
21 | const Header = (props) => {
22 | return (

BabelLoaderError: SyntaxError: [React Intl] `defineMessages()` must be called with an object expression with values that are React Intl Message Descriptors, also defined as object expressions.

17 | };
18 |
> 19 | const strings = defineMessages(headerStrings);
| ^
20 |
21 | const Header = (props) => {
22 | return (

Answer

The behavior of defineMessages is not a bug. This function is a hook to "scrape" the default messages from the component. If you want to include your strings from a JSON import, defineMessages is not necessary since it's purpose is to export your default messages to pass off to a translator.