我正试图从雅虎的react-intl
开始。 i18n项目,我遇到了一个奇怪的问题。我的目标是将基本字符串(英语)存储在组件外部的某种JSON文件中,以便非开发人员编辑它们。
这似乎比我import
它们更合乎逻辑,然后在组件中使用我需要的部分,但是defineMessages
函数在我这样做时会导致错误。
编辑:问题似乎是babel-plugin-react-intl
插件和"导出"默认字符串。应用程序运行正常,但运行npm run build
命令时会发生错误。
.babelrc:
{
"presets": [
"es2015",
"react"
],
"plugins": [
["react-intl", {
"messagesDir": "./build/messages/"
}]
]
}
的WebPack-配置:
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"
}
有效的代码:
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;
失败的代码:
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);
尝试直接传递引用而不是对象时出现的错误消息:
./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 (
答案 0 :(得分:1)
如果您将babel-plugin-react-intl
与webpack一起使用,请确保仅通过.babelrc
或webpack.config.js
加载babel插件,但不能同时加载"target_link_libraries( # Specifies the target library.
native-lib
-ljnigraphics
# Links the target library to the log library
# included in the NDK.
${log-lib} )
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:0.0 green:0.4705882353 blue:0.7450980392 alpha:1.0]];
多次,在尝试通过webpack运行时会产生完全相同的错误。
答案 1 :(得分:1)
在搜索同一问题时发现了此问题,并认为我会留下对我帮助最大的答案(基于此问题的标题)。 defineMessages
适用于babel-plugin-react-intl
,我认为this issue可以更好地描述预期的功能,以及为什么不能传递先前定义的对象,以及为什么必须在致电defineMessages
引用Eric的回复:
由于Babel是编译器,而不是JavaScript解释器或运行时,因此您需要在defineMessages()调用站点定义要提取的消息。这意味着defineMessages()仅应在实际定义消息的地方使用,而不应在引用消息的地方使用。
此插件的全部目的是从源代码中提取消息,并且defineMessages()对此是一个钩子,并且期望消息描述符存在于调用站点中。 defineMessages()是一个识别函数,它返回传入的对象,因此最常见的用例是:
const messages = defineMessages({
greeting: {
id: 'home.greeting',
defaultMessage: 'Hello, {name}!'
}
});
<FormattedMessage {...messages.greeting}/>
答案 2 :(得分:0)
defineMessages
的行为不是错误。此函数是一个钩子,用于“擦除”组件中的默认消息。如果您想要包含JSON import
中的字符串,则defineMessages
不是必需的,因为它的目的是导出您的默认消息以传递给翻译者。