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
Generate ID's for <FormattedMessage> components #31
Generate ID's for <FormattedMessage> components #31
Conversation
Sorry, we PR'd this early by mistake. Still a WIP but we intend to propose the change. |
5295977
to
f96f4cb
Compare
f96f4cb
to
8f9e880
Compare
Hi, we think this is ready to go - would love to hear what you think :) |
@bradbarrow Great work🎉 |
src/__tests__/components.test.js
Outdated
title: '', | ||
plugin, | ||
snapshot: true, | ||
babelOptions: { filename, babelrc: true }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use babelOptions: { filename, parserOpts: { plugins: ['jsx'] } },
remove babelrc: true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh cool... I understand the dependency removal now too thanks. What does it use to parse jsx under the hood?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -1,10 +1,15 @@ | |||
// @flow | |||
import p from 'path' | |||
import * as t from 'babel-types' | |||
import murmur from 'murmurhash3js' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What: an efficient hashing library to create unique but short hashes
Why: wanted to use the defaultMessage as part of the ID but they are difficult to sanitize and might be quite long. This is the same hash used in the Babel react intl hash plugin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -16,7 +21,7 @@ const isImportLocalName = (name: string, { file }: State) => { | |||
for (const specifier of path.get('specifiers')) { | |||
if ( | |||
specifier.isImportSpecifier() && | |||
specifier.node.imported.name === 'defineMessages' | |||
allowedNames.includes(specifier.node.imported.name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
package.json
Outdated
@@ -64,6 +65,7 @@ | |||
"babel-plugin-tester": "^5.0.0", | |||
"babel-preset-env": "^1.6.1", | |||
"babel-preset-flow": "^6.23.0", | |||
"babel-preset-react": "^6.24.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that without this, jest was unable to run my component fixtures. It throws errors when it finds the JSX nodes
src/__tests__/components.test.js
Outdated
code: ` | ||
import { FormattedMessage } from 'react-intl' | ||
|
||
console.log(<FormattedMessage defaultMessage="hello" />); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why need console.log
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't. I wanted to use the smallest possible valid code sample.i could just have the component by itself...It just felt like it would be floating...And not a typical use case 😄 happy to remove since I suppose Babel doesn't care
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to remove this, and in fact it does throw an error when <FormattedMessage>
is just in line on it's own. So, I've left the log to give it some structure.
Open to other ideas like a function:
const Component = () => <FormattedMessage />
or something?
src/index.js
Outdated
// Evaluate the message expression to see if it yields a string | ||
const evaluated = messageValuePath.get('expression').evaluate() | ||
|
||
//if (evaluated.confident && t.isStringLiteral(evaluated)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops sorry :)
src/__tests__/components.test.js
Outdated
code: ` | ||
import { FormattedMessage } from 'react-intl' | ||
|
||
console.log(<FormattedMessage defaultMessage={\`hello world ${1}\`} />); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clear intention 1
→1 + 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi I'll change that here and in the other test too
And please explain the description to the readme :) |
Hi I'll sort out those changes today :) I'm not sure what you'd like me to explain about the Readme? I tried to add a few examples and additions to show how this component based approach would look and what the result is. I added some minor formatting changes to make the section about extracting a little clearer ... I hope. |
8f9e880
to
504c729
Compare
Ok feedback addressed. I have left the console logs as it doesn't work without some kind of wrapper for context. |
504c729
to
f6416cc
Compare
That worked, changes pushed @akameco thank you :) |
Generates and inserts globally unique id props for react-intl React components FormattedMessage and FormattedHTMLMessage
f6416cc
to
6a25249
Compare
src/__tests__/index.test.js
Outdated
@@ -74,7 +74,7 @@ const tests = [ | |||
import { defineMessages } from 'react-intl' | |||
|
|||
defineMessages({ | |||
hello: \`hello world \${1}\`, | |||
hello: \`hello world \${1+1}\`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not change. Because no need to evaluate here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
Do not rebase😱 I'd like to see diff because of the cost of reviews. |
Fixed up the test :) Sorry, rebasing is my default workflow. Have added the latest fix as a new commit |
4c5f4f4
to
248a9e5
Compare
248a9e5
to
37b553b
Compare
Thanks for the review @akameco :) We're looking forward to the publish so we can start using this in production - we'll be sure to raise any improvements once we've used it for a while :) Thanks for being available 👍 |
Hi @akameco, just wondering if you have an ETA on this release? We're relying on it for a piece of work and we'd love to deliver it this week :) Thank you 🙏 |
@bradbarrow I released 1.1.0 🎉 Great work 👍 |
What:
Closes #27
babel-plugin-react-intl-auto
will generate a globally unique ID for<FormattedMessage>
components that don't specify one themselves.Why:
react-intl
provides two primary interfaces for defining and rendering formatted strings: thedefineMessages
function and<FormattedMessage>
React component.Currently, this plugin only supports generating an ID for messages defined via
defineMessages
.We would like to be able to use the React component but still don't want to have to deal with unique IDs.
How:
This plugin (essentially) creates ID's for
defineMessages
by combining the key passed todefineMessages
with the path to the current file.With
<FormattedMessage>
we don't have any key at all, just the message (descriptions are optional).So this PR proposes a way of creating ID's for React components by combining the path to the current file with a hash of the provided
defaultMessage
.This ensures that per file, all occurrences of a given
defaultMessage
will have the same unique ID. You will never get two matching ID's with different messages.Checklist: