我正试图让我的头从雅虎react-intl!i18n项目和我遇到了一个奇怪的问题。我的目标是将基字符串(English)存储在组件之外的某种JSON文件中,这样它们就可以由非devs编辑。
这似乎是合乎逻辑的,因为我不能只使用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 (发布于 2016-10-04 16:55:51
defineMessages的行为不是一个bug。此函数是从组件中“刮”默认消息的挂钩。如果希望从JSON import中包含字符串,则不必使用defineMessages,因为它的目的是导出默认消息以传递给翻译程序。
发布于 2019-01-18 19:39:17
在搜索同样的问题时发现了这个问题,并认为我会留下对我帮助最大的答案(基于这个问题的标题)。defineMessages打算与babel-plugin-react-intl一起使用,我认为本期更好地描述了预期的功能,以及为什么传入先前定义的对象不能工作,以及为什么您必须在调用defineMessages时定义消息
引用埃里克的回应:
因为Babel是一个编译器,而不是JavaScript解释器或运行时,所以您需要定义在defineMessages()调用站点中提取的消息。这意味着defineMessages()只能在实际定义消息的地方使用,而不应该在引用消息的地方使用。 这个插件的全部目的是从源代码中提取消息,而defineMessages()是一个钩子,预期消息描述符存在于调用站点中。defineMessages()是一个标识函数,并返回传入的对象,因此最常见的用例是:
const messages = defineMessages({
greeting: {
id: 'home.greeting',
defaultMessage: 'Hello, {name}!'
}
});
<FormattedMessage {...messages.greeting}/>发布于 2016-10-01 22:17:42
如果您与webpack一起使用babel-plugin-react-intl,请确保您只通过.babelrc或webpack.config.js加载了一次babel插件,而不是同时加载两种插件,因为这两种插件都是导致加载插件。多次加载的,在试图通过webpack运行时会导致完全相同的错误。
https://stackoverflow.com/questions/39811438
复制相似问题