-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make defaultMessage warning message configurable #251
Comments
@janhancic are you only extracting messages now because of the warnings in the console in development? Or is this just forcing you to add this step to your build now instead of in the future? |
Pretty much yeah. We might add another language at some point in the future, but we don't actually have any plans to do so. So our main use right now is just to separate text from our components and future proof the app. So having to do this right now is a bit annoying to be honest :) |
@janhancic for single language apps I recommend not using messages since it's inherently more complex, and instead use the other The future-proofing argument is interesting, but I don't have a good solution for that you and @ratson are asking for right now that's not also a footgun. Feel free to use the code in import * as fs from 'fs';
import * as p from 'path';
import {sync as globSync} from 'glob';
import {sync as mkdirpSync} from 'mkdirp';
const MESSAGES_PATTERN = './build/messages/**/*.json';
const LANG_DIR = './build/lang/';
// Aggregates the default messages that were extracted from app's React
// components via the React Intl Babel plugin. An error will be thrown if there
// are messages in different components that use the same `id`. The result is a
// flat collection of `id: message` pairs for the app's default locale.
let defaultMessages = globSync(MESSAGES_PATTERN)
.map((filename) => fs.readFileSync(filename, 'utf8'))
.map((file) => JSON.parse(file))
.reduce((collection, descriptors) => {
descriptors.forEach(({id, defaultMessage}) => {
if (collection.hasOwnProperty(id)) {
throw new Error(`Duplicate message id: ${id}`);
}
collection[id] = defaultMessage;
});
return collection;
}, {});
mkdirpSync(LANG_DIR);
fs.writeFileSync(
p.join(LANG_DIR, 'en-US.json'),
JSON.stringify(defaultMessages, null, 2)
); |
I end up monkey patching if (process.env.NODE_ENV !== 'production') {
const originalConsoleError = console.error
if (console.error === originalConsoleError) {
console.error = (...args) => {
if (args[0].indexOf('[React Intl] Missing message:') === 0) {
return
}
originalConsoleError.call(console, ...args)
}
}
} |
@ericf that's the code is took ys, ta. We're going to continue using this, as we have an app with insane amount of copy in it, so we wanted to extract it out from our markup and as a added benefit get the future proofing, as we know that at some point it's going to have to be internationalised. As an additional piece of information, we actually split out our messages into a separate file, which we then import into the component(s) that use those messages. So you end up with code like this: MyComponent.js import React from 'react';
import messages from './MyComponent.messages';
class MyComponent extends Component {
...
} MyComponent.messages.js import {defineMessages} from 'react-intl';
export default defineMessages({
...
}); Maybe it's just because we have so much copy, but we find it better to not have the actual text in the component file as it makes it much more readable and easy to maintain. It's not a hard rule though, so some smaller components might have the text inline (although you lose the ability to re-use the messages that way). |
I see the point. I'd also like to use defaultMessage as primary translation, rather than downloading same language data again. |
@janhancic with big swaths of text, @khouba understood. I'm wondering if the improvement that I can do here is no warn when |
We have a bit of both I guess (short UI text and copy), so it just makes sense to use the same thing to handle both. |
This prevents warnings from littering the console in development when no `messages` are passed into the <IntlProvider> for the default locale, and a default message is in the source. Fixes formatjs#251
Here's a PR that should resolve this issue without having to add a config option: #253 |
@janhancic okay, sounds good. Keep us updated on how well it works for the copy use-case. For UI strings you could define them in the components and leave the copy strings defined in their own module like you showed in your example code above. |
Sweet, thank you very much. Are you planning on doing a new release soon with the above PR? |
Hey @ericf happy new year :) Just curious if you know when this change will be released? |
No date planned yet. |
What you could also do, is add an additional defineMessages(
...,
locale = 'en'
); or to each individual message definition: {
id: ...,
description: ...,
defaultMessage: ...,
locale: 'en'
} If this This would actually colocate the messages with the |
I am also having these errors in the console. |
So I installed that |
I suppose the resulting That's too complicated. So, I'm removing that Babel plugin from the chain and keep it simple. |
Continue the discussion in 8a78992#commitcomment-14989589
defaultMessage
is often use as the primary source for translation, since it is already bundle with the application, and likely no need for translation, it should be a valid use-case that not loadingmessages
to avoid duplicates.The text was updated successfully, but these errors were encountered: